Spring @静态方法上的Bean注释
有人能解释一下为什么静态方法上的Spring @静态方法上的Bean注释,spring,Spring,有人能解释一下为什么静态方法上的@Bean返回两个不同的实例吗 我可以理解,像类a这样的非静态方法上的@Bean返回相同的实例,因为默认范围是singleton 如果我尝试在服务中使用@Autowire注入类B,它将不起作用,因此它看起来好像没有被Spring应用程序上下文加载。所以使用像D这样的类也是一样的!? 我认为这不是因为对于@PropertySource我们需要另外使用(用于占位符): 如果我们从中删除@Bean,它将无法工作 在静态方法上使用@Bean是否还有其他有用的用例 例如:
@Bean
返回两个不同的实例吗
我可以理解,像类a
这样的非静态方法上的@Bean
返回相同的实例,因为默认范围是singleton
如果我尝试在服务中使用@Autowire
注入类B
,它将不起作用,因此它看起来好像没有被Spring应用程序上下文加载。所以使用像D
这样的类也是一样的!?
我认为这不是因为对于@PropertySource
我们需要另外使用(用于占位符):
如果我们从中删除@Bean,它将无法工作
在静态方法上使用@Bean是否还有其他有用的用例
例如:
当我跑步时:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {Conf.class})
public class Test {
@org.junit.Test
public void test(){
}
}
为了
我得到:
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
因为对
bbb()
的每个方法调用都会创建一个新对象。bean间依赖关系(如果您只是调用bean生成方法)就是这样工作的,即为您的配置类创建一个代理,并且代理拦截对bean方法的方法调用,以交付正确的bean(单例、原型等)。但是,静态方法没有代理,所以当您调用静态方法时,Spring不知道它,您只得到常规Java对象。与PropertySourcesPlaceholderConfigurer不同,因为该方法没有在该类中直接调用,bean将只在使用它的地方被注入。@bean注释的方法得到代理,以便提供正确的bean实例。静态方法不会被代理。因此,在您的例子中,每次调用bbb()都会给出一个新的B实例
PropertySourcePlaceHolderConfigurer类是一种特殊的bean,因为它实现了BeanFactoryPostProcessor。在容器生命周期中,BeanFactoryPostProcessor对象的实例化时间必须早于@Configuration注释类的对象。此外,您不需要调用此静态方法
请参阅java文档中的引导部分:[
必须特别考虑返回的@Bean方法
SpringBeanFactoryPostProcessor(BFPP)类型。因为BFPP对象
必须在容器生命周期的早期实例化,它们可以
干扰诸如@Autowired、@Value、,
和@Configuration类中的@PostConstruct
生命周期问题,将返回@Bean方法的BFPP标记为静态
@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 {
}
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