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
@@ -150,6 +150,11 @@ public boolean isApplicableToBeanType(Class<?> beanType) {
150
150
return true ;
151
151
}
152
152
else if (beanType != null ) {
153
+ for (String basePackage : this .basePackages ) {
154
+ if (ClassUtils .getPackageName (beanType ).startsWith (basePackage )) {
155
+ return true ;
156
+ }
157
+ }
153
158
for (Class <?> clazz : this .assignableTypes ) {
154
159
if (ClassUtils .isAssignable (clazz , beanType )) {
155
160
return true ;
@@ -160,25 +165,25 @@ else if (beanType != null) {
160
165
return true ;
161
166
}
162
167
}
163
- String packageName = beanType .getPackage ().getName ();
164
- for (Package basePackage : this .basePackages ) {
165
- if (packageName .startsWith (basePackage .getName ())) {
166
- return true ;
167
- }
168
- }
169
168
}
170
169
return false ;
171
170
}
172
171
173
172
private boolean hasSelectors () {
174
- return (!this .basePackages .isEmpty () || !this .annotations .isEmpty () || !this .assignableTypes .isEmpty ());
173
+ return (!this .basePackages .isEmpty () || !this .assignableTypes .isEmpty () || !this .annotations .isEmpty ());
175
174
}
176
175
177
176
178
177
@ Override
179
178
public boolean equals (Object other ) {
180
- return (this == other ||
181
- (other instanceof ControllerAdviceBean && this .bean .equals (((ControllerAdviceBean ) other ).bean )));
179
+ if (this == other ) {
180
+ return true ;
181
+ }
182
+ if (!(other instanceof ControllerAdviceBean )) {
183
+ return false ;
184
+ }
185
+ ControllerAdviceBean otherAdvice = (ControllerAdviceBean ) other ;
186
+ return (this .bean .equals (otherAdvice .bean ) && this .beanFactory == otherAdvice .beanFactory );
182
187
}
183
188
184
189
@ Override
@@ -215,32 +220,21 @@ private static int initOrderFromBeanType(Class<?> beanType) {
215
220
return OrderUtils .getOrder (beanType , Ordered .LOWEST_PRECEDENCE );
216
221
}
217
222
218
- private static List <Package > initBasePackagesFromBeanType (Class <?> beanType , ControllerAdvice annotation ) {
219
- List <Package > basePackages = new ArrayList <Package >();
220
- List <String > basePackageNames = new ArrayList <String >();
221
- basePackageNames .addAll (Arrays .asList (annotation .value ()));
222
- basePackageNames .addAll (Arrays .asList (annotation .basePackages ()));
223
- for (String pkgName : basePackageNames ) {
224
- if (StringUtils .hasText (pkgName )) {
225
- Package pkg = Package .getPackage (pkgName );
226
- if (pkg != null ) {
227
- basePackages .add (pkg );
228
- }
229
- else {
230
- logger .warn ("Package [" + pkgName + "] was not found, see [" + beanType .getName () + "]" );
231
- }
223
+ private static Set <String > initBasePackages (ControllerAdvice annotation ) {
224
+ Set <String > basePackages = new LinkedHashSet <String >();
225
+ for (String basePackage : annotation .value ()) {
226
+ if (StringUtils .hasText (basePackage )) {
227
+ basePackages .add (basePackage );
232
228
}
233
229
}
234
- for (Class <?> markerClass : annotation .basePackageClasses ()) {
235
- Package pack = markerClass .getPackage ();
236
- if (pack != null ) {
237
- basePackages .add (pack );
238
- }
239
- else {
240
- logger .warn ("Package was not found for class [" + markerClass .getName () +
241
- "], see [" + beanType .getName () + "]" );
230
+ for (String basePackage : annotation .basePackages ()) {
231
+ if (StringUtils .hasText (basePackage )) {
232
+ basePackages .add (basePackage );
242
233
}
243
234
}
235
+ for (Class <?> markerClass : annotation .basePackageClasses ()) {
236
+ basePackages .add (ClassUtils .getPackageName (markerClass ));
237
+ }
244
238
return basePackages ;
245
239
}
246
240
0 commit comments