refresh过程——invokeBeanFactoryPostProcessors(beanFactory)

invokeBeanFactoryPostProcessors 在 Spring 启动流程中,是非常重要的一个步骤,此阶段会实例化并调用所有注册的 BeanFactoryPostProcessor beans。

方法有两个入参,分别是 工厂 beanFactory 和 初始的List<BeanFactoryPostProcessor>。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();

if (beanFactory instanceof BeanDefinitionRegistry) {
// beanFactory 默认是 DefaultListableBeanFactory 类型,实现了 DefaultListableBeanFactory 接口,会走进这个条件里
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

// beanFactoryPostProcessors 是方法传进来的参数,里面有三个BeanFactoryPostProcessor,他们对本文不重要。判断类型如果是 BeanDefinitionRegistryPostProcessor 就调用 postProcessBeanDefinitionRegistry 方法,并添加到 registryProcessor 中;如果不是,就先添加到 regularPostProcessors 中。之后会一起调用这两个集合中 BeanFactoryPostProcessor实例的postProcessBeanFactory方法。
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}

// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 首先获取所有实现了 PriorityOrdered 优先级接口的 BeanDefinitionRegistryPostProcessor,这个接口有能力添加 beanDefinition 到 beanFactory 中,这次只会找到一个 ConfigurationClassPostProcessor ,这是Spring最重要的一个处理器,它会找到 basePackages 下的所有 bean 的候选类,生成 beanDefinition 并添加到 beanFactory 中。下面会详谈这个处理器。
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 创建这个 bean
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 标记这个处理器已经执行过,防止重复执行
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 下面两行代码会出现很多次,把 BeanDefinitionRegistryPostProcessor 放到一个list 里是为了最后调用它们实现 BeanFactoryPostProcessor 接口的方法。因此,BeanDefinitionRegistryPostProcessor 的执行时机是早于所有的 BeanFactoryPostProcessor 的。
registryProcessors.addAll(currentRegistryProcessors);
// 因此调用 BeanDefinitionRegistryPostProcessor 的接口
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();

// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 其次,获取实现了 Ordered 接口的 BeanDefinitionRegistryPostProcessor, 和上面一样的流程,只是优先级的区别罢了。
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();

// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 最后,执行那些不带优先级注解的 BeanDefinitionRegistryPostProcessors 直到不再出现新的 BeanDefinitionRegistryPostProcessor 。为什么会出现呢,因为 BeanDefinitionRegistryPostProcessor 可以注册 BeanDefinitionRegistryPostProcessor 类型的 beanDefinition,所以就要用while循环不停地寻找了。
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 出现了新的 BeanDefinitionRegistryPostProcessor, 标记为已执行,并且设置需要继续循环
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}

// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 走到了这里的时候,所有的 BeanDefinitionRegistryPostProcessor 已经调用完其 postProcessBeanDefinitionRegistry() 方法了,这些处理器也都存了下来。由于 BeanDefinitionRegistryPostProcessors 还继承了 BeanFactoryPostProcessor ,因此还需要调用所有 BeanDefinitionRegistryPostProcessor 的 postProcessBeanFactory() 方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}

else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}

// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// 下面的流程比较简单,找出所有的 BeanFactoryPostProcessor ,并按照其优先级依次调用其 postProcessBeanFactory() 方法。
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}

// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}

BeanDefinitionRegistryPostProcessor

在上面的代码中,逻辑比较清晰,主要有两步:找出所有BeanDefinitionRegistryPostProcessor,并按优先级依次调用;找出所有 BeanFactoryPostProcessor 并按优先级依次调用。

那 BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor 有什么区别呢?这父子俩源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

public interface BeanFactoryPostProcessor {

/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for overriding or adding
* properties even to eager-initializing beans.
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}


/**
* Extension to the standard {@link BeanFactoryPostProcessor} SPI, allowing for
* the registration of further bean definitions <i>before</i> regular
* BeanFactoryPostProcessor detection kicks in. In particular,
* BeanDefinitionRegistryPostProcessor may register further bean definitions
* which in turn define BeanFactoryPostProcessor instances.
*
* @author Juergen Hoeller
* @since 3.0.1
* @see org.springframework.context.annotation.ConfigurationClassPostProcessor
*/
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

/**
* Modify the application context's internal bean definition registry after its
* standard initialization. All regular bean definitions will have been loaded,
* but no beans will have been instantiated yet. This allows for adding further
* bean definitions before the next post-processing phase kicks in.
* @param registry the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}

BeanDefinitionRegistryPostProcessor 继承了 BeanFactoryPostProcessor,根据源码,其执行时机也是早于 BeanFactoryPostProcessor 的,在 自定义BeanFactoryPostProcessor的错误做法 中有介绍过 BeanFactoryPostProcessor 接口。

简而言之, BeanFactoryPostProcessor 允许你修改 BeanDefinition,BeanDefinitionRegistryPostProcessor 允许你动态的注册 BeanDefinition。

举个代码演示下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Cat {
var name = "猫"
constructor() {
println("构造方法 name = $name")
}
}

@Component
class MyBeanDefinitionRegistryPostProcessor : BeanDefinitionRegistryPostProcessor {

override fun postProcessBeanDefinitionRegistry(registry: BeanDefinitionRegistry) {
val beanDefinition = RootBeanDefinition(Cat::class.java)
registry.registerBeanDefinition("cat", beanDefinition)
}

override fun postProcessBeanFactory(beanFactory: ConfigurableListableBeanFactory) {}
}

很明显, Cat 类上并没有添加任何 Spring 的注解,就是个简单的 bean 类,但是我们却可以通过自定义的 MyBeanDefinitionRegistryPostProcessor 来注册一个名字叫 cat 的 Cat类型的 beanDefinition,并在之后的过程中实例化这个对象。

ConfigurationClassPostProcessor——最核心的类

我们可以自定义 BeanDefinitionRegistryPostProcessor 并注册一些 beanDefinition 的,执行完所有的 BeanDefinitionRegistryPostProcessor 后,继续执行所有的 BeanFactoryPostProcessor 接口,最后根据 beanDefinition 实例化对应的 bean。
但是否思考过 spring 是如何找到我们自定义的 BeanDefinitionRegistryPostProcessor 呢?就是靠 ConfigurationClassPostProcessor 处理器,它是第一个执行的 BeanDefinitionRegistryPostProcessor 处理器,它也 Spring 中是最核心的类,没有之一

我们常常会用 @Bean、@Component、@Service、@Configuration 等注解来标记一个类是 bean,Spring就是通过 ConfigurationClassPostProcessor 这个处理器来找到所有带这些注解的类的。

那思考一下,ConfigurationClassPostProcessor 自己是什么时候被添加到 beanFactory 的呢?是在初始化 context 容器的时候添加进去的,我们来查看源代码:

在run方法的时候

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 下面这行代码
context = createApplicationContext();

// 如果是web容器,上面那行代码会生成此类型的 ApplicationContext
public AnnotationConfigServletWebServerApplicationContext() {
// 这行代码是关键
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}

// AnnotationConfigServletWebServerApplicationContext 又继承了 GenericApplicationContext, 父类会 new一个 DefaultListableBeanFactory 作为 beanFactory。
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}

不停地深入this.reader = new AnnotatedBeanDefinitionReader(this);,最终会调用以下方法,这就是初始化添加一些处理器的地方。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

/**
* The bean name of the internally managed Configuration annotation processor.
*/
public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.context.annotation.internalConfigurationAnnotationProcessor";

/**
* The bean name of the internally managed Required annotation processor.
* @deprecated as of 5.1, since no Required processor is registered by default anymore
*/
@Deprecated
public static final String REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.context.annotation.internalRequiredAnnotationProcessor";

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {

DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}

Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// 如果没有 ConfigurationClassPostProcessor ,那就添加一个
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}

// 下面还有很多和上面类似的代码,添加一些初始的处理器,但不是这次关注重点,省略掉。
// ...

return beanDefs;
}

最后,我们再来看看 ConfigurationClassPostProcessor 这个核心类的核心方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
// 一开始能拿到几个为数不多的 beanNames,包括 @SpringBootApplication 注解修饰的启动类。
String[] candidateNames = registry.getBeanDefinitionNames();

for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
// 这里是判断这bean是否解析过,如果解析过,值会是 lite 或 full
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}

// Return immediately if no @Configuration classes were found
// 一般到这里,只会有启动类留下来,@SpringBootApplication 包含了 @Configuration
if (configCandidates.isEmpty()) {
return;
}

// Sort by previously determined @Order value, if applicable
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});

// Detect any custom bean name generation strategy supplied through the enclosing application context
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}

if (this.environment == null) {
this.environment = new StandardEnvironment();
}

// Parse each @Configuration class
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);

Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
// 这行代码是核心,参数 candidates 中只有一个启动类
parser.parse(candidates);
parser.validate();

Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);

// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);

candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());

// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}

if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}

doProcessConfigurationClass 核心方法,每个bean都调用一次

我们先跟进parser.parse(candidates);方法,一直跟进,最后会进入ConfigurationClassParser.java中的doProcessConfigurationClass方法,分析一下这个方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
protected final ConfigurationClassParser.SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, ConfigurationClassParser.SourceClass sourceClass, Predicate<String> filter)
throws IOException {

// 这次即第一次调用的入参,configClass、sourceClass 都是我们的启动类

if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// Recursively process any member (nested) classes first
// 注册bean的成员(嵌套)类。静态内部类、非静态内部类都可以被spring管理。
processMemberClasses(configClass, sourceClass, filter);
}

// Process any @PropertySource annotations
// ... 这有些代码不会执行到,就省略了。

// Process any @ComponentScan annotations
// 获取每一个 @ComponentScan 注解的属性,每一个 ComponentScan 里的所有属性会被放在 AnnotationAttributes 中
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationCondition.ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// The config class is annotated with @ComponentScan -> perform the scan immediately
// 对于每一个 ComponentScan ,都去扫描,这个是核心方法
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config classes and parse recursively if needed
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
// 判断是否是配置类的候选者,有 @Component @ComponentScan @Import @ImportResource 注解的类会通过判断,或者有方法被 @Bean 装饰
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
// 对于这些类,递归调用 doProcessConfigurationClass 方法,因为这些类中也可能有 @ComponentScan @Bean @Import 等注解
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}

// Process any @Import annotations
// 处理 @Import 注解
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

// Process any @ImportResource annotations
// 处理 @ImportResource 注解
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}

// Process individual @Bean methods
// 处理 @Bean 注解,先添加到 configclass 中, 之后会configClasses 调用 loadBeanDefinitions 方法,生成相应的 beanDefinitions
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}

// Process default methods on interfaces
processInterfaces(configClass, sourceClass);

// Process superclass, if any
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}

// No superclass -> processing is complete
return null;
}

processMemberClasses 方法,注册恰好是配置类本身的成员(嵌套)类。

如果有一个类被spring管理了,那它的静态内部类、非静态内部类也都可以被spring管理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/**
* Register member (nested) classes that happen to be configuration classes themselves.
*/
private void processMemberClasses(ConfigurationClass configClass, ConfigurationClassParser.SourceClass sourceClass,
Predicate<String> filter) throws IOException {

Collection<ConfigurationClassParser.SourceClass> memberClasses = sourceClass.getMemberClasses();
if (!memberClasses.isEmpty()) {
List<ConfigurationClassParser.SourceClass> candidates = new ArrayList<>(memberClasses.size());
for (ConfigurationClassParser.SourceClass memberClass : memberClasses) {
// 对每一个内部类进行判断是否是候选人,判断依据是是否有 @Component @ComponentScan @Import @ImportResource 注解,或者有方法被 @Bean 装饰
if (ConfigurationClassUtils.isConfigurationCandidate(memberClass.getMetadata()) &&
!memberClass.getMetadata().getClassName().equals(configClass.getMetadata().getClassName())) {
candidates.add(memberClass);
}
}
OrderComparator.sort(candidates);
for (ConfigurationClassParser.SourceClass candidate : candidates) {
if (this.importStack.contains(configClass)) {
this.problemReporter.error(new ConfigurationClassParser.CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
processConfigurationClass(candidate.asConfigClass(configClass), filter);
}
finally {
this.importStack.pop();
}
}
}
}
}

private static final Set<String> candidateIndicators = new HashSet<>(8);

static {
candidateIndicators.add(Component.class.getName());
candidateIndicators.add(ComponentScan.class.getName());
candidateIndicators.add(Import.class.getName());
candidateIndicators.add(ImportResource.class.getName());
}

public static boolean isConfigurationCandidate(AnnotationMetadata metadata) {
// Do not consider an interface or an annotation...
if (metadata.isInterface()) {
return false;
}

// Any of the typical annotations found?
for (String indicator : candidateIndicators) {
if (metadata.isAnnotated(indicator)) {
return true;
}
}

// Finally, let's look for @Bean methods...
try {
return metadata.hasAnnotatedMethods(Bean.class.getName());
}
catch (Throwable ex) {
return false;
}
}

parse 与 doScan 方法

做一些配置工作,如 若没有指定 basePackages ,则使用启动类的包路径。再看一下 Set<BeanDefinitionHolder> scannedBeanDefinitions=this.componentScanParser.parse(componentScan,sourceClass.getMetadata().getClassName());这一行中调用的parse方法,看她是如何扫描的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
// ... 这里有很多代码,不是重点,先省略

Set<String> basePackages = new LinkedHashSet<>();
String[] basePackagesArray = componentScan.getStringArray("basePackages");
for (String pkg : basePackagesArray) {
String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
Collections.addAll(basePackages, tokenized);
}
for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
}
// 如果 basePackages 为空,那么就扫描启动类所在的包,就是在这里实现的,一般默认都是为空
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
}

// 另外,启动类要参与排除
scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
return declaringClass.equals(className);
}
});
// 这个是核心方法
return scanner.doScan(StringUtils.toStringArray(basePackages));
}

// 来看看这个 doScan 核心方法
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
// 找到这个包路径下的所有候选人,是很重要的方法
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}

scanCandidateComponents 方法,找到某个包路径下的所有候选人

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
// 一些常量 :
// String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
// static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
// private String resourcePattern = DEFAULT_RESOURCE_PATTERN;
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
// 这个变量最后是 packageSearchPath = "classpath*:com/example/helloworld/**/*.class"
// 找到这个路径下的所有 class 文件
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
for (Resource resource : resources) {
// 这个class文件必须是可读的
if (resource.isReadable()) {
try {
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
// 这个方法用来判断是否是真的候选人,即是需要被spring管理的bean,是核心方法
if (isCandidateComponent(metadataReader)) {
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
// 再次判断类是否满足某些条件
if (isCandidateComponent(sbd)) {
// 可以添加到候选人列表了
candidates.add(sbd);
}
}
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to read candidate component class: " + resource, ex);
}
}
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
}
return candidates;
}

isCandidateComponent 判断某个类是否是候选人

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 继续跟进核心方法,判断是否是候选人
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
// 判断给出的类是否不匹配任何一个excludeFilter,并且匹配任意一个includeFilter
for (TypeFilter tf : this.excludeFilters) {
// 有一个排除项是我们上面设置的, 启动类会参与排除
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return false;
}
}
// 一共有两个 includeFilter,实现类都是 AnnotationTypeFilter ,第一个是判断否有 Component 注解,第二个是判断是否有 ManagedBean 注解,JSF里的东西,就不去理解了
for (TypeFilter tf : this.includeFilters) {
if (tf.match(metadataReader, getMetadataReaderFactory())) {
// 如果match通过了,就说明有 Component 注解,将被spring管理
// 但是有一种情况,假如除了有 Component 还有 Conditional 注解,且match不通过,那么还是无法被spring容器管理,下面的方法就是用来判断这个情况的
return isConditionMatch(metadataReader);
}
}
return false;
}

isConditionMatch 方法判断是否满足了 Condition 注解的条件

会找出类上面的所有 Condition ,并依次判断是否满足条件,有一个不满足,就不会将这个类添加为候选人。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
private boolean isConditionMatch(MetadataReader metadataReader) {
if (this.conditionEvaluator == null) {
this.conditionEvaluator =
new ConditionEvaluator(getRegistry(), this.environment, this.resourcePatternResolver);
}
return !this.conditionEvaluator.shouldSkip(metadataReader.getAnnotationMetadata());
}

public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationCondition.ConfigurationPhase phase) {
// 如果连 Conditional 注解都没有,那肯定不用跳过这个组件,一定要管理
if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
return false;
}

if (phase == null) {
if (metadata instanceof AnnotationMetadata &&
ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) {
return shouldSkip(metadata, ConfigurationCondition.ConfigurationPhase.PARSE_CONFIGURATION);
}
return shouldSkip(metadata, ConfigurationCondition.ConfigurationPhase.REGISTER_BEAN);
}

List<Condition> conditions = new ArrayList<>();
for (String[] conditionClasses : getConditionClasses(metadata)) {
for (String conditionClass : conditionClasses) {
Condition condition = getCondition(conditionClass, this.context.getClassLoader());
conditions.add(condition);
}
}

AnnotationAwareOrderComparator.sort(conditions);

for (Condition condition : conditions) {
ConfigurationCondition.ConfigurationPhase requiredPhase = null;
if (condition instanceof ConfigurationCondition) {
requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase();
}
if ((requiredPhase == null || requiredPhase == phase) && !condition.matches(this.context, metadata)) {
// 只要有一个 condition 没有通过match,那么就跳过这个组件
return true;
}
}
return false;
}

isCandidateComponent 方法再次判断是否是候选人

我们继续回到scanCandidateComponents方法,如果一个类已经被判定为候选人,也就是要被spring管理了,往后走,又进入了一个判断isCandidateComponent(sbd),方法名和上面判定是否为候选人一样,是个重载的方法。

1
2
3
4
5
6
7
8
9
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
AnnotationMetadata metadata = beanDefinition.getMetadata();
// isIndependent 用于判断类是否是独立的类,即顶级类或者静态内部类(可以独立调用构造方法)
// isConcrete 用于判断是否是一个具体的类,而不是一个接口或者抽象类
// isAbstract 判断是否是抽象类
// 所以这里的逻辑是:首先类必须是独立类,如果是具体的类就返回true,也可以是抽象类,但类里的某个方法必须要有 Lookup 注解,这里以后再说,不常用
return (metadata.isIndependent() && (metadata.isConcrete() ||
(metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()))));
}

根据上面的那个方法,如果@Component 注解标记在内部类上,spring是无法找到并管理的,但实际测试,是仍然可以的,这是因为doProcessConfigurationClass方法里第一步就调用了processMemberClasses(configClass, sourceClass, filter);方法,用于判断这个类里面是否有成员类可以进行管理,上面有说此方法。

为配置类设置 full 或 lite 模式

到此时所有的需要spring托管的类都已经被找到了,我们又该回到之前说的doProcessConfigurationClass方法了,上面所说的都是Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());这一行方法调用的具体内容,现在所有需要托管的类都已经在scannedBeanDefinitions中了,紧接着一次遍历,对每个 bean 进行一次 checkConfigurationClassCandidate调用,用于判断该bean是否是配置类,只要类上面有Component、ComponentScan、Import、ImportResource,或方法上有@Bean,都是配置类,只不过是 lite 模式的配置类,而如果有@Configuration且proxyBeanMethods属性为true的话,会在beanDef中添加 full 属性,其他都添加 lite 属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 涉及到的相关成员变量
public static final String CONFIGURATION_CLASS_FULL = "full";
public static final String CONFIGURATION_CLASS_LITE = "lite";

public static boolean checkConfigurationClassCandidate(
BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {

String className = beanDef.getBeanClassName();
if (className == null || beanDef.getFactoryMethodName() != null) {
return false;
}

// 此处省略很多代码,未研究

Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
// 如果有 Configuration 注解,且这个注解中的 proxyBeanMethods 属性是 true,都会设置为 full 模式。(言外之意是如果 proxyBeanMethods 设为 false, 那就和Component 一样了)
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
else if (config != null || isConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
else {
return false;
}

// It's a full or lite configuration candidate... Let's determine the order value, if any.
Integer order = getOrder(metadata);
if (order != null) {
beanDef.setAttribute(ORDER_ATTRIBUTE, order);
}

return true;
}

@Configuration有什么不一样?为什么?

以下代码两行输出都只会打印一次,且两个bean是同一个,这意味着obj()方法只被调用了一次。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Configuration
public class MyConfiguration {
@Bean
Object obj2() {
System.out.println("执行obj2");
return obj();
}

@Bean
Object obj() {
System.out.println("执行obj");
return new Object();
}
}

而如果使用的是 @Component 而不是 @Configuration,会很容易发现obj()方法被调用了两次,且两个bean不是同一个对象了。
它们俩的区别是从哪开始产生的呢?就是从上面说到的,标记lite模式或full模式开始。所有有 Configuration 注解且注解的 proxyBeanMethods 属性为true的话,就会标记为full模式,其余为 lite 模式。

我们继续回到 ConfigurationClassPostProcessor 这个类,这个类实现了 BeanDefinitionRegistryPostProcessor 接口,这个接口的 postProcessBeanDefinitionRegistry 方法已经讲解完了,还有 postProcessBeanFactory 未说明,而 @Configuration 这部分功能的实现就在这里,上代码!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + beanFactory);
}
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigurationClasses lazily at this point then.
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
// 核心代码
enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor(beanFactory));
}


// 对有 Configuration 的类进行增强
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);
// ... 此处忽略了一些和主题无关的代码 ...
if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) {
if (!(beanDef instanceof AbstractBeanDefinition)) {
throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
}
else if (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) {
logger.info("Cannot enhance @Configuration bean definition '" + beanName +
"' since its singleton instance has been created too early. The typical cause " +
"is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " +
"return type: Consider declaring such methods as 'static'.");
}
// 如果是 full 模式的配置类,就加在这个 map 里
configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
}
}
if (configBeanDefs.isEmpty()) {
// nothing to enhance -> return immediately
return;
}

ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
AbstractBeanDefinition beanDef = entry.getValue();
// If a @Configuration class gets proxied, always proxy the target class
beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
// Set enhanced subclass of the user-specified bean class
Class<?> configClass = beanDef.getBeanClass();
// 核心代码,对这个配置类进行增强
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
if (configClass != enhancedClass) {
if (logger.isTraceEnabled()) {
logger.trace(String.format("Replacing bean definition '%s' existing class '%s' with " +
"enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
}
beanDef.setBeanClass(enhancedClass);
}
}
}

继续跟踪增强的方法。所谓增强,无非就是使用 CGLib 进行动态代理,下面的很多代码也都是属于 CGLib 的了,如果对这个框架不熟悉,建议先简单了解下,跑一个最简单的 demo。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {
if (logger.isDebugEnabled()) {
logger.debug(String.format("Ignoring request to enhance %s as it has " +
"already been enhanced. This usually indicates that more than one " +
"ConfigurationClassPostProcessor has been registered (e.g. via " +
"<context:annotation-config>). This is harmless, but you may " +
"want check your configuration and remove one CCPP if possible",
configClass.getName()));
}
return configClass;
}
Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
if (logger.isTraceEnabled()) {
logger.trace(String.format("Successfully enhanced %s; enhanced class name is: %s",
configClass.getName(), enhancedClass.getName()));
}
return enhancedClass;
}

private static final Callback[] CALLBACKS = new Callback[] {
new BeanMethodInterceptor(),
new BeanFactoryAwareMethodInterceptor(),
NoOp.INSTANCE
};

private Class<?> createClass(Enhancer enhancer) {
Class<?> subclass = enhancer.createClass();
// Registering callbacks statically (as opposed to thread-local)
// is critical for usage in an OSGi environment (SPR-5932)...
Enhancer.registerStaticCallbacks(subclass, CALLBACKS);
return subclass;
}

核心逻辑在 BeanMethodInterceptor 这个拦截器里面。它的拦截方法是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
MethodProxy cglibMethodProxy) throws Throwable {

ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);

// Determine whether this bean is a scoped-proxy
if (BeanAnnotationHelper.isScopedProxy(beanMethod)) {
String scopedBeanName = ScopedProxyCreator.getTargetBeanName(beanName);
if (beanFactory.isCurrentlyInCreation(scopedBeanName)) {
beanName = scopedBeanName;
}
}

// ...省去了一些和主题无关的代码...

// 判断当前被拦截的方法是当前方法,还是被其它方法调用的,如果是被其它方法调用的会返回false
if (isCurrentlyInvokedFactoryMethod(beanMethod)) {
// The factory is calling the bean method in order to instantiate and register the bean
// (i.e. via a getBean() call) -> invoke the super implementation of the method to actually
// create the bean instance.
if (logger.isInfoEnabled() &&
BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) {
logger.info(String.format("@Bean method %s.%s is non-static and returns an object " +
"assignable to Spring's BeanFactoryPostProcessor interface. This will " +
"result in a failure to process annotations such as @Autowired, " +
"@Resource and @PostConstruct within the method's declaring " +
"@Configuration class. Add the 'static' modifier to this method to avoid " +
"these container lifecycle issues; see @Bean javadoc for complete details.",
beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName()));
}
// 如果当前方法就是被拦截的方法,那直接走代理,执行原方法就行了。
return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
}
// 如果拦截的方法不是当前方法,是方法调用,那就尝试去获取这个bean,如果没有的话就会去创建bean。
return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
}

参考 Spring中眼见为虚的 @Configuration 配置类