@Configuration的proxyBeanMethods

作用:用于控制配置类的代理行为,确定配置类中的 @Bean 方法是否被代理,从而影响 Bean 的创建和管理方式

比较

proxyBeanMethods = true

  • 默认行为: 当 proxyBeanMethods 设置为 true(默认值)时,Spring 会为配置类创建一个代理对象。这个代理对象确保在调用 @Bean 方法时,如果该 Bean 已经在 Spring 容器中存在,则返回容器中的单例实例,而不是每次都创建一个新的实例。
  • 保证单例: 这种方式确保了配置类中的 @Bean 方法是幂等的,即无论调用多少次,返回的都是同一个实例。这对依赖注入和单例模式非常重要。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {
    @Bean
    public MyService myService() {
        return new MyService();
    }
    @Bean
    public MyController myController() {
        // 调用 myService() 方法时,返回的是 Spring 容器中的 MyService 实例,而不是新创建的实例
        return new MyController(myService());
    }
}

proxyBeanMethods = false

  • 禁用代理: 当 proxyBeanMethods 设置为 false 时,Spring 不会为配置类创建代理。这意味着每次调用 @Bean 方法时,都会创建一个新的实例,而不是返回容器中的单例实例。
  • 适用场景: 如果你不需要 @Bean 方法之间的依赖关系,并且想要优化性能以避免代理开销,可以将 proxyBeanMethods 设置为 false。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class AppConfig {
    @Bean
    public MyService myService() {
        return new MyService();
    }
    @Bean
    public MyController myController() {
        // 调用 myService() 方法时,每次都会创建一个新的 MyService 实例
        return new MyController(myService());
    }
}

在这个配置中,每次调用 myService() 方法时,都会创建一个新的 MyService 实例。如果 myController() 方法被频繁调用,将会导致大量的 MyService 实例被创建。

proxyBeanMethods = false为什么能优化性能

proxyBeanMethods = true(默认值)
  • 代理开销: 当 proxyBeanMethods 设置为 true 时,Spring 会为配置类创建一个 CGLIB 代理。这个代理会拦截对 @Bean 方法的调用,以确保在方法之间引用同一个 Bean 实例。虽然这种代理机制确保了 Bean 的单例性和依赖关系,但它也引入了一些额外的开销。
  • 运行时检查: 每次调用 @Bean 方法时,代理对象会进行检查,以决定是返回现有的 Bean 实例还是创建一个新的实例。这个过程涉及到运行时反射和方法调用的拦截,都会消耗一定的资源。
proxyBeanMethods = false
  • 无代理开销: 当 proxyBeanMethods 设置为 false 时,Spring 不会为配置类创建代理。这意味着配置类中的 @Bean 方法是普通的 Java 方法,没有代理对象来拦截和处理这些方法调用。
  • 直接调用: @Bean 方法的调用是直接的,没有额外的检查和拦截。这减少了运行时的开销,因为不再需要代理机制的参与。
  • 编译时优化: 因为没有代理,Java 编译器和 JVM 可以对配置类和 @Bean 方法进行更多的优化,例如方法内联和其他 JIT 编译优化。

proxyBeanMethods = false时,创建对象也是要消耗性能的

代理开销 vs. 对象创建开销
  • 代理开销(proxyBeanMethods = true): Spring 通过创建 CGLIB 代理来管理配置类中的 @Bean 方法。这确保了方法调用返回的是容器中的单例实例,但代理的创建和运行时拦截会引入额外的开销。
  • 对象创建开销(proxyBeanMethods = false): 每次调用 @Bean 方法时都会创建一个新的对象实例。虽然避免了代理相关的开销,但频繁的对象创建也会增加内存使用和垃圾回收的负担。
适用场景
  • 频繁调用 @Bean 方法且需要单例: 如果配置类中的 @Bean 方法被频繁调用,并且这些方法之间存在依赖关系,使用 proxyBeanMethods = true 更加合适。这种情况下,代理开销可以接受,因为它确保了方法调用的幂等性和单例性。
  • 简单配置类或不需要单例: 如果配置类中的 @Bean 方法不会频繁调用,或者每次调用返回的新实例不会对应用的性能造成显著影响,可以使用 proxyBeanMethods = false。这种配置避免了代理开销,适用于简单的、独立的 Bean 创建场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值