Spring自动配置实现原理详解
详情参阅系列:https://blog.csdn.net/f641385712/category_10035396.html
Note:
Spring中的配置分为Full模式和Lite模式(详情可参阅:https://fangshixiang.blog.csdn.net/article/details/106127418)。
Full模式:类上@Configuration + 方法上@Bean 的配置类,会被以Full模式解析加载。
Lite模式:类上没有@Configuration,只有方法上@Bean; 或者 方法上@Bean + 类上@Component/@ComponentScan/@Import/@ImportResource/@Configuration(proxyBeanMethods = false) 的配置类,会被以Lite模式加载解析。
注:proxyBeanMethods 是Spring 5.2.0新增的属性
两种模式的区别:
Full模式在运行时会为配置类生成CGLIB代理对象(具体过程可参阅:https://fangshixiang.blog.csdn.net/article/details/106205956),故@Bean方法不能是final或私有的(当然,非@Bean方法可以是final或私有的);Lite模式则不会生成代理而是直接调用目标对象。
Full模式下可以在一个@Bean方法内通过方法调用依赖其他@Bean。Lite模式则不可,调用其他Bean方法时得到的是一个新对象而非容器中的对象。(内部原理:https://fangshixiang.blog.csdn.net/article/details/106175299)
示例:
@Configuration public class AppConfig { @Bean public Son son() { Son son = new Son(); System.out.println("son created..." + son.hashCode()); return son; } @Bean public Parent parent() { Son son = son();//此AppConfig是Full模式故可通过方法调用依赖其他Bean,若是Lite模式则不可 System.out.println("parent created...持有的Son是:" + son.hashCode()); return new Parent(son); } //上述方法用如下法也可,对Full、Lite模式皆适用 //@Bean //public Parent parent(Son son){ // System.out.println("parent created...持有的Son是:" + son.hashCode()); // return new Parent(son); //} } ———————————————— //输出: son created...1797712197 parent created...持有的Son是:1797712197 com.marchon.fullliteconfig.config.AppConfig$$EnhancerBySpringCGLIB$$8ef51461@be64738 容器内的Son实例:1797712197 容器内Person持有的Son实例:1797712197 true