Spring能够处理这个用户案例吗?无论是属性还是构造函数注入

时间:2009-07-24 05:11:06

标签: java spring

基本上,我有一个依赖于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 {            
}

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

使用Spring的全部意义在于它是一个依赖注入框架,你在A中硬编码B的依赖。

尽量不要那样做。如果您不想将B存储在实例变量中,请将其作为参数传递给方法。

如果你对这样做很顽固,那么你必须得到一个ApplicationContext并自己加载它。另一种方法是让B实现InitializingBean,然后让你的afterPropertiesSet方法用静态实例变量注册当前实例。

答案 1 :(得分:1)

没有一点直接的支持这个,但是有几个解决问题的工作。

  1. 抓住B.get()中的ApplicationContext并调用getBean以获得构造B的弹簧。获取ApplicationContext是另一项任务,因为它通常不会静态保存,请查看'dirty singleton'的春季参考手册

  2. 让spring构造bean,然后在实例变量中保留对它的引用:

  3. @服务( '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实例。