java - 何时在 Springs @Configuration 中将 proxyBeanMethods 设置为 false?

标签 java spring spring-boot

查看 spring 自动配置时 source code似乎每个自动配置类都设置 proxyBeanMethods = false

@Configuration(proxyBeanMethods=false)
public class SomeAutoConfiguration {
    ...
}

javadoc 给出了这个特定字段的详细解释:

Specify whether {@code @Bean} methods should get proxied in order to enforce bean lifecycle behavior, e.g. to return shared singleton bean instances even in case of direct {@code @Bean} method calls in user code. (...) If this is not needed since each of this particular configuration's {@code @Bean} methods is self-contained and designed as a plain factory method for container use, switch this flag to {@code false} in order to avoid CGLIB subclass processing.(...)

读完本文后,我仍然很困惑什么时候将其设置为 false 更好。

这是我的问题:

  • 有人可以举一个具体的例子,说明该字段何时应该为真并解释原因吗?
  • 为什么在自动配置类上此字段设置为 false?

更新: 在 github 上发现了两个问题,它们给出了为什么大多数自动配置类上的 false 的一些解释:

最佳答案

类似这样的事情:

@Configuration(proxyBeanMethods=true)
public class SomeConfiguration {
    @Bean
    ServiceA serviceA(){
      return new ServiceA(sharedService());
    }

    @Bean
    ServiceB serviceB(){
      return new ServiceB(sharedService());
    }

    @Bean
    ServiceC sharedService(){
      return new ServiceC();
    }
}

这里,proxyBeanMethods 将确保“sharedService”方法将被拦截并重用其结果。如果按照正常的java逻辑,当调用serviceA()和serviceB()时,将有两个不同的ServiceC实例,而当直接调用sharedService()时,将创建第三个实例。然后代理拦截器会确保实际方法只被调用一次,因此只创建一个共享ServiceC的实例,ServiceA和ServiceB都会获得共享实例。

但是 proxyBeanMethods=true 在启动过程中会有性能消耗,特别是对于带有大量 @Configuration 类的库,比如 spring-boot 的内部库。参见例如https://github.com/spring-projects/spring-boot/issues/9068#issuecomment-461520814对 Spring WebFlux 的影响。 默认情况下他们无法将其更改为 false,因为这会破坏向后兼容性。请参阅原始问题中的链接。

您可以使用不同的配置模式来避免这种情况,这可能就是自动配置类所做的。

实现此目的的一种方法是通过方法参数而不是嵌套方法调用自动连接服务。它在普通 Java 中意义不大,但在 Spring 配置中有效:

@Configuration(proxyBeanMethods=false)
public class SomeSmarterConfiguration {

    @Bean
    ServiceC sharedService(){
      return new ServiceC();
    }

    @Bean
    ServiceA serviceA(ServiceC sharedService){
      return new ServiceA(sharedService);
    }

    @Bean
    ServiceB serviceB(ServiceC sharedService){
      return new ServiceB(sharedService);
    }
}

关于java - 何时在 Springs @Configuration 中将 proxyBeanMethods 设置为 false?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61266792/

相关文章:

java - 需要重新设置oracle中sequence的值

java - 带有 Rest 接口(interface)的 Spring Mvc Web 应用程序

java - 如何通过 start-stop-daemon 优雅地关闭 Spring Boot 应用程序

java - 添加动态数量的监听器(Spring JMS)

java - Hibernate 可以生成大写 SQL 吗?

java - 使用HttpClient验证用户名和密码

spring - Spring嵌套的ConfigurationProperties和Kotlin

Spring Boot JUnit 和 @TestPropertySource 使用多个属性文件

java - 输出中每个整数之间的连字符

java - 我应该避免在 Java Swing 中使用 set(Preferred|Maximum|Minimum) 大小方法吗?