Skip to content

Commit 8704ad9

Browse files
committed
Clear caches which are not needed after singleton instantiation
Closes gh-28293
1 parent c57b7e8 commit 8704ad9

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@
159159
public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
160160
MergedBeanDefinitionPostProcessor, BeanRegistrationAotProcessor, PriorityOrdered, BeanFactoryAware {
161161

162+
private static final Constructor<?>[] EMPTY_CONSTRUCTOR_ARRAY = new Constructor<?>[0];
163+
164+
162165
protected final Log logger = LogFactory.getLog(getClass());
163166

164167
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
@@ -286,7 +289,25 @@ public void setBeanFactory(BeanFactory beanFactory) {
286289

287290
@Override
288291
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
292+
// Register externally managed config members on bean definition.
289293
findInjectionMetadata(beanName, beanType, beanDefinition);
294+
295+
// Use opportunity to clear caches which are not needed after singleton instantiation.
296+
// The injectionMetadataCache itself is left intact since it cannot be reliably
297+
// reconstructed in terms of externally managed config members otherwise.
298+
if (beanDefinition.isSingleton()) {
299+
this.candidateConstructorsCache.remove(beanType);
300+
// With actual lookup overrides, keep it intact along with bean definition.
301+
if (!beanDefinition.hasMethodOverrides()) {
302+
this.lookupMethodsChecked.remove(beanName);
303+
}
304+
}
305+
}
306+
307+
@Override
308+
public void resetBeanDefinition(String beanName) {
309+
this.lookupMethodsChecked.remove(beanName);
310+
this.injectionMetadataCache.remove(beanName);
290311
}
291312

292313
@Override
@@ -324,12 +345,6 @@ private InjectionMetadata findInjectionMetadata(String beanName, Class<?> beanTy
324345
return metadata;
325346
}
326347

327-
@Override
328-
public void resetBeanDefinition(String beanName) {
329-
this.lookupMethodsChecked.remove(beanName);
330-
this.injectionMetadataCache.remove(beanName);
331-
}
332-
333348
@Override
334349
public Class<?> determineBeanType(Class<?> beanClass, String beanName) throws BeanCreationException {
335350
checkLookupMethods(beanClass, beanName);
@@ -429,7 +444,7 @@ else if (candidates.size() == 1 && logger.isInfoEnabled()) {
429444
"default constructor to fall back to: " + candidates.get(0));
430445
}
431446
}
432-
candidateConstructors = candidates.toArray(new Constructor<?>[0]);
447+
candidateConstructors = candidates.toArray(EMPTY_CONSTRUCTOR_ARRAY);
433448
}
434449
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
435450
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
@@ -442,7 +457,7 @@ else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
442457
candidateConstructors = new Constructor<?>[] {primaryConstructor};
443458
}
444459
else {
445-
candidateConstructors = new Constructor<?>[0];
460+
candidateConstructors = EMPTY_CONSTRUCTOR_ARRAY;
446461
}
447462
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
448463
}

0 commit comments

Comments
 (0)