Skip to content

Commit 21267e5

Browse files
committed
Cache resolved bean instance in ControllerAdviceBean
Prior to this commit, the resolveBean() method in ControllerAdviceBean looked up the @ControllerAdvice bean instance in the ApplicationContext by name for every web request that involved lookups for global methods annotated with @ExceptionHandler, @InitBinder, and @ModelAttribute. This commit avoids the need for such repeated lookups in the ApplicationContext by caching the resolved @ControllerAdvice bean instance within ControllerAdviceBean once it has been resolved.
1 parent 5990159 commit 21267e5

1 file changed

Lines changed: 20 additions & 1 deletion

File tree

spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,19 @@
4646
*/
4747
public class ControllerAdviceBean implements Ordered {
4848

49+
/**
50+
* Declared as {@code Object} since this may be a reference to a
51+
* {@code String} representing the bean name or a reference to the actual
52+
* bean instance.
53+
*/
4954
private final Object bean;
5055

56+
/**
57+
* A reference to the resolved bean instance, potentially lazily retrieved
58+
* via the {@code BeanFactory}.
59+
*/
60+
private Object resolvedBean;
61+
5162
@Nullable
5263
private final Class<?> beanType;
5364

@@ -99,6 +110,7 @@ private ControllerAdviceBean(Object bean, @Nullable BeanFactory beanFactory) {
99110
else {
100111
Assert.notNull(bean, "Bean must not be null");
101112
beanType = ClassUtils.getUserClass(bean.getClass());
113+
this.resolvedBean = bean;
102114
this.order = initOrderFromBean(bean);
103115
}
104116

@@ -143,9 +155,16 @@ public Class<?> getBeanType() {
143155
/**
144156
* Get the bean instance for this {@code ControllerAdviceBean}, if necessary
145157
* resolving the bean name through the {@link BeanFactory}.
158+
* <p>As of Spring Framework 5.2, once the bean instance has been resolved it
159+
* will be cached, thereby avoiding repeated lookups in the {@code BeanFactory}.
146160
*/
147161
public Object resolveBean() {
148-
return (this.bean instanceof String ? obtainBeanFactory().getBean((String) this.bean) : this.bean);
162+
if (this.resolvedBean == null) {
163+
// this.bean must be a String representing the bean name if
164+
// this.resolvedBean is null.
165+
this.resolvedBean = obtainBeanFactory().getBean((String) this.bean);
166+
}
167+
return this.resolvedBean;
149168
}
150169

151170
private BeanFactory obtainBeanFactory() {

0 commit comments

Comments
 (0)