Do not cache prototype @ControllerAdvice beans
Spring Framework 5.2 introduced support for caching @ControllerAdvice beans; however, this caching was also applied incorrectly to non-singleton beans. This commit addresses this regression by only caching singleton @ControllerAdvice beans. Closes gh-24157
This commit is contained in:
parent
55ae3c5e87
commit
d7d474f658
|
|
@ -54,6 +54,7 @@ public class ControllerAdviceBean implements Ordered {
|
|||
*/
|
||||
private final Object beanOrName;
|
||||
|
||||
private final boolean isSingletonBean;
|
||||
/**
|
||||
* Reference to the resolved bean instance, potentially lazily retrieved
|
||||
* via the {@code BeanFactory}.
|
||||
|
|
@ -84,6 +85,7 @@ public class ControllerAdviceBean implements Ordered {
|
|||
this.beanType = ClassUtils.getUserClass(bean.getClass());
|
||||
this.beanTypePredicate = createBeanTypePredicate(this.beanType);
|
||||
this.beanFactory = null;
|
||||
this.isSingletonBean = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -115,6 +117,7 @@ public class ControllerAdviceBean implements Ordered {
|
|||
"] does not contain specified controller advice bean '" + beanName + "'");
|
||||
|
||||
this.beanOrName = beanName;
|
||||
this.isSingletonBean = beanFactory.isSingleton(beanName);
|
||||
this.beanType = getBeanType(beanName, beanFactory);
|
||||
this.beanTypePredicate = (controllerAdvice != null ? createBeanTypePredicate(controllerAdvice) :
|
||||
createBeanTypePredicate(this.beanType));
|
||||
|
|
@ -191,7 +194,7 @@ public class ControllerAdviceBean implements Ordered {
|
|||
* will be cached, thereby avoiding repeated lookups in the {@code BeanFactory}.
|
||||
*/
|
||||
public Object resolveBean() {
|
||||
if (this.resolvedBean == null) {
|
||||
if (!this.isSingletonBean || this.resolvedBean == null) {
|
||||
// this.beanOrName must be a String representing the bean name if
|
||||
// this.resolvedBean is null.
|
||||
this.resolvedBean = obtainBeanFactory().getBean((String) this.beanOrName);
|
||||
|
|
|
|||
|
|
@ -206,6 +206,20 @@ public class RequestMappingHandlerAdapterTests {
|
|||
assertThat(mav.getModel().get("attr2")).isEqualTo("gAttr2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void prototypePageControllerAdvice() throws Exception {
|
||||
this.webAppContext.registerPrototype("maa", ModelAttributeAdvice.class);
|
||||
this.webAppContext.refresh();
|
||||
|
||||
HandlerMethod handlerMethod = handlerMethod(new SimpleController(), "handle");
|
||||
this.handlerAdapter.afterPropertiesSet();
|
||||
ModelAndView mav1 = this.handlerAdapter.handle(this.request, this.response, handlerMethod);
|
||||
ModelAndView mav2 = this.handlerAdapter.handle(this.request, this.response, handlerMethod);
|
||||
|
||||
assertThat(mav1.getModel().get("modelAttributeAdviceInstance")).isNotEqualTo(mav2.getModel().get("modelAttributeAdviceInstance"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void modelAttributeAdviceInParentContext() throws Exception {
|
||||
StaticWebApplicationContext parent = new StaticWebApplicationContext();
|
||||
|
|
@ -322,6 +336,7 @@ public class RequestMappingHandlerAdapterTests {
|
|||
public void addAttributes(Model model) {
|
||||
model.addAttribute("attr1", "gAttr1");
|
||||
model.addAttribute("attr2", "gAttr2");
|
||||
model.addAttribute("modelAttributeAdviceInstance", this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue