spring 中使用@Configuration注解修饰的类为什么必须被代理


spring 中使用@Configuration注解修饰的类为什么必须被代理

一、问题描述和场景

先来一段代码:如下,内容很简单,AopTest被configuration修饰,里面有两个方法,p()实例返回对象person,a()方法引用p(),同时返回对象A。并且都被@bean注解修饰。

 

 用这个场景来验证spring加@configuration注解的类都必须被代理:

 首先有一个问题;如果方法P在调用方法A,在不生成代理对象的时候,此时会创建两次Person对象?那么创建两次对象,即在spring里非单例对象,这样的话无法保证spring中配置类的属性单例原则。

 那么有没有一种可能,通过代理方法来管理person对象的创建,如果调用方法p()会交由代理去判断person对象是否已经被创建成功,如果是那么则交由代理对象的proxy.invokeSuper的方法调用父类

 去创建;如果没有则通过代理类$$BeanFactory.getBean的方法创建对象person,从而保证对象只被创建一次,即为单例。

二、源码分析

1、主函数,register上面的AopTest

 

 2、到refresh()方法,当执行到invokeBeanDefinitionRegistryPostProcessors 方法解析此类,则从map里面遍历 BeanDefinition ,判断当前BeanDefinition 的map里面的属性key -configurationClass 值是full还是lite,刚开始扫描时候为null,则继续解析,判断若果加了@Configuration configurationClass 的值设置为full。如下图所示:

 

3、调用 invokeBeanFactoryPostPorcessors ,此方法遍历所有的BeanFactoryPostPorcessors,如下图,此时的对象还是普通对象,并非生成的代理对象。 

 

4、 在遍历中会调用到enhanceConfigurationClass ,此方法中获取regist里面的所有类,遍历判断 isfullConfigurationClass 是否为full,若为full,存到一个LinkedHashMap 中,为lite则不存,若map为null ,则返回之后直接new 对象。调用enhanceConfigurationClasses() ,判断该类是否实现EnhancedConfiguration接口spring完成代理则会让该类去实现此接口;若没有被代理则去实现代理 enhancer.create()创建代码对象,可以看出该对象已经是"aopTest" -> "Generic bean: class [com.mashibing.AopTest$$EnhancerBySpringCGLIB$$fa629855]代理对象

 

 

结论: 凡是加了@Configuration注解修饰的类都会被spring代理,目的是为了解决@Bean单例问题

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM