1
1
/*
2
- * Copyright 2002-2012 the original author or authors.
2
+ * Copyright 2002-2013 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
16
16
17
17
package org .springframework .web .context .support ;
18
18
19
+ import java .util .Arrays ;
20
+ import java .util .LinkedHashSet ;
21
+ import java .util .Set ;
22
+
19
23
import org .springframework .beans .factory .support .BeanNameGenerator ;
20
24
import org .springframework .beans .factory .support .DefaultListableBeanFactory ;
21
25
import org .springframework .context .annotation .AnnotatedBeanDefinitionReader ;
22
26
import org .springframework .context .annotation .AnnotationConfigUtils ;
23
27
import org .springframework .context .annotation .ClassPathBeanDefinitionScanner ;
24
28
import org .springframework .context .annotation .ScopeMetadataResolver ;
25
29
import org .springframework .util .Assert ;
26
- import org .springframework .util .ObjectUtils ;
27
30
import org .springframework .util .StringUtils ;
28
31
import org .springframework .web .context .ContextLoader ;
29
32
64
67
* {@linkplain ContextLoader#CONTEXT_INITIALIZER_CLASSES_PARAM "contextInitializerClasses"}
65
68
* context-param / init-param. In such cases, users should favor the {@link #refresh()}
66
69
* and {@link #scan(String...)} methods over the {@link #setConfigLocation(String)}
67
- * method, which is primarily for use by {@code ContextLoader}
70
+ * method, which is primarily for use by {@code ContextLoader}.
68
71
*
69
72
* <p>Note: In case of multiple {@code @Configuration} classes, later {@code @Bean}
70
73
* definitions will override ones defined in earlier loaded files. This can be leveraged
77
80
*/
78
81
public class AnnotationConfigWebApplicationContext extends AbstractRefreshableWebApplicationContext {
79
82
80
- private Class <?>[] annotatedClasses ;
81
-
82
- private String [] basePackages ;
83
-
84
83
private BeanNameGenerator beanNameGenerator ;
85
84
86
85
private ScopeMetadataResolver scopeMetadataResolver ;
87
86
87
+ private final Set <Class <?>> annotatedClasses = new LinkedHashSet <Class <?>>();
88
+
89
+ private final Set <String > basePackages = new LinkedHashSet <String >();
90
+
91
+
88
92
/**
89
- * {@inheritDoc}
90
- * <p>This implementation accepts delimited values in the form of fully-qualified
91
- * class names, (typically of {@code Configuration} classes) or fully-qualified
92
- * packages to scan for annotated classes. During {@link #loadBeanDefinitions}, these
93
- * locations will be processed in their given order, first attempting to load each
94
- * value as a class. If class loading fails (i.e. a {@code ClassNotFoundException}
95
- * occurs), the value is assumed to be a package and scanning is attempted.
96
- * <p>Note that this method exists primarily for compatibility with Spring's
97
- * {@link org.springframework.web.context.ContextLoader} and that if this application
98
- * context is being configured through an
99
- * {@link org.springframework.context.ApplicationContextInitializer}, use of the
100
- * {@link #register} and {@link #scan} methods are preferred.
101
- * @see #register(Class...)
102
- * @see #scan(String...)
103
- * @see #setConfigLocations(String[])
104
- * @see #loadBeanDefinitions(DefaultListableBeanFactory)
93
+ * Set a custom {@link BeanNameGenerator} for use with {@link AnnotatedBeanDefinitionReader}
94
+ * and/or {@link ClassPathBeanDefinitionScanner}.
95
+ * <p>Default is {@link org.springframework.context.annotation.AnnotationBeanNameGenerator}.
96
+ * @see AnnotatedBeanDefinitionReader#setBeanNameGenerator
97
+ * @see ClassPathBeanDefinitionScanner#setBeanNameGenerator
105
98
*/
106
- @ Override
107
- public void setConfigLocation (String location ) {
108
- super .setConfigLocation (location );
99
+ public void setBeanNameGenerator (BeanNameGenerator beanNameGenerator ) {
100
+ this .beanNameGenerator = beanNameGenerator ;
109
101
}
110
102
111
103
/**
112
- * {@inheritDoc}
113
- * <p>This implementation accepts individual location values as fully-qualified class
114
- * names (typically {@code @Configuration} classes) or fully-qualified packages to
115
- * scan. During {@link #loadBeanDefinitions}, these locations will be processed in
116
- * order, first attempting to load values as a class, and upon class loading failure
117
- * the value is assumed to be a package to be scanned.
118
- * <p>Note that this method exists primarily for compatibility with Spring's
119
- * {@link org.springframework.web.context.ContextLoader} and that if this application
120
- * context is being configured through an
121
- * {@link org.springframework.context.ApplicationContextInitializer}, use of the
122
- * {@link #register} and {@link #scan} methods are preferred.
123
- * @see #scan(String...)
124
- * @see #register(Class...)
125
- * @see #setConfigLocation(String)
126
- * @see #loadBeanDefinitions(DefaultListableBeanFactory)
104
+ * Return the custom {@link BeanNameGenerator} for use with {@link AnnotatedBeanDefinitionReader}
105
+ * and/or {@link ClassPathBeanDefinitionScanner}, if any.
127
106
*/
128
- @ Override
129
- public void setConfigLocations (String [] locations ) {
130
- super .setConfigLocations (locations );
107
+ protected BeanNameGenerator getBeanNameGenerator () {
108
+ return this .beanNameGenerator ;
131
109
}
132
110
111
+ /**
112
+ * Set a custom {@link ScopeMetadataResolver} for use with {@link AnnotatedBeanDefinitionReader}
113
+ * and/or {@link ClassPathBeanDefinitionScanner}.
114
+ * <p>Default is an {@link org.springframework.context.annotation.AnnotationScopeMetadataResolver}.
115
+ * @see AnnotatedBeanDefinitionReader#setScopeMetadataResolver
116
+ * @see ClassPathBeanDefinitionScanner#setScopeMetadataResolver
117
+ */
118
+ public void setScopeMetadataResolver (ScopeMetadataResolver scopeMetadataResolver ) {
119
+ this .scopeMetadataResolver = scopeMetadataResolver ;
120
+ }
121
+
122
+ /**
123
+ * Return the custom {@link ScopeMetadataResolver} for use with {@link AnnotatedBeanDefinitionReader}
124
+ * and/or {@link ClassPathBeanDefinitionScanner}, if any.
125
+ */
126
+ protected ScopeMetadataResolver getScopeMetadataResolver () {
127
+ return this .scopeMetadataResolver ;
128
+ }
129
+
130
+
133
131
/**
134
132
* Register one or more annotated classes to be processed.
135
- * Note that {@link #refresh()} must be called in order for the context to fully
136
- * process the new class.
137
- * <p>Calls to {@link # register} are idempotent; adding the same
133
+ * Note that {@link #refresh()} must be called in order for the context
134
+ * to fully process the new class.
135
+ * <p>Calls to {@code register} are idempotent; adding the same
138
136
* annotated class more than once has no additional effect.
139
137
* @param annotatedClasses one or more annotated classes,
140
138
* e.g. {@link org.springframework.context.annotation.Configuration @Configuration} classes
@@ -145,7 +143,7 @@ public void setConfigLocations(String[] locations) {
145
143
*/
146
144
public void register (Class <?>... annotatedClasses ) {
147
145
Assert .notEmpty (annotatedClasses , "At least one annotated class must be specified" );
148
- this .annotatedClasses = annotatedClasses ;
146
+ this .annotatedClasses . addAll ( Arrays . asList ( annotatedClasses )) ;
149
147
}
150
148
151
149
/**
@@ -160,9 +158,10 @@ public void register(Class<?>... annotatedClasses) {
160
158
*/
161
159
public void scan (String ... basePackages ) {
162
160
Assert .notEmpty (basePackages , "At least one base package must be specified" );
163
- this .basePackages = basePackages ;
161
+ this .basePackages . addAll ( Arrays . asList ( basePackages )) ;
164
162
}
165
163
164
+
166
165
/**
167
166
* Register a {@link org.springframework.beans.factory.config.BeanDefinition} for
168
167
* any classes specified by {@link #register(Class...)} and scan any packages
@@ -205,20 +204,20 @@ protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
205
204
scanner .setScopeMetadataResolver (scopeMetadataResolver );
206
205
}
207
206
208
- if (!ObjectUtils . isEmpty ( this .annotatedClasses )) {
207
+ if (!this .annotatedClasses . isEmpty ( )) {
209
208
if (logger .isInfoEnabled ()) {
210
209
logger .info ("Registering annotated classes: [" +
211
- StringUtils .arrayToCommaDelimitedString (this .annotatedClasses ) + "]" );
210
+ StringUtils .collectionToCommaDelimitedString (this .annotatedClasses ) + "]" );
212
211
}
213
- reader .register (this .annotatedClasses );
212
+ reader .register (this .annotatedClasses . toArray ( new Class <?>[ this . annotatedClasses . size ()]) );
214
213
}
215
214
216
- if (!ObjectUtils . isEmpty ( this .basePackages )) {
215
+ if (!this .basePackages . isEmpty ( )) {
217
216
if (logger .isInfoEnabled ()) {
218
217
logger .info ("Scanning base packages: [" +
219
- StringUtils .arrayToCommaDelimitedString (this .basePackages ) + "]" );
218
+ StringUtils .collectionToCommaDelimitedString (this .basePackages ) + "]" );
220
219
}
221
- scanner .scan (this .basePackages );
220
+ scanner .scan (this .basePackages . toArray ( new String [ this . basePackages . size ()]) );
222
221
}
223
222
224
223
String [] configLocations = getConfigLocations ();
@@ -250,37 +249,4 @@ protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
250
249
}
251
250
}
252
251
253
- public void setBeanNameGenerator (BeanNameGenerator beanNameGenerator ) {
254
- this .beanNameGenerator = beanNameGenerator ;
255
- }
256
-
257
- /**
258
- * Provide a custom {@link BeanNameGenerator} for use with {@link AnnotatedBeanDefinitionReader}
259
- * and/or {@link ClassPathBeanDefinitionScanner}, if any.
260
- * <p>Default is {@link org.springframework.context.annotation.AnnotationBeanNameGenerator}.
261
- * @see AnnotatedBeanDefinitionReader#setBeanNameGenerator
262
- * @see ClassPathBeanDefinitionScanner#setBeanNameGenerator
263
- */
264
- protected BeanNameGenerator getBeanNameGenerator () {
265
- return this .beanNameGenerator ;
266
- }
267
-
268
- /**
269
- * Set the {@link ScopeMetadataResolver} to use for detected bean classes.
270
- * <p>The default is an {@link org.springframework.context.annotation.AnnotationScopeMetadataResolver}.
271
- */
272
- public void setScopeMetadataResolver (ScopeMetadataResolver scopeMetadataResolver ) {
273
- this .scopeMetadataResolver = scopeMetadataResolver ;
274
- }
275
-
276
- /**
277
- * Provide a custom {@link ScopeMetadataResolver} for use with {@link AnnotatedBeanDefinitionReader}
278
- * and/or {@link ClassPathBeanDefinitionScanner}, if any.
279
- * <p>Default is {@link org.springframework.context.annotation.AnnotationScopeMetadataResolver}.
280
- * @see AnnotatedBeanDefinitionReader#setScopeMetadataResolver
281
- * @see ClassPathBeanDefinitionScanner#setScopeMetadataResolver
282
- */
283
- protected ScopeMetadataResolver getScopeMetadataResolver () {
284
- return this .scopeMetadataResolver ;
285
- }
286
252
}
0 commit comments