Skip to content

Commit 1cb6e3d

Browse files
jhoellerunknown
authored and
unknown
committed
Several enhancements with respect to CachingMetadataReaderFactory handling.
Added "clearCache()" method to CachingMetadataReaderFactory, for clearing the metadata cache once not needed anymore - in particular when the MetadataReaderFactory instance is long-lived. Also added "setMetadataReaderFactory" method to ClassPathScanningCandidateComponentProvider, analogous to ConfigurationClassPostProcessor.
1 parent e298658 commit 1cb6e3d

File tree

4 files changed

+63
-14
lines changed

4 files changed

+63
-14
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,10 @@ public void scan(String... basePackages) {
153153
this.scanner.scan(basePackages);
154154
}
155155

156+
@Override
157+
protected void prepareRefresh() {
158+
this.scanner.clearCache();
159+
super.prepareRefresh();
160+
}
161+
156162
}

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

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
import org.apache.commons.logging.Log;
2727
import org.apache.commons.logging.LogFactory;
28+
2829
import org.springframework.beans.factory.BeanDefinitionStoreException;
2930
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
3031
import org.springframework.beans.factory.config.BeanDefinition;
@@ -78,7 +79,8 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
7879

7980
private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
8081

81-
private MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver);
82+
private MetadataReaderFactory metadataReaderFactory =
83+
new CachingMetadataReaderFactory(this.resourcePatternResolver);
8284

8385
private String resourcePattern = DEFAULT_RESOURCE_PATTERN;
8486

@@ -120,6 +122,31 @@ public void setResourceLoader(ResourceLoader resourceLoader) {
120122
this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
121123
}
122124

125+
/**
126+
* Return the ResourceLoader that this component provider uses.
127+
*/
128+
public final ResourceLoader getResourceLoader() {
129+
return this.resourcePatternResolver;
130+
}
131+
132+
/**
133+
* Set the {@link MetadataReaderFactory} to use.
134+
* <p>Default is a {@link CachingMetadataReaderFactory} for the specified
135+
* {@linkplain #setResourceLoader resource loader}.
136+
* <p>Call this setter method <i>after</i> {@link #setResourceLoader} in order
137+
* for the given MetadataReaderFactory to override the default factory.
138+
*/
139+
public void setMetadataReaderFactory(MetadataReaderFactory metadataReaderFactory) {
140+
this.metadataReaderFactory = metadataReaderFactory;
141+
}
142+
143+
/**
144+
* Return the MetadataReaderFactory used by this component provider.
145+
*/
146+
public final MetadataReaderFactory getMetadataReaderFactory() {
147+
return this.metadataReaderFactory;
148+
}
149+
123150
/**
124151
* Set the Environment to use when resolving placeholders and evaluating
125152
* {@link Profile @Profile}-annotated component classes.
@@ -130,17 +157,10 @@ public void setEnvironment(Environment environment) {
130157
this.environment = environment;
131158
}
132159

133-
public Environment getEnvironment() {
160+
public final Environment getEnvironment() {
134161
return this.environment;
135162
}
136163

137-
/**
138-
* Return the ResourceLoader that this component provider uses.
139-
*/
140-
public final ResourceLoader getResourceLoader() {
141-
return this.resourcePatternResolver;
142-
}
143-
144164
/**
145165
* Set the resource pattern to use when scanning the classpath.
146166
* This value will be appended to each base package name.
@@ -324,4 +344,14 @@ protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
324344
return (beanDefinition.getMetadata().isConcrete() && beanDefinition.getMetadata().isIndependent());
325345
}
326346

347+
348+
/**
349+
* Clear the underlying metadata cache, removing all cached class metadata.
350+
*/
351+
public void clearCache() {
352+
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
353+
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
354+
}
355+
}
356+
327357
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,10 @@ public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
320320
singletonRegistry.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
321321
}
322322
}
323+
324+
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
325+
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
326+
}
323327
}
324328

325329
/**

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

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2010 the original author or authors.
2+
* Copyright 2002-2012 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.
@@ -40,7 +40,7 @@ public class CachingMetadataReaderFactory extends SimpleMetadataReaderFactory {
4040

4141
private volatile int cacheLimit = DEFAULT_CACHE_LIMIT;
4242

43-
private final Map<Resource, MetadataReader> classReaderCache =
43+
private final Map<Resource, MetadataReader> metadataReaderCache =
4444
new LinkedHashMap<Resource, MetadataReader>(DEFAULT_CACHE_LIMIT, 0.75f, true) {
4545
@Override
4646
protected boolean removeEldestEntry(Map.Entry<Resource, MetadataReader> eldest) {
@@ -95,14 +95,23 @@ public MetadataReader getMetadataReader(Resource resource) throws IOException {
9595
if (getCacheLimit() <= 0) {
9696
return super.getMetadataReader(resource);
9797
}
98-
synchronized (this.classReaderCache) {
99-
MetadataReader metadataReader = this.classReaderCache.get(resource);
98+
synchronized (this.metadataReaderCache) {
99+
MetadataReader metadataReader = this.metadataReaderCache.get(resource);
100100
if (metadataReader == null) {
101101
metadataReader = super.getMetadataReader(resource);
102-
this.classReaderCache.put(resource, metadataReader);
102+
this.metadataReaderCache.put(resource, metadataReader);
103103
}
104104
return metadataReader;
105105
}
106106
}
107107

108+
/**
109+
* Clear the entire MetadataReader cache, removing all cached class metadata.
110+
*/
111+
public void clearCache() {
112+
synchronized (this.metadataReaderCache) {
113+
this.metadataReaderCache.clear();
114+
}
115+
}
116+
108117
}

0 commit comments

Comments
 (0)