spring注解之@Configuration源码解析

1、spring内部提供的beanFactoryPostProcessor的实现类ConfigurationClassPostProcessor继承了BeanFactoryPostProcessor,BeanFactoryPostProcessor又继承了BeanFactoryPostProcessor,并且重写了postProcessBeanDefinitionRegistry方法

2、spring容器在启动的时候,在 invokeBeanFactoryPostProcessors的方法里面会调用ConfigurationClassPostProcessor类的postProcessBeanDefinitionRegistry方法,该方法里面调用了processConfigBeanDefinitions 生成config的beanDefinition对象

 3、在org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(BeanDefinitionRegistry)方法中会调用ConfigurationClassUtils.checkConfigurationClassCandidate的方法 ,该方法中会判断类是否添加了@Configuration注解

 

4、在org.springframework.context.annotation.ConfigurationClassUtils.checkConfigurationClassCandidate(BeanDefinition, MetadataReaderFactory)中 判断了配置类是否添加了@Configuration注解

如果添加了该注解 ,因为@Configuration注解里面默认proxyBeanMethods为true则 给该类的beanDefinition对象的configurationClass属性赋值为full,此处有两个选项 full和lite 

5、ConfigurationClassPostProcessor方法因为实现了BeanFactoryPostProcessor方法,最终会执行postProcessBeanFactory方法的实现,其中enhanceConfigurationClasses会生成@Configuration的类 的代理类  因为该类可能没有接口类 所以此处直接用了cglib来代理实现

6、org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurableListableBeanFactory)方法里面 通过ConfigurationClassEnhancer生成代理类 

 7、org.springframework.context.annotation.ConfigurationClassEnhancer.enhance(Class<?>, ClassLoader)方法里面 调用了createClass方法生成代理类

此处newEnhancer方法中有设置父类 以及接口类

而接口类public interface EnhancedConfiguration extends BeanFactoryAware 继承了BeanFactoryAware方法 也就是代理类中实际上是能拿到beanFactory对象的 下面会用到beanFactory对象

 

8、进入createClass方法 我们能看到 Enhancer.registerStaticCallbacks(subclass, CALLBACKS); 这段代码 设置了几个增强器

9、以BeanMethodInterceptor为例,进入该类 查看intercept方法 有这么一段逻辑: 

这段话就是当你的类加上@Configuration之后,代理就会保持主键的单例性

 

10、举例说明

 有两个类MyService和MyService2两个普通类 各自构造函数打印一句话

 

我在我的配置类中 定义了两个bean  其中一个bean中调用另一个bean的构造方法

 

如果是单例bean的话 控制台就只会输出一次“MyService构造函数”的字样  因为 new Service只会触发一次。

验证结果如下:

 

spring的ConfigurationClassEnhancer类的静态内部类BeanMethodInterceptor就是这么实现的

众所周知 cglib生成的代理类是继承当前类的 所以

第一次实例化的话 会调用 cglibMethodProxy.invokeSuper方法直接调用父类的方法

第二次的话调用org.springframework.context.annotation.ConfigurationClassEnhancer.BeanMethodInterceptor.resolveBeanReference(Method, Object[], ConfigurableBeanFactory, String) 

看到底层代码 也就是cglib代理类中会通过beanFactory对象 拿到初始化好了的bean对象的  所以不会再初始化第二次。

 

 

总结:

1.加上了@Configuration的类 spring会对它通过cglib生成代理类

2.@Configuration 注解里面默认proxyBeanMethods方法默认为true,所以代理的bean 会保证bean的单例性

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值