任何人都可以解释为什么@Bean静态方法返回2个不同的实例?
我可以理解,@Bean在类非A返回相同实例的非静态方法上,因为默认范围是单例.
如果我尝试注入类B用@Autowire的服务将无法正常工作,所以它看起来像它不是由Spring应用程序上下文加载.所以使用D类似的类会是类似的!我想不是因为@PropertySource我们需要另外使用(用于占位符):
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
Run Code Online (Sandbox Code Playgroud)
如果我们从中删除@Bean,它将无法工作.
还有其他用例,在静态方法上使用@Bean会有用吗?
例:
当我跑:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {Conf.class})
public class Test {
@org.junit.Test
public void test(){
}
}
Run Code Online (Sandbox Code Playgroud)
对于
@Configuration
@ComponentScan
public class Conf {
@Bean
public A aaa(){
return new A();
}
@Bean
public static B bbb(){
return new B();
}
@Bean
@Scope("prototype")
public C ccc(){
return new C();
}
public static D ddd(){
return new D();
}
@PostConstruct
public void post(){
System.out.println(aaa());
System.out.println(aaa());
System.out.println(bbb());
System.out.println(bbb());
System.out.println(ccc());
System.out.println(ccc());
System.out.println(ddd());
System.out.println(ddd());
}
}
public class A {
}
public class B {
}
public class C {
}
public class D {
}
Run Code Online (Sandbox Code Playgroud)
我明白了:
uk.co.xxx.unit.A@6caf0677
uk.co.xxx.unit.A@6caf0677
uk.co.xxx.unit.B@413d1baf
uk.co.xxx.unit.B@16eb3ea3
uk.co.xxx.unit.C@353352b6
uk.co.xxx.unit.C@4681c175
uk.co.xxx.unit.D@57a78e3
uk.co.xxx.unit.D@402c4085
Run Code Online (Sandbox Code Playgroud)
因为您为每个方法调用创建一个新对象bbb().bean之间的依赖关系(如果你只是调用bean生成方法)以这种方式工作,为你的配置类创建一个代理,并且代理拦截对bean方法的方法调用以提供正确的bean(单例,原型等). ).但是,静态方法不会被代理,因此当您调用静态方法时,Spring不知道它,您只需获取常规Java对象.使用PropertySourcesPlaceholderConfigurer它是不同的,因为该方法不是在该类中直接调用的,所以bean只会在使用它的地方注入.
@Bean 注释的方法被代理以提供正确的 bean 实例。静态方法不会被代理。因此,在您的情况下,每次调用 bbb() 都会给出一个新的 B 实例。
PropertySourcesPlaceholderConfigurer 类是一种特殊的 bean,因为它实现了 BeanFactoryPostProcessor。在容器生命周期中,BeanFactoryPostProcessor 对象必须早于@Configuration-annotated 类的对象被实例化。你也不需要调用这个静态方法。
请参阅 java 文档中的 Bootstrapping 部分:[ http://docs.spring.io/spring/docs/4.2.x/javadoc-api/org/springframework/context/annotation/Bean.html][1]
必须特别考虑返回 Spring BeanFactoryPostProcessor (BFPP) 类型的 @Bean 方法。由于 BFPP 对象必须在容器生命周期的早期实例化,因此它们可能会干扰 @Configuration 类中的 @Autowired、@Value 和 @PostConstruct 等注释的处理。为避免这些生命周期问题,请将返回 BFPP 的 @Bean 方法标记为静态
| 归档时间: |
|
| 查看次数: |
5475 次 |
| 最近记录: |