19
19
import java .lang .annotation .Annotation ;
20
20
import java .util .ArrayList ;
21
21
import java .util .Arrays ;
22
+ import java .util .LinkedHashSet ;
22
23
import java .util .List ;
23
-
24
- import org .apache .commons .logging .Log ;
25
- import org .apache .commons .logging .LogFactory ;
24
+ import java .util .Set ;
26
25
27
26
import org .springframework .beans .factory .BeanFactory ;
28
27
import org .springframework .beans .factory .BeanFactoryUtils ;
39
38
* Encapsulates information about an {@linkplain ControllerAdvice @ControllerAdvice}
40
39
* Spring-managed bean without necessarily requiring it to be instantiated.
41
40
*
42
- * <p>The {@link #findAnnotatedBeans(ApplicationContext)} method can be used to discover
43
- * such beans. However, an {@code ControllerAdviceBean} may be created from
44
- * any object, including ones without an {@code @ControllerAdvice}.
41
+ * <p>The {@link #findAnnotatedBeans(ApplicationContext)} method can be used to
42
+ * discover such beans. However, a {@code ControllerAdviceBean} may be created
43
+ * from any object, including ones without an {@code @ControllerAdvice}.
45
44
*
46
45
* @author Rossen Stoyanchev
47
46
* @author Brian Clozel
47
+ * @author Juergen Hoeller
48
48
* @since 3.2
49
49
*/
50
50
public class ControllerAdviceBean implements Ordered {
51
51
52
- private static final Log logger = LogFactory .getLog (ControllerAdviceBean .class );
53
-
54
52
private final Object bean ;
55
53
54
+ private final BeanFactory beanFactory ;
55
+
56
56
private final int order ;
57
57
58
- private final BeanFactory beanFactory ;
58
+ private final Set < String > basePackages ;
59
59
60
- private final List <Package > basePackages = new ArrayList < Package >() ;
60
+ private final List <Class <?>> assignableTypes ;
61
61
62
- private final List <Class <? extends Annotation >> annotations = new ArrayList < Class <? extends Annotation >>() ;
62
+ private final List <Class <? extends Annotation >> annotations ;
63
63
64
- private final List <Class <?>> assignableTypes = new ArrayList <Class <?>>();
65
64
65
+ /**
66
+ * Create a {@code ControllerAdviceBean} using the given bean instance.
67
+ * @param bean the bean instance
68
+ */
69
+ public ControllerAdviceBean (Object bean ) {
70
+ this (bean , null );
71
+ }
66
72
67
73
/**
68
- * Create an instance using the given bean name.
74
+ * Create a {@code ControllerAdviceBean} using the given bean name.
69
75
* @param beanName the name of the bean
70
76
* @param beanFactory a BeanFactory that can be used later to resolve the bean
71
77
*/
72
78
public ControllerAdviceBean (String beanName , BeanFactory beanFactory ) {
73
- Assert .hasText (beanName , "Bean name must not be null" );
74
- Assert .notNull (beanFactory , "BeanFactory must not be null" );
75
-
76
- if (!beanFactory .containsBean (beanName )) {
77
- throw new IllegalArgumentException (
78
- "BeanFactory [" + beanFactory + "] does not contain bean with name '" + beanName + "'" );
79
- }
80
-
81
- this .bean = beanName ;
82
- this .beanFactory = beanFactory ;
83
-
84
- Class <?> beanType = this .beanFactory .getType (beanName );
85
- this .order = initOrderFromBeanType (beanType );
86
-
87
- ControllerAdvice annotation = AnnotationUtils .findAnnotation (beanType ,ControllerAdvice .class );
88
- Assert .notNull (annotation , "BeanType [" + beanType .getName () + "] is not annotated @ControllerAdvice" );
89
-
90
- this .basePackages .addAll (initBasePackagesFromBeanType (beanType , annotation ));
91
- this .annotations .addAll (Arrays .asList (annotation .annotations ()));
92
- this .assignableTypes .addAll (Arrays .asList (annotation .assignableTypes ()));
79
+ this ((Object ) beanName , beanFactory );
93
80
}
94
81
95
- /**
96
- * Create an instance using the given bean instance.
97
- * @param bean the bean
98
- */
99
- public ControllerAdviceBean (Object bean ) {
100
- Assert .notNull (bean , "Bean must not be null" );
82
+ private ControllerAdviceBean (Object bean , BeanFactory beanFactory ) {
101
83
this .bean = bean ;
102
- this .order = initOrderFromBean (bean );
103
-
104
- Class <?> beanType = bean .getClass ();
105
- ControllerAdvice annotation = AnnotationUtils .findAnnotation (beanType ,ControllerAdvice .class );
106
- Assert .notNull (annotation , "Bean type [" + beanType .getName () + "] is not annotated @ControllerAdvice" );
84
+ this .beanFactory = beanFactory ;
85
+ Class <?> beanType ;
86
+
87
+ if (bean instanceof String ) {
88
+ String beanName = (String ) bean ;
89
+ Assert .hasText (beanName , "Bean name must not be null" );
90
+ Assert .notNull (beanFactory , "BeanFactory must not be null" );
91
+ if (!beanFactory .containsBean (beanName )) {
92
+ throw new IllegalArgumentException ("BeanFactory [" + beanFactory +
93
+ "] does not contain specified controller advice bean '" + beanName + "'" );
94
+ }
95
+ beanType = this .beanFactory .getType (beanName );
96
+ this .order = initOrderFromBeanType (beanType );
97
+ }
98
+ else {
99
+ Assert .notNull (bean , "Bean must not be null" );
100
+ beanType = bean .getClass ();
101
+ this .order = initOrderFromBean (bean );
102
+ }
107
103
108
- this .basePackages .addAll (initBasePackagesFromBeanType (beanType , annotation ));
109
- this .annotations .addAll (Arrays .asList (annotation .annotations ()));
110
- this .assignableTypes .addAll (Arrays .asList (annotation .assignableTypes ()));
111
- this .beanFactory = null ;
104
+ ControllerAdvice annotation = AnnotationUtils .findAnnotation (beanType , ControllerAdvice .class );
105
+ if (annotation == null ) {
106
+ throw new IllegalArgumentException (
107
+ "Bean type [" + beanType .getName () + "] is not annotated as @ControllerAdvice" );
108
+ }
109
+ this .basePackages = initBasePackages (annotation );
110
+ this .assignableTypes = Arrays .asList (annotation .assignableTypes ());
111
+ this .annotations = Arrays .asList (annotation .annotations ());
112
112
}
113
113
114
114
115
115
/**
116
116
* Returns the order value extracted from the {@link ControllerAdvice}
117
- * annotation or {@link Ordered#LOWEST_PRECEDENCE} otherwise.
117
+ * annotation, or {@link Ordered#LOWEST_PRECEDENCE} otherwise.
118
118
*/
119
119
@ Override
120
120
public int getOrder () {
121
121
return this .order ;
122
122
}
123
123
124
124
/**
125
- * Returns the type of the contained bean.
126
- * If the bean type is a CGLIB-generated class, the original, user-defined class is returned.
125
+ * Return the type of the contained bean.
126
+ * <p>If the bean type is a CGLIB-generated class, the original
127
+ * user-defined class is returned.
127
128
*/
128
129
public Class <?> getBeanType () {
129
130
Class <?> clazz = (this .bean instanceof String ?
@@ -139,7 +140,7 @@ public Object resolveBean() {
139
140
}
140
141
141
142
/**
142
- * Checks whether the given bean type should be assisted by this
143
+ * Check whether the given bean type should be assisted by this
143
144
* {@code @ControllerAdvice} instance.
144
145
* @param beanType the type of the bean to check
145
146
* @see org.springframework.web.bind.annotation.ControllerAdvice
@@ -150,6 +151,12 @@ public boolean isApplicableToBeanType(Class<?> beanType) {
150
151
return true ;
151
152
}
152
153
else if (beanType != null ) {
154
+ String packageName = ClassUtils .getPackageName (beanType );
155
+ for (String basePackage : this .basePackages ) {
156
+ if (packageName .startsWith (basePackage )) {
157
+ return true ;
158
+ }
159
+ }
153
160
for (Class <?> clazz : this .assignableTypes ) {
154
161
if (ClassUtils .isAssignable (clazz , beanType )) {
155
162
return true ;
@@ -160,25 +167,25 @@ else if (beanType != null) {
160
167
return true ;
161
168
}
162
169
}
163
- String packageName = beanType .getPackage ().getName ();
164
- for (Package basePackage : this .basePackages ) {
165
- if (packageName .startsWith (basePackage .getName ())) {
166
- return true ;
167
- }
168
- }
169
170
}
170
171
return false ;
171
172
}
172
173
173
174
private boolean hasSelectors () {
174
- return (!this .basePackages .isEmpty () || !this .annotations .isEmpty () || !this .assignableTypes .isEmpty ());
175
+ return (!this .basePackages .isEmpty () || !this .assignableTypes .isEmpty () || !this .annotations .isEmpty ());
175
176
}
176
177
177
178
178
179
@ Override
179
180
public boolean equals (Object other ) {
180
- return (this == other ||
181
- (other instanceof ControllerAdviceBean && this .bean .equals (((ControllerAdviceBean ) other ).bean )));
181
+ if (this == other ) {
182
+ return true ;
183
+ }
184
+ if (!(other instanceof ControllerAdviceBean )) {
185
+ return false ;
186
+ }
187
+ ControllerAdviceBean otherAdvice = (ControllerAdviceBean ) other ;
188
+ return (this .bean .equals (otherAdvice .bean ) && this .beanFactory == otherAdvice .beanFactory );
182
189
}
183
190
184
191
@ Override
@@ -216,32 +223,21 @@ private static int initOrderFromBeanType(Class<?> beanType) {
216
223
return (ann != null ? ann .value () : Ordered .LOWEST_PRECEDENCE );
217
224
}
218
225
219
- private static List <Package > initBasePackagesFromBeanType (Class <?> beanType , ControllerAdvice annotation ) {
220
- List <Package > basePackages = new ArrayList <Package >();
221
- List <String > basePackageNames = new ArrayList <String >();
222
- basePackageNames .addAll (Arrays .asList (annotation .value ()));
223
- basePackageNames .addAll (Arrays .asList (annotation .basePackages ()));
224
- for (String pkgName : basePackageNames ) {
225
- if (StringUtils .hasText (pkgName )) {
226
- Package pkg = Package .getPackage (pkgName );
227
- if (pkg != null ) {
228
- basePackages .add (pkg );
229
- }
230
- else {
231
- logger .warn ("Package [" + pkgName + "] was not found, see [" + beanType .getName () + "]" );
232
- }
226
+ private static Set <String > initBasePackages (ControllerAdvice annotation ) {
227
+ Set <String > basePackages = new LinkedHashSet <String >();
228
+ for (String basePackage : annotation .value ()) {
229
+ if (StringUtils .hasText (basePackage )) {
230
+ basePackages .add (basePackage );
233
231
}
234
232
}
235
- for (Class <?> markerClass : annotation .basePackageClasses ()) {
236
- Package pack = markerClass .getPackage ();
237
- if (pack != null ) {
238
- basePackages .add (pack );
239
- }
240
- else {
241
- logger .warn ("Package was not found for class [" + markerClass .getName () +
242
- "], see [" + beanType .getName () + "]" );
233
+ for (String basePackage : annotation .basePackages ()) {
234
+ if (StringUtils .hasText (basePackage )) {
235
+ basePackages .add (basePackage );
243
236
}
244
237
}
238
+ for (Class <?> markerClass : annotation .basePackageClasses ()) {
239
+ basePackages .add (ClassUtils .getPackageName (markerClass ));
240
+ }
245
241
return basePackages ;
246
242
}
247
243
0 commit comments