前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >spring configuration注解原理

spring configuration注解原理

作者头像
johnhuster的分享
发布2022-03-29 14:34:15
4760
发布2022-03-29 14:34:15
举报
文章被收录于专栏:johnhuster

spring既支持xml式配置bean,也可以通过@Configuration注解来配置bean,xml是spring最初支持的方式,随着springboot的出现,通过@Configuration注解来配置bean也越来越被采用,常见的配置如下:

代码语言:javascript
复制
@Configuration
 public class TestConfig {
 
     protected static Logger logger = LoggerFactory.getLogger(TestConfig.class);
 
     public TestConfig(){
         logger.info("TestConfig创建");
     }
 
     @Bean("student")  
     Student student(){
         logger.info("student创建");
         return new Student(address());
     }
 
     @Bean 
     Address address(){
         logger.info("address创建");
         return new Address();
     }
 }

那么@Configuration注解到底背后的工作原理是什么呢,笔者将从源码角度引入讲述@Configuration注解的工作原理,下面简单概述下Configuration注解是被初始化的流程:

AbstractApplicationContext::refresh-->AbstractApplicationContext::invokeBeanFactoryPostProcessors

-->ConfigurationClassPostProcessor::postProcessBeanFactory-->ConfigurationClassPostProcessor::enhanceConfigurationClasses

ConfigurationClassPostProcessor::enhanceConfigurationClasses这个方法是Configuration注解工作的核心方法,spring应用启动时所有的被@Configuration注解的类都会被spring cglib库生成cglib动态代理,然后其他地方通过@Autowired注解引入Student类对象就会被生成的configuration配置类生成的动态代理拦截,处理完后再调用原configuration注解类的student方法获取到Student实例。

Configuration注解类初始化的过程我们知道了,那么在Configuration注解内的@Bean注解的方法又是如何被调用的呢,不着急,下面我们将随着源码的探究揭开这层面纱。

@Bean注解方法被调用的入口就在AbstractAutowireCapableBeanFactory::createBeanInstance方法上,下面贴出核心代码:

代码语言:javascript
复制
    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
         // Make sure bean class is actually resolved at this point.
         Class<?> beanClass = resolveBeanClass(mbd, beanName);
        if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                     "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
         }
        Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
         if (instanceSupplier != null) {
             return obtainFromSupplier(instanceSupplier, beanName);
         }
        if (mbd.getFactoryMethodName() != null)  {
             return instantiateUsingFactoryMethod(beanName, mbd, args);
         }

由于@Bean注解方法生成的Bean实例getFactoryMethodName不为null,所以就会通过调用对应的bean方法来创建该Bean实例!

想要了解更多的可以在调试spring项目时进入对应源码跟踪调试。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/01/19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档