在Singleton类中使用ApplicationContextAware

时间:2012-04-28 04:12:33

标签: spring singleton inject

我正在尝试将对象注入到单例类实现中。像这样的东西

public class MyObjectWrapper implements ApplicationContextAware {

    public static MyObject myObject;
    private ApplicationContext ctxt;
    private MyObjectWrapper() {}

    public static synchronized MyObject getImpl() {
        if (myObject!=null)
            return myObject;

        MyObjectWrapper myObjectWrapper=new MyObjectWrapper();
        this.myObject = (MyObject) myObjectWrapper.getCtxt().getBean("myobject");
        return myObject;
    }

    @Override
    public void setApplicationContext(ApplicationContext arg0)
            throws BeansException {
        logger.debug("setApplicationContext - " + arg0);
        this.ctxt = arg0;
    }

    public ApplicationContext getCtxt() {
        return ctxt;
    }

    public void setCtxt(ApplicationContext ctxt) {
        this.ctxt = ctxt;
    }

}
  1. 它不起作用,就是当我调用MyObjectWrapper.getImpl()时,我得到一个空的MyObject。我有myobject和MyObjectWrapper的bean条目。

  2. 我知道使用getBean不是最好的做法,但在这个特殊的例子中它是否可以接受?有什么缺点?如果不在这里,我将在我的Main方法中进行类似的getBean调用。

  3. 我可以在我的main方法中执行getBean(我在那里访问应用程序上下文),但是我只是希望这个Wrapper类负责创建这个单例。需要MyObject的对象只需调用MyObjectWrapper.getImpl()即可获得单个对象。

    对此相关的任何反馈都将不胜感激。

1 个答案:

答案 0 :(得分:5)

这不起作用,因为您在静态MyWrapperObject方法中实例化getInstance()的新实例。因为您正在实例化它,所以bean是 NOT Spring管理的,因此Spring不会调用ApplicationContextAware方法setApplicationContext(...)

我不是这个代码的粉丝,但如果你想做这样的事情,我确实有一个建议。而不是将ApplicationContext保存到实例成员,而是将其保存到静态成员。然后,在静态getInstance()方法中,不要创建MyWrapperObject的新实例,只需使用您创建ApplicationContext实例的静态MyObject即可。如果这个类确实是一个Spring单例,那么你应该没有什么可担心的。

这样的事情:

public class MyObjectWrapper implements ApplicationContextAware {
    private static MyObject myObject;
    private static ApplicationContext ctxt;
    private MyObjectWrapper() {}

    public static synchronized MyObject getImpl() {
        if (myObject!=null)
            return myObject;

        this.myObject = ctxt.getBean("myobject", MyObject.class);
        return myObject;
    }

    @Override
    public void setApplicationContext(ApplicationContext arg0) throws BeansException {
        ctxt = arg0;
    }
}

另外,不要让你的对象public。出于某种原因,这是一个单身人士。您希望调用getInstance()的每个人获得该对象的相同实例。如果你成功public,那么任何人都可以抓住它并根据需要重新分配。它有点挫败了目的......