我们知道@Configuration 和 @Component都可以向String容器中注入bean对象,但是他们之前还是有不同点的。Spring中@Configuration源码深度解析(二)的传送门:Spring中@Configuration源码深度解析(二)
下面直接看@Configuration的源码,关于@Configuration的使用,后面有机会写篇文章:
package com.luban.configuration;
@Configuration
@ComponentScan("com.luban.configuration")
public class Config {
@Bean
public School school() {
return new School();
}
}
public class Test01 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(Config.class); //以这句代码为入口进行分析
}
}
代码块1. AnnotationConfigApplicationContext#AnnotationConfigApplicationContext方法
/**
* 这个构造方法需要传入一个被javaconfig注解了的配置类
* 然后会把这个被注解了javaconfig的类通过注解读取器读取后继而解析
*/
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//1.annotatedClasses appconfig.class
//在自己构造方法中初始一个读取器和扫描器
//这句代码内部会创建一个AnnotatedBeanDefinitionReader对象,在创建这个对象时
//会向容器中注入多个后置处理器,其中有一个是用来完成
//指定包扫描,并把普通的标了注解的Java类,解析成beanDefinition对象
//并放到一个Map中,这个后置处理为ConfigurationClassPostProcessor
this();
//2.将配置类注册到容器中
register(annotatedClasses);
//3.完成容器刷新,就是在这一步容器完成bean的创建
refresh();
}
其中第3步,会调用refresh会完成容器刷新,看代码块2,就是在这一步容器完成bean的创建,前面两步注释已经写的很清楚了,想要深入了解的话,可以点进去看一下,这篇文档只是让你了解加了@Configuration后,Spring会怎么进行解析,就不在介绍了。
代码块2. AbstractApplicationContext#refresh方法
//这个方法可以说是Spring中最重要的一个方法,也用到了模板方法模式
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
1.准备工作包括设置启动时间,是否激活标识位,
// 初始化属性源(property source)配置
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//2.返回一个factory 为什么需要返回一个工厂
//因为要对工厂进行初始化
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//3.准备工厂
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
//4. 这个方法在当前版本的spring是没用任何代码的
//可能spring期待在后面的版本中去扩展吧
postProcessBeanFactory(beanFactory);
// 5. Invoke factory processors registered as beans in the context.
//在spring的环境中去执行已经被注册的 factory processors
//设置执行自定义的ProcessBeanFactory 和spring内部自己定义的
//在该步会进行注解的解析,并完成普通对象到beanDefinition的转变
//其中@Configuration也是在这步完成的
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//6. 注册beanPostProcessor
registerBeanPostProcessors(beanFactory);
//7. Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
//8. 初始化应用事件广播器
initApplicationEventMulticaster();
//9. Initialize other special beans in specific context subclasses.
onRefresh();
//10. Check for listener beans and register them.
registerListeners();
//11. Instantiate all remaining (non-lazy-init) singletons.
//该步会根据beanDefinition完成剩下的非懒加载的bean
finishBeanFactoryInitialization(beanFactory);
//12. Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
在第5步中会完成普通对象到beanDefinition的转换,然后在第11步会根据beanDefinition完成剩下的非懒加载的bean,我们这里我们只关注第5步就行,第5步是执行BeanFactory的后置处理器,这是Spring提供的扩展点之一,在这个扩展点中允许我们在bean实例话之前做一些操作,看代码块3
代码块3. AbstractApplicationContext#invokeBeanFactoryPostProcessors方法
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//这个地方需要注意getBeanFactoryPostProcessors()是获取手动给spring的BeanFactoryPostProcessor
//自定义并不仅仅是程序员自己写的
//自己写的可以加companent也可以不加
//如果加了getBeanFactoryPostProcessors()这个地方得不得,是spring自己扫描的
//为什么得不到getBeanFactoryPostProcessors()这个方法是直接获取一个list,
//这个list是在AnnotationConfigApplicationContext被定义
//所谓的自定义的就是你手动调用AnnotationConfigApplicationContext.addBeanFactoryPostProcesor();
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
会调用PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors来完成BeanFactoryPostProcessors后置处理的调用工作,看代码块4
代码块4. PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法
这里先说一下,之前我们提到ConfigurationClassPostProcessor类,先来看一下它的继承关系:
invokeBeanFactoryPostProcessors的代码比较长,我先说一下做了什么事,这样便于大家在看源码,这个方法会调用所有实现了BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的方法(BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor是继承关系),首先他会拿到容器内部所有的BeanFactoryPostProcessor,也就是自定义,判断是否有BeanDefinitionRegistryPostProcessor类型的,如果是,执行BeanDefinitionRegistryPostProcessor接口的方法,然后根据名称先查找所有的BeanDefinitionRegistryPostProcessor接口,根据实现了PriorityOrdered、Ordered和普通的依次调用其BeanDefinitionRegistryPostProcessor接口的方法,然后在执行是BeanDefinitionRegistryPostProcessor类型的BeanFactoryPostProcessor接口的postProcessBeanFactory方法,因为一个类如果是BeanDefinitionRegistryPostProcessor类型的,那么它必然属于BeanFactoryPostProcessor类型的。
然后根据类型再查找所有的BeanFactoryPostProcessor类型,根据根据实现了PriorityOrdered、Ordered和普通的依次调用其postProcessBeanFactory方法。
其中PriorityOrdered、Ordered是Spring用来排序用的,可以规定谁先执行,谁后执行。
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
//自定义的beanFactoryPostProcessors
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {//BeanDefinitionRegistryPostProcessor BeanfactoryPostProcessor
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.
//这个currentRegistryProcessors 放的是spring内部自己实现了BeanDefinitionRegistryPostProcessor接口的对象
//我的理解:currentRegistryProcessors存在的正在遍历的实现了BeanDefinitionRegistryPostProcessor接口的对象,然后将
//之保存起来,进行调用,调用之后,清空
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
//BeanDefinitionRegistryPostProcessor 等于 BeanFactoryPostProcessor
//getBeanNamesForType 根据bean的类型获取bean的名字ConfigurationClassPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//这个地方可以得到一个BeanFactoryPostProcessor,因为是spring默认在最开始自己注册的
//为什么要在最开始注册这个呢?
//因为spring的工厂需要许解析去扫描等等功能
//而这些功能都是需要在spring工厂初始化完成之前执行
//要么在工厂最开始的时候、要么在工厂初始化之中,反正不能再之后
//因为如果在之后就没有意义,因为那个时候已经需要使用工厂了
//所以这里spring'在一开始就注册了一个BeanFactoryPostProcessor,用来插手springfactory的实例化过程
//在这个地方断点可以知道这个类叫做ConfigurationClassPostProcessor
//ConfigurationClassPostProcessor那么这个类能干嘛呢?可以参考源码
//下面我们对这个牛逼哄哄的类(他能插手spring工厂的实例化过程还不牛逼吗?)重点解释
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//排序不重要,况且currentRegistryProcessors这里也只有一个数据
sortPostProcessors(currentRegistryProcessors, beanFactory);
//合并list,不重要(为什么要合并,因为还有自己的)
//我的理解:合并之后集中进行调用BeanFactoryPostProcessor接口的postProcessBeanFactory
registryProcessors.addAll(currentRegistryProcessors);
//1. 最重要。注意这里是方法调用
//执行所有BeanDefinitionRegistryPostProcessor
//因为ConfigurationClassPostProcessor实现了PriorityOrdered接口,所以会在这个调用ConfigurationClassPostProcessor
//类的postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//执行完成了所有BeanDefinitionRegistryPostProcessor
//这个list只是一个临时变量,故而要清除
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
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.
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));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
//2. Now, invoke the postProcessBeanFactory callback of all processors handled so far.
//执行BeanFactoryPostProcessor的回调,前面不是吗?
//前面执行的BeanFactoryPostProcessor的子类BeanDefinitionRegistryPostProcessor的回调
//这是执行的是BeanFactoryPostProcessor postProcessBeanFactory
//ConfuguratuonClassPpostProcssor
//这里执行的是BeanFactoryPostProcessor接口的方法,因为在找到并执行BeanDefinitionRegistryPostProcessor接口的方法后,
//又因为BeanDefinitionRegistryPostProcessor继承与BeanFactoryPostProcessor,所以此时BeanFactoryPostProcessor的接
//口还没执行的
//这一步会调用实现了BeanDefinitionRegistryPostProcessor接口的,父类方法,
//标注了@Configuration注解的类,会在这个得到增强
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//自定义BeanFactoryPostProcessor
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!
//ConfigurationClassPostProcessor
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) {
//processedBeans里面保存是在执行BeanDefinitionRegistryPostProcessor的时候已经执行过了BeanFactoryPostProcessor接口的方法
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<>();
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<>();
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();
}
最重要的和@Configuration相关的就是上述代码块中标注了第1步和第2步的地方。
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);会将普通注解类转换成beanDefinition对象,看代码块5
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);会根据一个类是否标有@Configuration来进行增强,由于篇幅有限,关于这个方法放到了Spring中@Configuration源码深度解析(二)里面进行讲解。
代码块5. PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors方法
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
//循环调用所有的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
//走到这里就会调用ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法了
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
代码块6.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry方法
首先说明一下在这个processConfigBeanDefinitions方法中会做很多事情,会解析类上面标注了@ComponentScan、@Import、@bean、@Component等注解信息,对于@ComponentScan会解析出需要扫描的包,然后利用ASM技术得到这个类,然后再次解析类上面的注解,对于@Import来说,由于支持带入普通类、ImportSelector的实现类和ImportBeanDefinitionRegistrar的实现了,所以在解析@Import的时候,会进行判断三种情况,然后执行ImportBeanDefinitionRegistrar和ImportSelector接口中的方法,对于导入的类,也会进行判断类中标注的注解(使用递归),
这里简单这样说一下,不做过多介绍,只介绍Spring对于@Configuration是怎么处理的。
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
//得到一个hash值,判断是否已经解析过这个对象了
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
this.registriesPostProcessed.add(registryId);
//真正完成从普通注解类到beanDefinition的转换
processConfigBeanDefinitions(registry);
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
//1. 定义一个list存放app 提供的bd(项目当中提供了@Compent)
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//2. 获取容器中注册的所有bd名字
String[] candidateNames = registry.getBeanDefinitionNames();
/**
* Full
* Lite
*/
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
//3. 如果BeanDefinition中的configurationClass属性为full或者lite,则意味着已经处理过了,直接跳过
}
//4. 判断是否是Configuration类,如果加了Configuration下面的这几个注解就不再判断了
// 还有 add(Component.class.getName());
// candidateIndicators.add(ComponentScan.class.getName());
// candidateIndicators.add(Import.class.getName());
// candidateIndicators.add(ImportResource.class.getName());
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
//BeanDefinitionHolder 也可以看成一个数据结构
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}
// 5. 排序,根据order,不重要
// 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;
// 6. 如果BeanDefinitionRegistry是SingletonBeanRegistry子类的话,
// 由于我们当前传入的是DefaultListableBeanFactory,是SingletonBeanRegistry 的子类
// 因此会将registry强转为SingletonBeanRegistry
//主要是生成bean的名字生成器
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {//是否有自定义的
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
//SingletonBeanRegistry中有id为 org.springframework.context.annotation.internalConfigurationBeanNameGenerator
//如果有则利用他的,否则则是spring默认的
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// Parse each @Configuration class
//7. 实例化ConfigurationClassParser 为了解析各个配置类
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
//实例化2个set,candidates用于将之前加入的configCandidates进行去重,Spring内部没有重复的,就怕你给他一个重复的
//因为可能有多个配置类重复了
//alreadyParsed用于判断是否处理过
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
//8.解析类中标注的注解
parser.parse(candidates);
parser.validate();
//map.keyset
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());
}
/**
* 这里值得注意的是扫描出来的bean当中可能包含了特殊类
* 比如ImportBeanDefinitionRegistrar那么也在这个方法里面处理
* 但是并不是包含在configClasses当中
* configClasses当中主要包含的是importSelector
* 因为ImportBeanDefinitionRegistrar在扫描出来的时候已经被添加到一个list当中去了
*/
//bd 到 map 除却普通
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
//由于我们这里进行了扫描,把扫描出来的BeanDefinition注册给了factory
//但是
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();
}
}
查看第4步代码:ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory),再次会判断是否加了@Component、@Import、@Configuration、@ComponentScan等注解,如果加了Spring才会加到list中进行解析,如果不加就不进行解析,看代码块7。在第8步中,会解析类中的注解。
代码块7.ConfigurationClassUtils#checkConfigurationClassCandidate方法
public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
String className = beanDef.getBeanClassName();
if (className == null || beanDef.getFactoryMethodName() != null) {
return false;
}
AnnotationMetadata metadata;
if (beanDef instanceof AnnotatedBeanDefinition &&
className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
// Can reuse the pre-parsed metadata from the given BeanDefinition...
//1. 如果BeanDefinition 是 AnnotatedBeanDefinition的实例,并且className 和 BeanDefinition中 的元数据 的类名相同
// 则直接从BeanDefinition 获得Metadata
metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
}
else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
// Check already loaded Class if present...
// since we possibly can't even load the class file for this Class.
//2. 如果BeanDefinition 是 AbstractBeanDefinition的实例,并且beanDef 有 beanClass 属性存在
//则实例化StandardAnnotationMetadata
Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
metadata = new StandardAnnotationMetadata(beanClass, true);
}
else {
try {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
metadata = metadataReader.getAnnotationMetadata();
}
catch (IOException ex) {
return false;
}
}
//3. 判断当前这个bd中存在的类是不是加了@Configruation注解
//如果存在则spring认为他是一个全注解的类
if (isFullConfigurationCandidate(metadata)) {
//如果存在Configuration 注解,则为BeanDefinition 设置configurationClass属性为full
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
//4. 判断是否加了以下注解,摘录isLiteConfigurationCandidate的源码
// candidateIndicators.add(Component.class.getName());
// candidateIndicators.add(ComponentScan.class.getName());
// candidateIndicators.add(Import.class.getName());
// candidateIndicators.add(ImportResource.class.getName());
//如果不存在Configuration注解,spring则认为是一个部分注解类
else if (isLiteConfigurationCandidate(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注解,则给beanDefinition的CONFIGURATION_CLASS_ATTRIBUTE属性设为full,如果加了@Component、@ComponentScan、@Import、@ImportResource,则给beanDefinition的CONFIGURATION_CLASS_ATTRIBUTE属性设为lite。
会在第3步和第4步进行full和lite的判断,看代码块8
代码块8. ConfigurationClassUtils#isFullConfigurationCandidate方法和ConfigurationClassUtils#isLiteConfigurationCandidate方法
public static boolean isFullConfigurationCandidate(AnnotationMetadata metadata) {
return metadata.isAnnotated(Configuration.class.getName());
}
public static boolean isLiteConfigurationCandidate(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) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to introspect @Bean methods on class [" + metadata.getClassName() + "]: " + ex);
}
return false;
}
}
所以在此可以判断出加了@Configuration注解后,其CONFIGURATION_CLASS_ATTRIBUTE属性设为full,其他的加了@Component、@ComponentScan、@Import、@ImportResource,则给beanDefinition的CONFIGURATION_CLASS_ATTRIBUTE属性设为lite。
这样设置了有什么用?就只是这个不一样就会造成很大不同吗?这个后面再说,现在我们说完了代码块4中的 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry),该方法是将普通注解类转换成beanDefinition对象,并对标有@Configuration注解的类使用full进行标记。关于invokeBeanFactoryPostProcessors(registryProcessors, beanFactory)在下篇文章中进行源码分析,其就是根据CONFIGURATION_CLASS_ATTRIBUTE的值是否为full,进行增强,请大家前往Spring中@Configuration源码深度解析(二)继续学习@Configuration源码深度解析。