当前位置: 首页 > 知识库问答 >
问题:

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

松兴邦
2023-03-14

查看spings autoconfiure源代码时,似乎每个自动配置类都设置了proxyBeanMethod=false

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

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

指定是否应该代理{@code@Bean}方法以强制bean生命周期行为,例如,即使在用户代码中直接调用{@code@Bean}方法的情况下,也返回共享的单例bean实例。(…)如果不需要这样做,因为此特定配置的每个{@code@Bean}方法都是自包含的,并且设计容器使用的普通工厂方法,请将此标志切换为{@code false}以避免CGLIB子类处理。(…)

读完这篇文章后,我仍然感到困惑,什么时候最好将其设置为false。

这是我的问题:

  • 有人能举一个具体的例子,说明这个字段应该是正确的吗?
  • 为什么此字段在自动配置类上设置为false?

更新:在github上发现了两个问题,可以解释为什么在大多数自动配置类上它是false

    < Li > https://github . com/spring-projects/spring-boot/issues/9068 < Li > https://github . com/spring-projects/spring-framework/issues/22461

共有2个答案

龙洛城
2023-03-14

Spring在5.2版中引入了proxyBeanMethod。proxyBeansMethod的默认值为true。这意味着默认情况下将为使用@Configuration配置的类生成代理对象。在Springboot版本2及以后,所有AutoConfiguration类都使用@Configuration(proxyBeanMethod=false)配置。这是因为自动配置功能在SpringBoot中被广泛使用。生成代理对象将增加Spring的启动时间并增加代理部分的对象内存。最佳实践是使用@Configuration(proxyBeanMethod=false)注释配置类

林绪
2023-03-14

像这样:

@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();
    }
}

在这里,代理Bean方法将确保“共享服务”方法将被拦截并重新使用其结果。如果遵循正常的 java 逻辑,则在调用服务 A() 和服务 B() 时,将有两个不同的服务C 实例,而当直接调用共享服务() 时,将创建第三个实例。然后,代理拦截器将确保实际方法仅调用一次,因此只创建共享 ServiceC 的一个实例,并且 ServiceA 和服务 B 都将获取共享实例。

然而,proxyBeanMethods=true在启动期间有性能成本,特别是对于具有大量@Configuration类的库,如spring boot的内部库。参见例如。https://github.com/spring-projects/spring-boot/issues/9068#issuecomment-461520814对SpringWebFlux的影响。默认情况下,他们无法将其更改为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);
    }
}
 类似资料:
  • 问题内容: elasticsearch 中该选项的一个好用例是什么?我在es网站上找不到足够的解释。 问题答案: 范数是一个值,它与字段一起存储在索引中,用于评分。使用默认的评分算法,它结合了一个(用于对短字段进行加权而不是对长字段进行加权)和任何字段级别的提升。您可以在Lucene文档中查看有关它的更多信息。 LengthNorm方面在适当的全文字段上最有帮助。在不需要场增强的结构化字段上,可以

  • 问题内容: 我用Java 创建了一个对象。当我这样做时,它显示如下:。结果,我的Excel文件似乎减少了一天(27 feb变为26 feb,依此类推),我认为这一定是因为时间的缘故。如何将其设置为下午5:30? 问题答案: 另请参阅 乔达时间 日历文件

  • 我有一个用于使用Oracle DB的mybatis+springs的现有设置。我有一组java映射器接口,一组对应的映射器XML(每个都有对其对应的java映射器的引用)。我也需要设置对MSSQL的支持,但发现很难做到这一点。我在com/mycomp/mob/db/mappers/MSSQL中创建了一组单独的XML(特定于MSSQL的查询)。 下面是我的applicationconext.xml的

  • 问题内容: 我正在使用Jenkins Multibranch Pipelines实施构建工作。最后阶段是将构建输出上传到Artifactory。 通过界面配置独立作业时,有一个选项“从Artifactory丢弃旧版本”,这使我只能保留与“要保留的最大版本数”设置中指定的相同数量的版本。 我的Jenkins文件中的上传阶段配置如下:https ://wiki.jenkins- ci.org/disp

  • 本文向大家介绍如何在JavaFX中将动作设置为RadioButton?,包括了如何在JavaFX中将动作设置为RadioButton?的使用技巧和注意事项,需要的朋友参考一下 单选按钮是一种圆形的按钮。它有两种状态,选择和取消选择。通常,单选按钮使用切换组进行分组,您只能在其中选择一个。 您可以通过实例化javafx.scene.control.RadioButton类(它是ToggleButto

  • 我正在与来自不同项目的不同人员在线工作,他们负责后端API webservice。通常我在发送和接收JSON方面没有问题,但这次,我似乎无法正确地将JSON发送到服务器。 通常我使用Alamofire来接收和发送JSON消息,通常的调用如下: 但这一次,我得到了后端程序员要求我使用OAuthV2的项目。假设我已经开发了一个函数,它已经负责获取访问令牌字符串。该函数现在变成如下所示: 但结果不是40