首页 > 编程语言 > 详细

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

时间:2021-01-07 13:03:45      阅读:40      评论:0      收藏:0      [点我收藏+]

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代理

 

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

原文:https://www.cnblogs.com/chenhuadong12/p/14245689.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!