@Autowired或@Resource是单身人士吗?

时间:2017-12-12 15:12:02

标签: java spring

我维护一个旧的应用程序但不熟悉Spring Framework。我正在上一个目前看起来像这样的课程:

public class Foo {

    @Resource(name = "fb")
    private FooBar fb;

    @Resource
    private FooBar2 fb2;

    @Autowired
    private FooBar3 fb3 = null;

    ...
}

和一个如下所示的XML文件:

<beans xmlns="http://www.springframework.org/schema/beans" ... >
    <context:annotation-config/>
    ...
    <bean id="fb3" class="FooBar3"/>
    ...
</beans>

在其他一些方法中,类Foo被实例化:

void carryOutSomeFoobarring() {
    Foo f = new Foo();
    ...(use f)...
}

如果从两个不同的线程同时调用carryOutSomeFoobarring,那么当然会有两个独立的局部变量f的Foo实例。但是,字段f.fb的两个实例都会引用相同的注入FooBar对象吗?那么f.fb2f.fb3呢?

3 个答案:

答案 0 :(得分:4)

默认情况下,他们是单身人士。如果范围更改为原型,则会获得单独的对象。

答案 1 :(得分:3)

默认情况下,Spring通过创建每个bean的一个实例来工作。

您可以将它们视为ApplicationContext初始化所创建的所有内容(实际上,根据配置,它们可能会在以后延迟初始化)。

然后,当自动装配时,它识别适当的bean并注入它。如果对使用哪个bean存在任何歧义,则抛出异常。

可以将Bean配置为 prototype bean - 对于那些,每次注入它们时,都会创建一个新实例。但这不是默认值,并不是所有常用的。

但是,Spring依赖注入只发生在Spring bean上 - 而bean是由bean工厂创建的,而不是(直接)由new创建的。大多数时候new Foo()将创建一个Foo的非托管实例 - 不是由Spring管理的东西,因此不会引入字段。

所以我希望:

Foo f = new Foo();
return f.getFooBar();

...返回null

如果Foo()类中的方法调用了更高的调用堆栈,则@Configuration 可能会注入,由Spring本身调用。

答案 2 :(得分:2)

如果您像以前一样创建Foo实例:

Foo f = new Foo();

局部变量fb,fb2,fb3很可能为空。这是因为您在Spring应用程序上下文之外创建了Foo实例,并且不会发生成员变量的连接。

如果它也可以是一个单例,你应该向Foo类添加一个@Component注释,并确保它由Springs Component Scan选中,或者创建一个单独的配置类,你将Foo声明为@Bean