I'm dealing with a legacy code base where a class which is not wired up in spring needs to obtain a class that is wired up in spring. I was hoping to create a factory class that was wired up on startup and then I could just call the getInstance() method to obtain a wired up object. What is the best way to go about this?
Example:
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;
}
}
I need FooFactory to be wired up on startup so that LegacyA can simply call getInstance() so that it returns an instance of Foo (which is also a bean defined in the application context).
<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"/>
Edit: I had to re-work my example a bit as I got it a bit confuzzled in my own head...
Using statics like this really goes against the grain of Spring IoC, but if you really have to use them, then I would suggest writing a simple Spring hook which takes the Foo
and injects it into the FooFactory
, e.g.
public class FooFactoryProcessor implements InitializingBean {
private Foo foo;
public void setFoo(Foo foo) {
this.foo = foo;
}
public void afterPropertiesSet() throws Exception {
Foofactory.setFoo(foo);
}
}
And in your XML:
<bean id="foo" class="Foo"/>
<bean class="FooFactoryProcessor">
<property name="foo" ref="foo"/>
</bean>
No need to modify Foo
or FooFactory
Is defining the bean as a singleton in the Spring configuration of use here ? You can then inject it into LegacyB
using property or constructor inject (my preference is the latter) and then only the one instance is available.
EDIT: Re. your changed question (!) I not sure why you don't simply inject Foo again as a singleton into your factory. Note also that you can use the getInstance()
method via the Spring configs by using factory-method, and maintain injection through all classes.
In addition to skaffman's answer you must be very very careful about initialization order.
When using Spring beans only the framework will automatically figure out the correct order of initializing stuff. As soon as you are doing singleton tricks however, this may break if you are not careful.
In other words make sure that LegacyA cannot be run before application context finishes loading.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With