关于Spring中的@Configuration中的proxyBeanMethods属性
@Configuration的proxyBeanMethods属性
在@Configuration
注解中,有两个属性:
value
配置Bean名称proxyBeanMethos
,默认是true
这个proxyBeanMethods
的默认属性是true。
直接说:当@Configuration
注解的proxyBeanMeathods
属性是true时,那么此类的Bean就会被Spring代理,被代理就意味着此类中的方法得到的增强处理。那么此类中通过@Bean
来对外提供Bean的方法就会被增强
我们可以看一下:
这是一个被@Configuration
修饰的类
@Configuration public class DBConfig { }
我们获取一下这个Bean,打印一下类型
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class); System.out.println(ctx.getBean("DBConfig")); // com.liumingkai.config.DBConfig$$EnhancerBySpringCGLIB$$ef2610c5@5bfa9431
可以看到,打印出来的类型不是DBConfig
,而是被代理后的类型DBConfig$$EnhancerBySpringCGLIB
,(可以看到这是CGLib代理出来的类,因为JDK动态代理只能处理有接口的类,而CGlib是通过继承的方式来做代理的)
当设置proxyBeanMethos
的属性是false时,得到的就是此类型,不再是代理类
System.out.println(ctx.getBean("DBConfig")); // com.liumingkai.config.DBConfig@710726a3
我们知道,被@Bean
修饰的方法的返回对象,会被注册进入Spring的容器中,受Spring的管理
那将@Configuration
的proxyBeanMethods
的属性设置为true
会有什么好处呢?
因为@Configuration
注解通常用来修饰配置类,会在此类中配置大量的配置项或者用来对外提供Bean
该配置类中通过@Bean
来对外提供Bean的方法会被增强,每次都会返回Spring容器管理的Bean
演示一下
例如:在@Configuration
修饰的类,在此类中有一个被@Bean
修饰的方法,用来对外提供Bean。
我们获取到此类型的Bean后,可以像普通方法一样来调用这个被@Bean
修饰的方法,会得到返回的对象。
区别在于:
- 当
proxyBeanMethods
属性为true时,此类被代理,方法得到增强,那么我们每次通过此类型的Bean来调用@Bean
修饰的方法,每次返回的都是Spring容器中的单例Bean - 当
proxyBeanMethods
属性是false时,此类型的Bean就是一个普通的Bean,未被代理,那么每次调用@Bean
修饰的方法,这都是一个普通的方法,返回的都是新的普通的对象,不是被Spring容器管理的对象
测试
例如;
- 先来看,当
proxyBeanMethods
为false时
@Configuration(proxyBeanMethods = false) public class DBConfig { @Bean public DruidDataSource getDruidDataSource() { return new DruidDataSource(); } }
测试
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class); // 获取此类型的Bean,查看类型 DBConfig dbConfig = ctx.getBean("DBConfig", DBConfig.class); // 查看类型 System.out.println(dbConfig); // com.liumingkai.config.DBConfig@f2ff811 // 就是普通的类型,未被代理 // 调用此Bean上被@Bean修饰的方法 System.out.println(dbConfig.getDruidDataSource() == dbConfig.getDruidDataSource()); // false 证明此方法就是普通的方法,每次都会创建一个对象
- 再来看
proxyBeanMethods
为true的情况
@Configuration public class DBConfig { @Bean public DruidDataSource getDruidDataSource() { return new DruidDataSource(); } }
测试
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class); // 获取此类型的Bean,查看类型 DBConfig dbConfig = ctx.getBean("DBConfig", DBConfig.class); // 查看类型 System.out.println(dbConfig); // com.liumingkai.config.DBConfig$$EnhancerBySpringCGLIB$$ef2610c5@5bfa9431 // 可以看到这是一个被代理后的类,不再是原先的类型了 // 调用此Bean上被@Bean修饰的方法 // 此方法是被增强后的,每次都会返回Spring容器中的单例Bean System.out.println(dbConfig.getDruidDataSource() == dbConfig.getDruidDataSource()); // true 证明此方法返回的是Spring容器中的单例Bean
总结
被@Configuration
修饰的类,本质上也是一个Bean
- 当
@Configuration
中的proxyBeanMethods
属性默认是true
,意味着这个类会被代理,这个类中通过@Bean
修饰的方法会被增强,调用这个方法时,会直接返回受Spring容器管理的Bean(Spring容器中的Bean默认都是单例的) - 而如果
@Configuration
中的proxyBeanMethods
属性是false
,那么此配置类就是一个普通的类,未被代理。因此调用被@Bean
修饰的方法,就是一个普通的方法,每次调用都会返回一个新的对象
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现