先来一段代码:如下,内容很简单,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]代理对象
spring 中使用@Configuration注解修饰的类为什么必须被代理
原文:https://www.cnblogs.com/chenhuadong12/p/14245689.html