spring configuration注解原理

版权声明:本文为博主原创文章,支持转载,但转载时请务必在明显位置,给出原文连接。 https://blog.csdn.net/john1337/article/details/86544214

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

@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方法上,下面贴出核心代码:

    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项目时进入对应源码跟踪调试。

猜你喜欢

转载自blog.csdn.net/john1337/article/details/86544214