Skip to content

Commit 243e21a

Browse files
committed
Backport streamlined ClassPathBeanDefinitionScanner setup
Issue: SPR-15061
1 parent 20aaa88 commit 243e21a

File tree

6 files changed

+123
-95
lines changed

6 files changed

+123
-95
lines changed

spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigApplicationContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
* deliberately override certain bean definitions via an extra {@code @Configuration}
3636
* class.
3737
*
38-
* <p>See @{@link Configuration} Javadoc for usage examples.
38+
* <p>See @{@link Configuration}'s javadoc for usage examples.
3939
*
4040
* @author Chris Beams
4141
* @author Juergen Hoeller

spring-context/src/main/java/org/springframework/context/annotation/ClassPathBeanDefinitionScanner.java

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -132,16 +132,39 @@ public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean u
132132
* @since 3.1
133133
* @see #setResourceLoader
134134
*/
135-
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment) {
136-
super(useDefaultFilters, environment);
135+
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
136+
Environment environment) {
137+
138+
this(registry, useDefaultFilters, environment,
139+
(registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
140+
}
141+
142+
/**
143+
* Create a new {@code ClassPathBeanDefinitionScanner} for the given bean factory and
144+
* using the given {@link Environment} when evaluating bean definition profile metadata.
145+
* @param registry the {@code BeanFactory} to load bean definitions into, in the form
146+
* of a {@code BeanDefinitionRegistry}
147+
* @param useDefaultFilters whether to include the default filters for the
148+
* {@link org.springframework.stereotype.Component @Component},
149+
* {@link org.springframework.stereotype.Repository @Repository},
150+
* {@link org.springframework.stereotype.Service @Service}, and
151+
* {@link org.springframework.stereotype.Controller @Controller} stereotype annotations
152+
* @param environment the Spring {@link Environment} to use when evaluating bean
153+
* definition profile metadata
154+
* @param resourceLoader the {@link ResourceLoader} to use
155+
* @since 4.3.6
156+
*/
157+
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
158+
Environment environment, ResourceLoader resourceLoader) {
137159

138160
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
139161
this.registry = registry;
140162

141-
// Determine ResourceLoader to use.
142-
if (this.registry instanceof ResourceLoader) {
143-
setResourceLoader((ResourceLoader) this.registry);
163+
if (useDefaultFilters) {
164+
registerDefaultFilters();
144165
}
166+
setEnvironment(environment);
167+
setResourceLoader(resourceLoader);
145168
}
146169

147170

@@ -192,7 +215,8 @@ public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
192215
* @see #setScopedProxyMode
193216
*/
194217
public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {
195-
this.scopeMetadataResolver = (scopeMetadataResolver != null ? scopeMetadataResolver : new AnnotationScopeMetadataResolver());
218+
this.scopeMetadataResolver =
219+
(scopeMetadataResolver != null ? scopeMetadataResolver : new AnnotationScopeMetadataResolver());
196220
}
197221

198222
/**
@@ -258,7 +282,8 @@ protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
258282
}
259283
if (checkCandidate(beanName, candidate)) {
260284
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
261-
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
285+
definitionHolder =
286+
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
262287
beanDefinitions.add(definitionHolder);
263288
registerBeanDefinition(definitionHolder, this.registry);
264289
}

spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java

Lines changed: 80 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -36,7 +36,6 @@
3636
import org.springframework.core.env.StandardEnvironment;
3737
import org.springframework.core.io.Resource;
3838
import org.springframework.core.io.ResourceLoader;
39-
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
4039
import org.springframework.core.io.support.ResourcePatternResolver;
4140
import org.springframework.core.io.support.ResourcePatternUtils;
4241
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
@@ -72,23 +71,30 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
7271

7372
static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
7473

75-
protected final Log logger = LogFactory.getLog(getClass());
76-
77-
private Environment environment;
7874

79-
private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
80-
81-
private MetadataReaderFactory metadataReaderFactory =
82-
new CachingMetadataReaderFactory(this.resourcePatternResolver);
75+
protected final Log logger = LogFactory.getLog(getClass());
8376

8477
private String resourcePattern = DEFAULT_RESOURCE_PATTERN;
8578

8679
private final List<TypeFilter> includeFilters = new LinkedList<TypeFilter>();
8780

8881
private final List<TypeFilter> excludeFilters = new LinkedList<TypeFilter>();
8982

83+
private Environment environment;
84+
9085
private ConditionEvaluator conditionEvaluator;
9186

87+
private ResourcePatternResolver resourcePatternResolver;
88+
89+
private MetadataReaderFactory metadataReaderFactory;
90+
91+
92+
/**
93+
* Protected constructor for flexible subclass initialization.
94+
* @since 4.3.6
95+
*/
96+
protected ClassPathScanningCandidateComponentProvider() {
97+
}
9298

9399
/**
94100
* Create a ClassPathScanningCandidateComponentProvider with a {@link StandardEnvironment}.
@@ -115,73 +121,10 @@ public ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters, En
115121
if (useDefaultFilters) {
116122
registerDefaultFilters();
117123
}
118-
Assert.notNull(environment, "Environment must not be null");
119-
this.environment = environment;
120-
}
121-
122-
123-
/**
124-
* Set the ResourceLoader to use for resource locations.
125-
* This will typically be a ResourcePatternResolver implementation.
126-
* <p>Default is PathMatchingResourcePatternResolver, also capable of
127-
* resource pattern resolving through the ResourcePatternResolver interface.
128-
* @see org.springframework.core.io.support.ResourcePatternResolver
129-
* @see org.springframework.core.io.support.PathMatchingResourcePatternResolver
130-
*/
131-
@Override
132-
public void setResourceLoader(ResourceLoader resourceLoader) {
133-
this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
134-
this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
135-
}
136-
137-
/**
138-
* Return the ResourceLoader that this component provider uses.
139-
*/
140-
public final ResourceLoader getResourceLoader() {
141-
return this.resourcePatternResolver;
124+
setEnvironment(environment);
125+
setResourceLoader(null);
142126
}
143127

144-
/**
145-
* Set the {@link MetadataReaderFactory} to use.
146-
* <p>Default is a {@link CachingMetadataReaderFactory} for the specified
147-
* {@linkplain #setResourceLoader resource loader}.
148-
* <p>Call this setter method <i>after</i> {@link #setResourceLoader} in order
149-
* for the given MetadataReaderFactory to override the default factory.
150-
*/
151-
public void setMetadataReaderFactory(MetadataReaderFactory metadataReaderFactory) {
152-
this.metadataReaderFactory = metadataReaderFactory;
153-
}
154-
155-
/**
156-
* Return the MetadataReaderFactory used by this component provider.
157-
*/
158-
public final MetadataReaderFactory getMetadataReaderFactory() {
159-
return this.metadataReaderFactory;
160-
}
161-
162-
/**
163-
* Set the Environment to use when resolving placeholders and evaluating
164-
* {@link Conditional @Conditional}-annotated component classes.
165-
* <p>The default is a {@link StandardEnvironment}.
166-
* @param environment the Environment to use
167-
*/
168-
public void setEnvironment(Environment environment) {
169-
Assert.notNull(environment, "Environment must not be null");
170-
this.environment = environment;
171-
this.conditionEvaluator = null;
172-
}
173-
174-
@Override
175-
public final Environment getEnvironment() {
176-
return this.environment;
177-
}
178-
179-
/**
180-
* Returns the {@link BeanDefinitionRegistry} used by this scanner, if any.
181-
*/
182-
protected BeanDefinitionRegistry getRegistry() {
183-
return null;
184-
}
185128

186129
/**
187130
* Set the resource pattern to use when scanning the classpath.
@@ -256,6 +199,69 @@ protected void registerDefaultFilters() {
256199
}
257200
}
258201

202+
/**
203+
* Set the Environment to use when resolving placeholders and evaluating
204+
* {@link Conditional @Conditional}-annotated component classes.
205+
* <p>The default is a {@link StandardEnvironment}.
206+
* @param environment the Environment to use
207+
*/
208+
public void setEnvironment(Environment environment) {
209+
Assert.notNull(environment, "Environment must not be null");
210+
this.environment = environment;
211+
this.conditionEvaluator = null;
212+
}
213+
214+
@Override
215+
public final Environment getEnvironment() {
216+
return this.environment;
217+
}
218+
219+
/**
220+
* Return the {@link BeanDefinitionRegistry} used by this scanner, if any.
221+
*/
222+
protected BeanDefinitionRegistry getRegistry() {
223+
return null;
224+
}
225+
226+
/**
227+
* Set the {@link ResourceLoader} to use for resource locations.
228+
* This will typically be a {@link ResourcePatternResolver} implementation.
229+
* <p>Default is a {@code PathMatchingResourcePatternResolver}, also capable of
230+
* resource pattern resolving through the {@code ResourcePatternResolver} interface.
231+
* @see org.springframework.core.io.support.ResourcePatternResolver
232+
* @see org.springframework.core.io.support.PathMatchingResourcePatternResolver
233+
*/
234+
@Override
235+
public void setResourceLoader(ResourceLoader resourceLoader) {
236+
this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
237+
this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
238+
}
239+
240+
/**
241+
* Return the ResourceLoader that this component provider uses.
242+
*/
243+
public final ResourceLoader getResourceLoader() {
244+
return this.resourcePatternResolver;
245+
}
246+
247+
/**
248+
* Set the {@link MetadataReaderFactory} to use.
249+
* <p>Default is a {@link CachingMetadataReaderFactory} for the specified
250+
* {@linkplain #setResourceLoader resource loader}.
251+
* <p>Call this setter method <i>after</i> {@link #setResourceLoader} in order
252+
* for the given MetadataReaderFactory to override the default factory.
253+
*/
254+
public void setMetadataReaderFactory(MetadataReaderFactory metadataReaderFactory) {
255+
this.metadataReaderFactory = metadataReaderFactory;
256+
}
257+
258+
/**
259+
* Return the MetadataReaderFactory used by this component provider.
260+
*/
261+
public final MetadataReaderFactory getMetadataReaderFactory() {
262+
return this.metadataReaderFactory;
263+
}
264+
259265

260266
/**
261267
* Scan the class path for candidate components.

spring-context/src/main/java/org/springframework/context/annotation/ComponentScanAnnotationParser.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,8 @@ public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final
7777
Assert.state(this.environment != null, "Environment must not be null");
7878
Assert.state(this.resourceLoader != null, "ResourceLoader must not be null");
7979

80-
ClassPathBeanDefinitionScanner scanner =
81-
new ClassPathBeanDefinitionScanner(this.registry, componentScan.getBoolean("useDefaultFilters"));
82-
scanner.setEnvironment(this.environment);
83-
scanner.setResourceLoader(this.resourceLoader);
80+
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
81+
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
8482

8583
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
8684
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);

spring-context/src/main/java/org/springframework/context/annotation/ComponentScanBeanDefinitionParser.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -98,8 +98,6 @@ protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserCo
9898

9999
// Delegate bean definition registration to scanner class.
100100
ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters);
101-
scanner.setResourceLoader(parserContext.getReaderContext().getResourceLoader());
102-
scanner.setEnvironment(parserContext.getReaderContext().getEnvironment());
103101
scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
104102
scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());
105103

@@ -127,7 +125,8 @@ protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserCo
127125
}
128126

129127
protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) {
130-
return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters);
128+
return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters,
129+
readerContext.getEnvironment(), readerContext.getResourceLoader());
131130
}
132131

133132
protected void registerComponents(
@@ -266,7 +265,7 @@ private Object instantiateUserDefinedStrategy(String className, Class<?> strateg
266265
throw new IllegalArgumentException("Class [" + className + "] for strategy [" +
267266
strategyType.getName() + "] not found", ex);
268267
}
269-
catch (Exception ex) {
268+
catch (Throwable ex) {
270269
throw new IllegalArgumentException("Unable to instantiate class [" + className + "] for strategy [" +
271270
strategyType.getName() + "]: a zero-argument constructor is required", ex);
272271
}

spring-core/src/main/java/org/springframework/core/type/classreading/CachingMetadataReaderFactory.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@
2525

2626
/**
2727
* Caching implementation of the {@link MetadataReaderFactory} interface,
28-
* caching {@link MetadataReader} per Spring {@link Resource} handle
28+
* caching a {@link MetadataReader} instance per Spring {@link Resource} handle
2929
* (i.e. per ".class" file).
3030
*
3131
* @author Juergen Hoeller
@@ -77,7 +77,7 @@ public CachingMetadataReaderFactory(ClassLoader classLoader) {
7777

7878
/**
7979
* Specify the maximum number of entries for the MetadataReader cache.
80-
* Default is 256.
80+
* <p>Default is 256.
8181
*/
8282
public void setCacheLimit(int cacheLimit) {
8383
this.cacheLimit = cacheLimit;

0 commit comments

Comments
 (0)