Skip to content

Commit 2ec7d5c

Browse files
committed
Support load-time weaving for @component classes again
Since Spring Framework 5.2, the LoadTimeWeaver no longer weaves bean classes annotated with @component. This is a regression caused by the changes in 40c6213, stemming from the fact that any class annotated or meta-annotated with @component is considered to be a candidate configuration class in 'configuration lite' mode (i.e., a class without the @configuration annotation and without any @bean methods) and therefore now has its class eagerly loaded. This results in the class being loaded before the LoadTimeWeaver has a chance to weave it. This commit fixes this regression by explicitly avoiding eager class loading for any 'lite' @configuration or @component class without @bean methods. Closes gh-26199
1 parent 9f7c8ae commit 2ec7d5c

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

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

+18-8
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
* @author Chris Beams
8282
* @author Juergen Hoeller
8383
* @author Phillip Webb
84+
* @author Sam Brannen
8485
* @since 3.0
8586
*/
8687
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
@@ -376,21 +377,30 @@ public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFact
376377
for (String beanName : beanFactory.getBeanDefinitionNames()) {
377378
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
378379
Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);
380+
AnnotationMetadata annotationMetadata = null;
379381
MethodMetadata methodMetadata = null;
380382
if (beanDef instanceof AnnotatedBeanDefinition) {
381-
methodMetadata = ((AnnotatedBeanDefinition) beanDef).getFactoryMethodMetadata();
383+
AnnotatedBeanDefinition annotatedBeanDefinition = (AnnotatedBeanDefinition) beanDef;
384+
annotationMetadata = annotatedBeanDefinition.getMetadata();
385+
methodMetadata = annotatedBeanDefinition.getFactoryMethodMetadata();
382386
}
383387
if ((configClassAttr != null || methodMetadata != null) && beanDef instanceof AbstractBeanDefinition) {
384388
// Configuration class (full or lite) or a configuration-derived @Bean method
385-
// -> resolve bean class at this point...
389+
// -> eagerly resolve bean class at this point, unless it's a 'lite' configuration
390+
// or component class without @Bean methods.
386391
AbstractBeanDefinition abd = (AbstractBeanDefinition) beanDef;
387392
if (!abd.hasBeanClass()) {
388-
try {
389-
abd.resolveBeanClass(this.beanClassLoader);
390-
}
391-
catch (Throwable ex) {
392-
throw new IllegalStateException(
393-
"Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
393+
boolean liteConfigurationCandidateWithoutBeanMethods =
394+
(ConfigurationClassUtils.CONFIGURATION_CLASS_LITE.equals(configClassAttr) &&
395+
annotationMetadata != null && !ConfigurationClassUtils.hasBeanMethods(annotationMetadata));
396+
if (!liteConfigurationCandidateWithoutBeanMethods) {
397+
try {
398+
abd.resolveBeanClass(this.beanClassLoader);
399+
}
400+
catch (Throwable ex) {
401+
throw new IllegalStateException(
402+
"Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
403+
}
394404
}
395405
}
396406
}

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2021 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.
@@ -46,6 +46,7 @@
4646
*
4747
* @author Chris Beams
4848
* @author Juergen Hoeller
49+
* @author Sam Brannen
4950
* @since 3.1
5051
*/
5152
abstract class ConfigurationClassUtils {
@@ -162,6 +163,10 @@ public static boolean isConfigurationCandidate(AnnotationMetadata metadata) {
162163
}
163164

164165
// Finally, let's look for @Bean methods...
166+
return hasBeanMethods(metadata);
167+
}
168+
169+
static boolean hasBeanMethods(AnnotationMetadata metadata) {
165170
try {
166171
return metadata.hasAnnotatedMethods(Bean.class.getName());
167172
}

0 commit comments

Comments
 (0)