当我将带@Configuration
注释的类子类化并将其提供给AnnotationConfigApplicationContext
下面的这些类概述了该方案。这是完整的来源
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
方法在精简模式下运行。
与
@Configuration
类中bean方法的语义相反,精简模式不支持“ bean间引用”。相反,当一种@Bean
方法@Bean
在精简模式下调用另一种方法时,该调用是标准Java方法调用;Spring不会通过CGLIB代理拦截调用。这类似于内部@Transactional方法调用,在代理模式下,Spring不会拦截调用-Spring仅在AspectJ模式下会拦截调用。
强调我的。这意味着该bar()
呼叫
return new Foo(bar());
实际上只是bar()
再次调用,它没有返回创建的旧实例。
@Configuration
通过让Spring创建带注释的类的代理来工作,该代理将缓存@Bean
工厂方法返回的实例。既然您已经删除了@Configuration
,Spring将不会应用此缓存,并且方法调用将正常工作,在这种情况下,您将返回一个新实例。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句