美文网首页
Spring源码解析之@Configuration @Bean

Spring源码解析之@Configuration @Bean

作者: 但时间也偷换概念 | 来源:发表于2019-10-02 23:08 被阅读0次

    前言:

    在SpringBoot中,我们可以用@Configuration+@Bean注解完成注入工作,替代了原来的xml管理bean方式。

    那么我们来看一下从SpringApplication.run(MyApplication.class, args)到处理@Configuration都涉及到哪些源码。

    启动类

    我们从spring-boot启动类进入源码,自动装配从这里开始

    进入run方法

    run方法走进来,经过了SpringApplication的构造函数以后,进入上图的run方法。

    这个run方法不是今天的重点,所以简单介绍一下。

    run方法主要是做环境准备,打印banner,注册Listener等工作。

    我们直接进入refreshContext方法。

    可以看到跟进来以后,走到了refresh模版方法,这也是spring源码里最关键的一个方法了,spring xml管理bean也是从refresh开始的,所以我们还可以知道,spring-boot最后也是走到refresh去完成升级的。

    然后我们直接进入invokeBeanFactoryPostProcessors(beanFactory)方法

    再进入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

    再跟进

    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

    进入ConfigurationClassPostProcessor实现

    然后我们进入processConfigBeanDefinitions(registry);

    然后我们进入parser.parse(candidates);

    然后我们看三个parse方法,和parse内调用的processConfigurationClass(new ConfigurationClass(reader, beanName));

    众所周知Spring源码的风格有一个特点,真正干事情的就是do Prefix Method。

    所以我们进入sourceClass = doProcessConfigurationClass(configClass, sourceClass);

    有没有发现新大陆,终于看到黄色的Component注解了。

    我们继续进入processMemberClasses(configClass, sourceClass);

    继续进入ConfigurationClassUtils.isConfigurationCandidate(memberClass.getMetadata())

    这里又出现了Bean注解的身影,对的,也就是在这里,Spring完成了@Configuration上下文中所有@Bean实例的metadata信息发现。

    最后我们返回上一步

    private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass)throws IOException

    this.importStack.push(configClass);

    可以看到类的元信息都保存进了importStack中

    再退到public void processConfigBeanDefinitions(BeanDefinitionRegistry registry)中

    parser.parse(candidates);

    parser.validate();

    这两步操作之后

    而parser.getImportRegistry返回的正是importStack

    ImportRegistrygetImportRegistry() {

    return this.importStack;

    }

    然后我们进入this.reader.loadBeanDefinitions(configClasses);

    刚好是从上到下调用的,最后走到了this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());

    BeanDefinitionRegistry这个类应该是非常熟悉的了,我们经常使用ImportBeanDefinitionRegistrar这个拓展接口主动注入bean,我有一篇博客专门介绍这个的,可以翻一翻。

    这里也就完成了beanDefinition的定义了。

    所以把上面的串联起来,就是Spring关于自动装配中@Configuration+@Bean组合的实现原理了。

    相关文章

      网友评论

          本文标题:Spring源码解析之@Configuration @Bean

          本文链接:https://www.haomeiwen.com/subject/rnbrpctx.html