diff --git a/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java b/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java index e66bb447309..fbf7318c964 100644 --- a/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java +++ b/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java @@ -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); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapterTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapterTests.java index 8ec5bd501e4..f97a39c5fde 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapterTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapterTests.java @@ -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); } }