@Configuration和@Bean是如何工作的?

460 阅读1分钟

企业微信20210325-153601.png

企业微信20210325-153741.png 下面主要看看红框中的这两个接口:

BeanDefinitionRegistryPostProcessor:
    postProcessBeanDefinitionRegistry
BeanFactoryPostProcessor:
    postProcessBeanFactory

1、以上两个方法都会调用到processConfigBeanDefinitions这个核心方法,下面来分析下:

1、从frozenBeanDefinitionNames或者beanDefinitionNames中获得已经注册的beanDefinitionNames;
2、遍历上面的bean,将标注有@Configuration@Component@ComponentScan@Import@ImportResource、和标注@Bean方法的BeanDefinitionHolder添加到
configCandidates这个临时变量,供后面使用;

企业微信20210325-164305.png

企业微信20210325-164322.png

企业微信20210325-164335.png

企业微信20210325-164349.png

3、如果没有符合的bean就返回;
4、根据@Order进行排序;
5、给componentScanBeanNameGenerator和importBeanNameGenerator赋值,beanName的生成策略;
6、设置environment;
7、重要的来了,循环解析配置类,通过ConfigurationClassParser的parse方法
    1、根据@Condition注解,判断是否需要解析,不需要直接返回;
    2、先从configurationClasses缓存中获取,如果已经存在,返回;
    3、将configClass转为SourceCLass;
    4、通过doProcessConfigurationClass执行实际的解析配置类;
        1、解析标注@Component的配置类,放入到importStack;
        2、解析标注@PropertySource,添加到propertySourceNames;
        3、解析标注@Component的,添加到beanDefinitionMap;(这块后面详细解读)
        4、解析标注@Import的,放入到importStack;
        5、解析标注@ImportResource的,放入到importedResources;
        6、解析标注@Bean的方法,放入到beanMethods;
        7、解析接口的默认方法,放入到**beanMethods**;
        8、循环解析他的父类;
    5、将解析后的配置类放到configurationClasses缓存中;
8、移除重复的,由ConfigurationClassBeanDefinitionReader的loadBeanDefinitions注册bean Definition;
    1、跳过不符合条件的bean;
    2、符合条件的都注册到beanDefinitionMap;
    

企业微信20210325-173501.png

9、注册ConfigurationClassPostProcessor.class.getName() + ".importRegistry"到singletonObjects中;
10、清除本地缓存

2、postProcessBeanFactory中的额外操作:

1、对配置进行了增强;
2、添加ImportAwareBeanPostProcessor到BeanFactory;