我正在处理一个遗留代码库,其中一个未在spring中连接的类需要获得一个 在春天连接的类。我希望创建一个在启动时连接的工厂类,然后我可以调用getInstance()方法来获取有线对象。最好的方法是什么?
示例:
public class LegacyA {
public void doSomething() {
...
Foo foo = FooFactory.getInstance();
...
}
}
public class FooFactory {
private static Foo foo;
public static Foo getInstance() {
if (foo == null) throw new IllegalStateException();
return foo;
}
}
我需要在启动时连接FooFactory,以便LegacyA可以简单地调用getInstance(),以便它返回一个Foo实例(它也是在应用程序上下文中定义的bean)。
<bean id="legacyA" class="LegacyA"/>
<bean id="foo" class="Foo"/>
<!-- I need this bean to be injected with foo so that the FooFactory can return a foo -->
<bean id="fooFactory" class="FooFactory"/>
编辑:我不得不重新尝试我的例子,因为我在自己的头脑中有点困惑......
答案 0 :(得分:10)
使用这样的静态非常违反Spring IoC,但如果你真的 使用它们,那么我建议写一个简单的Spring钩子,它接受Foo
和将其注入FooFactory
,例如
public class FooFactoryProcessor implements InitializingBean {
private Foo foo;
public void setFoo(Foo foo) {
this.foo = foo;
}
public void afterPropertiesSet() throws Exception {
Foofactory.setFoo(foo);
}
}
在您的XML中:
<bean id="foo" class="Foo"/>
<bean class="FooFactoryProcessor">
<property name="foo" ref="foo"/>
</bean>
无需修改Foo
或FooFactory
答案 1 :(得分:1)
在这里使用的Spring配置中将bean定义为singleton?然后,您可以使用属性或构造函数注入将其注入LegacyB
(我的首选项是后者),然后只有一个实例可用。
编辑:Re。你改变了的问题(!)我不知道为什么你不再简单地将Foo作为单身人员注入你的工厂。另请注意,您可以使用factory-method通过Spring配置使用getInstance()
方法,并通过所有类维护注入。
答案 2 :(得分:1)
除了skaffman的答案,你必须非常小心初始化顺序。
当使用Spring bean时,只有框架会自动找出初始化内容的正确顺序。但是,一旦你做了单身技巧,如果你不小心,这可能会破裂。
换句话说,确保在应用程序上下文完成加载之前无法运行LegacyA。