spring4.0之二:@Configuration的使用 https://www.cnblogs.com/duanxz/p/7493276.html
上面链接说了比较完整。
有一点补充
Spring 5.2+ 建议,如果没有方法间引用的配置类中,使用非代理模式@Configuration(proxyBeanMethods = false)
运行时会给该类生成一个代理CGLIB子类放进容器,有一定的性能、时间开销(这个开销在Spring Boot这种拥有大量配置类的情况下是不容忽视的,
这也是为何Spring 5.2新增了proxyBeanMethods属性的最直接原因)
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Configuration { @AliasFor(annotation = Component.class) String value() default ""; boolean proxyBeanMethods() default true; }
@Configuration(proxyBeanMethods = false)
proxyBeanMethods : 这个参数表示是否动态代理bean方法。 true:使用cglib进行bean的代理:即处于Full模式 支持Bean方法间的引用 false:不使用cglib代理,即处于 Lite 模式 不支持Bean方法间的引用
非@Configuration标记的类内定义的@Bean方法都是 Lite 模式的
还有@Configuration(proxyBeanMethods = false)标记的类内定义的@Bean方法也是 Lite 模式
Full模式:
1、@Bean方法生成对象会被CGLIB增强(生成代理对象),放进ioc容器的是代理对象
2、支持@Bean 方法间互相调用,能够保证获取到了实例都是指向ioc容器的单例
Lite模式:
1、bean类不会被cglib增强,注册到ioc容器中的就是它本身
2、类内部申明的@Bean 不支持@Bean 方法间互相调用,
否则每次生成的都是一个新实例(重新执行这个方法),而不是ioc容器中的单例
3、该模式下@Bean方法可以使用private和final 修饰
@Configuration public class DataSourceConfig { ... @Bean public DataSource dataSource() { ... return dataSource; } @Bean(name = "transactionManager") public DataSourceTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } ... }
上面的代码,默认使用代理模式,dataSource() 声明bean时,被调用, transactionManager()方法中被调用
这两次调用第一次会调用dataSource方法获取到DataSource对象,然后注册到BeanFactory中,第二次调用
总结:
运行时会给该类生成一个CGLIB子类放进容器,有一定的性能、时间开销(这个开销在Spring Boot这种拥有大量配置类的情况下是不容忽视的,
这也是为何Spring 5.2新增了proxyBeanMethods属性的最直接原因)
如果存在Bean方法的互相引用,则这个参数要为true。
资料参考
@Configuration(proxyBeanMethods = false) 详解 https://blog.csdn.net/z69183787/article/details/109533579
原文:https://www.cnblogs.com/gne-hwz/p/14486431.html