gpt4 book ai didi

java - 为什么这个基于 Java 的 Spring 配置会创建一个单例 bean 的两个实例?

转载 作者:行者123 更新时间:2023-11-30 08:19:43 24 4
gpt4 key购买 nike

当我子类化一个 @Configuration 注释类,并将其提供给 AnnotationConfigApplicationContext

时,会发生这种情况

下面的这些类总结了场景。这是 full source

public class Bar {}

public class Foo {
private Bar bar;
public Foo(Bar bar) { this.bar = bar; }
@Override public String toString() {
return super.toString() + "(" + bar + ")";
}
}

@Configuration
public class BaseAppConfig {
@Bean public Foo foo() { return new Foo(bar()); }
@Bean public Bar bar() { return new Bar(); }
}

/** Omitting @Configuration here */
public class AppConfig extends BaseAppConfig {
@Bean @Override public Bar bar() { return new Bar(); }
}

public class App {
public static void main(String[] args) {
try (AnnotationConfigApplicationContext ctx = new
AnnotationConfigApplicationContext(AppConfig.class)) {
System.out.println(ctx.getBean(Foo.class).toString());
System.out.println(ctx.getBean(Bar.class).toString());
}
}
}

这会打印两个 Bar 实例,我希望在其中看到相同的实例两次:

Foo@3e9b1010(Bar@6c3708b3)
Bar@6f1fba17

最佳答案

因为您省略了 @Configuration 注释(并且因为它不是 @Inherited)

/** Omitting @Configuration here */
public class AppConfig extends BaseAppConfig {

AnnotationConfigApplicationContext中指定类

AnnotationConfigApplicationContext ctx = new
AnnotationConfigApplicationContext(AppConfig.class)

将其标记为常规 bean 类,而不是@Configuration bean 类。

这意味着 @Bean方法在精简模式下运行。

In contrast to the semantics for bean methods in @Configuration classes, 'inter-bean references' are not supported in lite mode. Instead, when one @Bean-method invokes another @Bean-method in lite mode, the invocation is a standard Java method invocation; Spring does not intercept the invocation via a CGLIB proxy. This is analogous to inter-@Transactional method calls where in proxy mode, Spring does not intercept the invocation — Spring does so only in AspectJ mode.

强调我的。这意味着 bar() 调用

return new Foo(bar());

实际上只是再次调用 bar(),它不会返回创建的旧实例。

@Configuration 的工作原理是让 Spring 创建一个带注释的类的代理,它缓存由 @Bean 工厂方法返回的实例。由于您已删除 @Configuration,因此 Spring 不会应用此缓存,并且方法调用会正常工作,在您的情况下会返回一个新实例。

关于java - 为什么这个基于 Java 的 Spring 配置会创建一个单例 bean 的两个实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26641349/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com