2012-04-28 4 views
2

Я пытаюсь внедрить объект в одноэлементную реализацию класса. Что-то вроде этогоИспользование ApplicationContextAware в Singleton class

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. У меня есть записи bean для myobject и MyObjectWrapper.

  2. Я знаю, что использование getBean - это не лучшая практика, но в этом конкретном примере это приемлемо? Что такое недостаток? Если не здесь, я буду делать аналогичный вызов getBean в моем основном методе.

я могу сделать getBean в моем основном методе (я имею доступ к контексту приложения там), но я просто хотел, чтобы этот класс Wrapper, чтобы нести ответственность за создание этого синглтон. Объекты, которые нуждаются в MyObject, могут просто вызвать MyObjectWrapper.getImpl(), и они получают объект singleton.

Любая обратная связь на том же будет оценена по достоинству.

ответ

6

Это не будет работать, потому что вы создаете новый экземпляр MyWrapperObject в своем статическом методе getInstance(). Поскольку вы создаете экземпляр, bean is NOT Весна управляется, и поэтому метод 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, тогда любой сможет его удержать и переназначить, если захочет. Это несколько поражает цель ...