在Singleton类中使用ApplicationContextAware

noi*_*i.m 2 singleton spring 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;
    }

}
Run Code Online (Sandbox Code Playgroud)
  1. 它不起作用,就是当我调用MyObjectWrapper.getImpl()时,我得到一个null MyObject.我有myobject和MyObjectWrapper的bean条目.

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

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

任何有关相同的反馈将不胜感激.

nic*_*ild 5

这不起作用,因为您MyWrapperObject在静态getInstance()方法中实例化一个新实例.因为您正在实例化它,所以bean 不是 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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