关于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的管理

那将@ConfigurationproxyBeanMethods的属性设置为true会有什么好处呢?
因为@Configuration注解通常用来修饰配置类,会在此类中配置大量的配置项或者用来对外提供Bean

该配置类中通过@Bean来对外提供Bean的方法会被增强,每次都会返回Spring容器管理的Bean

演示一下

例如:在@Configuration修饰的类,在此类中有一个被@Bean修饰的方法,用来对外提供Bean。

我们获取到此类型的Bean后,可以像普通方法一样来调用这个被@Bean修饰的方法,会得到返回的对象。

区别在于:

  • proxyBeanMethods属性为true时,此类被代理,方法得到增强,那么我们每次通过此类型的Bean来调用@Bean修饰的方法,每次返回的都是Spring容器中的单例Bean
  • proxyBeanMethods属性是false时,此类型的Bean就是一个普通的Bean,未被代理,那么每次调用@Bean修饰的方法,这都是一个普通的方法,返回的都是新的普通的对象,不是被Spring容器管理的对象

测试

例如;

  1. 先来看,当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 证明此方法就是普通的方法,每次都会创建一个对象
  1. 再来看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修饰的方法,就是一个普通的方法,每次调用都会返回一个新的对象
posted @   秋天Code  阅读(29)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示