我维护一个旧的应用程序但不熟悉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.fb2
和f.fb3
呢?
答案 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