基本上,我有一个依赖于B类的A类,而B类又依赖于Spring托管bean C,但我不想将B作为类变量保留,只是出于某种原因在一个方法中使用B.我的解决方案是在B中创建一个静态方法get(),返回B的实例。现在的问题是,C没有正确地注入到B中。
// A cannot have B as a class/field variable.
public class A {
public void method(){
// B.get() returns a instance of B, but this instance is not the
// instance that spring created, it is the static "instance" in B.
B.get().doSomething();// ofcourse it throws out a nullpointer exception
}
}
class B{
@Resource(name = "c")
private C c;
private static B instance;
public static B get() {
return instance==null ? (instance=new B()) : instance;
}
public void doSomething(){
c.toString(); // this line will break if c is not
// injected to the instance of b
}
}
@Service("c")
class C {
}
我该如何解决这个问题?
答案 0 :(得分:2)
使用Spring的全部意义在于它是一个依赖注入框架,你在A中硬编码B的依赖。
尽量不要那样做。如果您不想将B存储在实例变量中,请将其作为参数传递给方法。
如果你对这样做很顽固,那么你必须得到一个ApplicationContext并自己加载它。另一种方法是让B实现InitializingBean,然后让你的afterPropertiesSet方法用静态实例变量注册当前实例。
答案 1 :(得分:1)
没有一点直接的支持这个,但是有几个解决问题的工作。
抓住B.get()中的ApplicationContext并调用getBean以获得构造B的弹簧。获取ApplicationContext是另一项任务,因为它通常不会静态保存,请查看'dirty singleton'的春季参考手册
让spring构造bean,然后在实例变量中保留对它的引用:
@服务( 'b')的 B级{ @Resource(name =“c”) 私人C c;
private static B instance;
public B(){
// sets the static here
// not ideal...should use afterProperties set or what ever the Annotation equivalent is
instance = this;
}
public static B get() {
if( instance == null ){
throw new IllegalStateException("errr...say something useful here")
}
return instance;
}
public void doSomething(){
c.toString(); // this line will break if c is not
// injected to the instance of b
}
}
我已经看过2.在各种项目中使用了几次,它并不漂亮,如果你有选择不这样做,只需要弹簧连接整个应用程序。但如果你没有选择,那可能是最差的选择。
答案 2 :(得分:0)
您必须以编程方式从Spring ApplicationContext
获取bean,在A#method()
内,或在A的构造函数或其初始化方法中,并缓存Spring注入的B实例。