33
33
import org .springframework .context .ConfigurableApplicationContext ;
34
34
import org .springframework .core .OrderComparator ;
35
35
import org .springframework .core .Ordered ;
36
- import org .springframework .core .annotation .AnnotatedElementUtils ;
37
36
import org .springframework .core .annotation .OrderUtils ;
38
37
import org .springframework .lang .Nullable ;
39
38
import org .springframework .util .Assert ;
43
42
/**
44
43
* Encapsulates information about an {@link ControllerAdvice @ControllerAdvice}
45
44
* Spring-managed bean without necessarily requiring it to be instantiated.
45
+ * The {@link #findAnnotatedBeans(ApplicationContext)} method can be used to
46
+ * discover such beans.
46
47
*
47
- * <p>The {@link #findAnnotatedBeans(ApplicationContext)} method can be used to
48
- * discover such beans. However, a {@code ControllerAdviceBean} may be created
49
- * from any object, including ones without an {@code @ControllerAdvice} annotation.
48
+ * <p>This class is internal to Spring Framework and is not meant to be used
49
+ * by applications to manually create {@code @ControllerAdvice} beans.
50
50
*
51
51
* @author Rossen Stoyanchev
52
52
* @author Brian Clozel
56
56
*/
57
57
public class ControllerAdviceBean implements Ordered {
58
58
59
- /**
60
- * Reference to the actual bean instance or a {@code String} representing
61
- * the bean name.
62
- */
63
- private final Object beanOrName ;
59
+ private final String beanName ;
64
60
65
61
private final boolean isSingleton ;
66
62
@@ -76,60 +72,33 @@ public class ControllerAdviceBean implements Ordered {
76
72
77
73
private final HandlerTypePredicate beanTypePredicate ;
78
74
79
- @ Nullable
80
75
private final BeanFactory beanFactory ;
81
76
82
77
@ Nullable
83
78
private Integer order ;
84
79
85
80
86
- /**
87
- * Create a {@code ControllerAdviceBean} using the given bean instance.
88
- * @param bean the bean instance
89
- */
90
- public ControllerAdviceBean (Object bean ) {
91
- Assert .notNull (bean , "Bean must not be null" );
92
- this .beanOrName = bean ;
93
- this .isSingleton = true ;
94
- this .resolvedBean = bean ;
95
- this .beanType = ClassUtils .getUserClass (bean .getClass ());
96
- this .beanTypePredicate = createBeanTypePredicate (this .beanType );
97
- this .beanFactory = null ;
98
- }
99
-
100
- /**
101
- * Create a {@code ControllerAdviceBean} using the given bean name and
102
- * {@code BeanFactory}.
103
- * @param beanName the name of the bean
104
- * @param beanFactory a {@code BeanFactory} to retrieve the bean type initially
105
- * and later to resolve the actual bean
106
- */
107
- public ControllerAdviceBean (String beanName , BeanFactory beanFactory ) {
108
- this (beanName , beanFactory , null );
109
- }
110
-
111
81
/**
112
82
* Create a {@code ControllerAdviceBean} using the given bean name,
113
83
* {@code BeanFactory}, and {@link ControllerAdvice @ControllerAdvice}
114
84
* annotation.
115
85
* @param beanName the name of the bean
116
86
* @param beanFactory a {@code BeanFactory} to retrieve the bean type initially
117
87
* and later to resolve the actual bean
118
- * @param controllerAdvice the {@code @ControllerAdvice} annotation for the
119
- * bean, or {@code null} if not yet retrieved
88
+ * @param controllerAdvice the {@code @ControllerAdvice} annotation for the bean
120
89
* @since 5.2
121
90
*/
122
- public ControllerAdviceBean (String beanName , BeanFactory beanFactory , @ Nullable ControllerAdvice controllerAdvice ) {
91
+ public ControllerAdviceBean (String beanName , BeanFactory beanFactory , ControllerAdvice controllerAdvice ) {
123
92
Assert .hasText (beanName , "Bean name must contain text" );
124
93
Assert .notNull (beanFactory , "BeanFactory must not be null" );
125
94
Assert .isTrue (beanFactory .containsBean (beanName ), () -> "BeanFactory [" + beanFactory +
126
95
"] does not contain specified controller advice bean '" + beanName + "'" );
96
+ Assert .notNull (controllerAdvice , "ControllerAdvice must not be null" );
127
97
128
- this .beanOrName = beanName ;
98
+ this .beanName = beanName ;
129
99
this .isSingleton = beanFactory .isSingleton (beanName );
130
100
this .beanType = getBeanType (beanName , beanFactory );
131
- this .beanTypePredicate = (controllerAdvice != null ? createBeanTypePredicate (controllerAdvice ) :
132
- createBeanTypePredicate (this .beanType ));
101
+ this .beanTypePredicate = createBeanTypePredicate (controllerAdvice );
133
102
this .beanFactory = beanFactory ;
134
103
}
135
104
@@ -158,31 +127,24 @@ public ControllerAdviceBean(String beanName, BeanFactory beanFactory, @Nullable
158
127
@ Override
159
128
public int getOrder () {
160
129
if (this .order == null ) {
161
- String beanName = null ;
162
130
Object resolvedBean = null ;
163
- if (this .beanFactory != null && this .beanOrName instanceof String stringBeanName ) {
164
- beanName = stringBeanName ;
165
- String targetBeanName = ScopedProxyUtils .getTargetBeanName (beanName );
166
- boolean isScopedProxy = this .beanFactory .containsBean (targetBeanName );
167
- // Avoid eager @ControllerAdvice bean resolution for scoped proxies,
168
- // since attempting to do so during context initialization would result
169
- // in an exception due to the current absence of the scope. For example,
170
- // an HTTP request or session scope is not active during initialization.
171
- if (!isScopedProxy && !ScopedProxyUtils .isScopedTarget (beanName )) {
172
- resolvedBean = resolveBean ();
173
- }
174
- }
175
- else {
131
+ String targetBeanName = ScopedProxyUtils .getTargetBeanName (this .beanName );
132
+ boolean isScopedProxy = this .beanFactory .containsBean (targetBeanName );
133
+ // Avoid eager @ControllerAdvice bean resolution for scoped proxies,
134
+ // since attempting to do so during context initialization would result
135
+ // in an exception due to the current absence of the scope. For example,
136
+ // an HTTP request or session scope is not active during initialization.
137
+ if (!isScopedProxy && !ScopedProxyUtils .isScopedTarget (this .beanName )) {
176
138
resolvedBean = resolveBean ();
177
139
}
178
140
179
141
if (resolvedBean instanceof Ordered ordered ) {
180
142
this .order = ordered .getOrder ();
181
143
}
182
144
else {
183
- if (beanName != null && this .beanFactory instanceof ConfigurableBeanFactory cbf ) {
145
+ if (this .beanFactory instanceof ConfigurableBeanFactory cbf ) {
184
146
try {
185
- BeanDefinition bd = cbf .getMergedBeanDefinition (beanName );
147
+ BeanDefinition bd = cbf .getMergedBeanDefinition (this . beanName );
186
148
if (bd instanceof RootBeanDefinition rbd ) {
187
149
Method factoryMethod = rbd .getResolvedFactoryMethod ();
188
150
if (factoryMethod != null ) {
@@ -225,9 +187,7 @@ public Class<?> getBeanType() {
225
187
*/
226
188
public Object resolveBean () {
227
189
if (this .resolvedBean == null ) {
228
- // this.beanOrName must be a String representing the bean name if
229
- // this.resolvedBean is null.
230
- Object resolvedBean = obtainBeanFactory ().getBean ((String ) this .beanOrName );
190
+ Object resolvedBean = this .beanFactory .getBean (this .beanName );
231
191
// Don't cache non-singletons (e.g., prototypes).
232
192
if (!this .isSingleton ) {
233
193
return resolvedBean ;
@@ -237,11 +197,6 @@ public Object resolveBean() {
237
197
return this .resolvedBean ;
238
198
}
239
199
240
- private BeanFactory obtainBeanFactory () {
241
- Assert .state (this .beanFactory != null , "No BeanFactory set" );
242
- return this .beanFactory ;
243
- }
244
-
245
200
/**
246
201
* Check whether the given bean type should be advised by this
247
202
* {@code ControllerAdviceBean}.
@@ -257,17 +212,17 @@ public boolean isApplicableToBeanType(@Nullable Class<?> beanType) {
257
212
@ Override
258
213
public boolean equals (@ Nullable Object other ) {
259
214
return (this == other || (other instanceof ControllerAdviceBean that &&
260
- this .beanOrName .equals (that .beanOrName ) && this .beanFactory == that .beanFactory ));
215
+ this .beanName .equals (that .beanName ) && this .beanFactory == that .beanFactory ));
261
216
}
262
217
263
218
@ Override
264
219
public int hashCode () {
265
- return this .beanOrName .hashCode ();
220
+ return this .beanName .hashCode ();
266
221
}
267
222
268
223
@ Override
269
224
public String toString () {
270
- return this .beanOrName . toString () ;
225
+ return this .beanName ;
271
226
}
272
227
273
228
@@ -308,22 +263,13 @@ private static Class<?> getBeanType(String beanName, BeanFactory beanFactory) {
308
263
return (beanType != null ? ClassUtils .getUserClass (beanType ) : null );
309
264
}
310
265
311
- private static HandlerTypePredicate createBeanTypePredicate (@ Nullable Class <?> beanType ) {
312
- ControllerAdvice controllerAdvice = (beanType != null ?
313
- AnnotatedElementUtils .findMergedAnnotation (beanType , ControllerAdvice .class ) : null );
314
- return createBeanTypePredicate (controllerAdvice );
315
- }
316
-
317
- private static HandlerTypePredicate createBeanTypePredicate (@ Nullable ControllerAdvice controllerAdvice ) {
318
- if (controllerAdvice != null ) {
319
- return HandlerTypePredicate .builder ()
320
- .basePackage (controllerAdvice .basePackages ())
321
- .basePackageClass (controllerAdvice .basePackageClasses ())
322
- .assignableType (controllerAdvice .assignableTypes ())
323
- .annotation (controllerAdvice .annotations ())
324
- .build ();
325
- }
326
- return HandlerTypePredicate .forAnyHandlerType ();
266
+ private static HandlerTypePredicate createBeanTypePredicate (ControllerAdvice controllerAdvice ) {
267
+ return HandlerTypePredicate .builder ()
268
+ .basePackage (controllerAdvice .basePackages ())
269
+ .basePackageClass (controllerAdvice .basePackageClasses ())
270
+ .assignableType (controllerAdvice .assignableTypes ())
271
+ .annotation (controllerAdvice .annotations ())
272
+ .build ();
327
273
}
328
274
329
275
}
0 commit comments