@Configuration(proxyBeanMethods = false) 设置这个为false有啥用
最近看Nacos的源码,发现很多Configuration配置类上 @Configuration(proxyBeanMethods = false) 都把proxyBeanMethods设置成了false了。特地研究下。
源码中默认是true,对这个属性的解释也可以大概知道。
1: 如果为true, 则表示被@Bean标识的方法都会被CGLIB进行代理,而且会走bean的生命周期中的一些行为(比如:@PostConstruct,@Destroy等 spring中提供的生命周期), 如果bean是单例的,那么在同一个configuration中调用
@Bean标识的方法,无论调用几次得到的都是同一个bean,就是说这个bean只初始化一次。
2: 如果为false,则标识被@Bean标识的方法,不会被拦截进行CGLIB代理,也就不会走bean的生命周期中的一些行为(比如:@PostConstruct,@Destroy等 spring中提供的生命周期),如果同一个configuration中调用@Bean标识的方法,就只是普通方法的执行而已,并不会从容器中获取对象。所以如果单独调用@Bean标识的方法就是普通的方法调用,而且不走bean的生命周期。
所以,如果配置类中的@Bean标识的方法之间不存在依赖调用的话,可以设置为false,可以避免拦截方法进行代理操作,也是提升性能的一种优化。但是需要注意,@Bean标识的返回值对象还是会放入到容器中的,从容器中获取bean还是可以是单例的,会走生命周期。
看下面的例子:
public class MyBean { @PostConstruct public void init(){ System.out.println("MyBean初始化了"); } public void hello(){ System.out.println("Mybean hello"); } }
public class YourBean { public MyBean myBean; public YourBean(MyBean myBean){ this.myBean=myBean; } @PostConstruct public void init(){ System.out.println("YourBean 初始化了"); } public void hello(){ System.out.println("YourBean hello"); } }
@Configuration(proxyBeanMethods=true)
@Configuration(proxyBeanMethods = true) public class ConfigureTest { @Bean public OrderEntity getOrderEntity(){ return new OrderEntity(); } @Bean public MyBean myBean(){ return new MyBean(); } @Bean public YourBean yourBean(){ return new YourBean(myBean()); } }
测试方法:
@Component public class InitClass implements InitializingBean , ApplicationContextAware { ApplicationContext applicationContext; @Override public void afterPropertiesSet() throws Exception { YourBean bean = this.applicationContext.getBean(YourBean.class); // 第一行 YourBean bean1 = this.applicationContext.getBean(YourBean.class); // 第二行 MyBean myBean = this.applicationContext.getBean(MyBean.class); // 第三行 myBean.hello(); bean.hello(); bean1.hello(); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext=applicationContext; } }
第一行执行完:MyBean和YourBean都进行初始化了,说明在new YourBean(myBean())中myBean()走了bean的生命周期,说明被CGLIB进行代理了。
第二,三行执行完,没什么内容输出,说明YourBean,MyBean都初始化一次。
@Configuration(proxyBeanMethods=false)
@Configuration(proxyBeanMethods = false) public class ConfigureTest { @Bean public OrderEntity getOrderEntity(){ return new OrderEntity(); } @Bean public MyBean myBean(){ return new MyBean(); } @Bean public YourBean yourBean(){ return new YourBean(myBean()); } }
执行完第一行,只有YourBean初始化有输出:看到里面的MyBean属性是@5351
执行完第二行,没有内容输出,bean1中的MyBean属性也是@5351
第三行执行完,MyBean的初始化才输出,而且从容器中得到的这个bean是@5360
看到这里应该能体会到,proxyBeanMethods的含义了吧。为false的时候,@Bean标识的方法调用就是普通的方法调用,不会被代理。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!