jsa*_*ler 11 java spring spring-boot
在查看 springs 自动配置源代码时,似乎每个自动配置类都设置了proxyBeanMethods = false.
@Configuration(proxyBeanMethods=false)
public class SomeAutoConfiguration {
...
}
Run Code Online (Sandbox Code Playgroud)
javadoc 给出了这个特定字段的详细解释:
指定 {@code @Bean} 方法是否应该被代理以强制执行 bean 生命周期行为,例如,即使在用户代码中直接调用 {@code @Bean} 方法的情况下也返回共享的单例 bean 实例。(...) 如果这不是必需的,因为每个特定配置的 {@code @Bean} 方法都是自包含的并且设计为容器使用的普通工厂方法,请将此标志切换为 {@code false} 以便避免 CGLIB 子类处理。(...)
读完这篇文章后,我仍然很困惑,什么时候最好将它设置为 false。
以下是我的问题:
更新:
在 github 上发现了两个问题,它们解释了为什么它出现false在大多数自动配置类上:
Gee*_*nte 17
像这样的东西:
@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();
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,proxyBeanMethods 将确保“sharedService”方法将被拦截并重用其结果。如果按照普通的java逻辑,在调用serviceA()和serviceB()时,会有两个不同的ServiceC实例,直接调用sharedService()时,会创建第三个实例。然后代理拦截器会保证实际的方法只被调用一次,所以只创建了一个共享ServiceC的实例,ServiceA和ServiceB都会得到共享实例。
您可以使用不同的配置模式来避免这种情况,这可能是自动配置类所做的。
一种方法是通过方法参数而不是嵌套方法调用自动连接服务。它在普通 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);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4226 次 |
| 最近记录: |