Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring @静态方法上的Bean注释_Spring - Fatal编程技术网

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