在不使用Singleton的情况下从非bean对象获取Spring Application上下文

Lio*_*orH 9 singleton spring design-patterns

我需要从非bean对象获取spring应用程序上下文.在SO中的另一个线程中,接受的答案建议使用单例来获取应用程序上下文. 获取Spring应用程序上下文

但是使用单例使得我的代码更加耦合并且不太可测试,许多线程中讨论的常见问题(例如单身人士的坏事)

问题是,有一种优雅的方法从非bean对象获取应用程序上下文而不使用单例吗?

mic*_*oon 8

我认为你的问题几乎与我几天前的情况差不多.我认为以下内容适合您:

首先创建一个AppContextManager如下所示的类:

@Component
public class AppContextManager implements ApplicationContextAware{
    private static ApplicationContext _appCtx;

    @Override
    public void setApplicationContext(ApplicationContext ctx){
         _appCtx = ctx;
    }

    public static ApplicationContext getAppContext(){
        return _appCtx;
    } 
}
Run Code Online (Sandbox Code Playgroud)

使用@Component或为您的AppContextManager声明一个bean来注释上面的类application context xml.

现在在您的non-singleton non-spring实例中使用以下代码片段来获取任何其他spring bean:

ApplicationContext ctx = ApplicationContextManager.getAppContext();
SomeSpringBean bean = ctx.getBean(SomeSpringBean.class);
Run Code Online (Sandbox Code Playgroud)

这将为您提供代码中任何位置的bean实例.


kro*_*old 7

始终存在引导问题.对于Web应用程序,通常有外部servlet过滤器来处理这种情况.

如果不是一个网络应用程序,那么就无法使用某种外部单例或引导程序.但; 在这里使用单例只会影响单个引导程序类的可测试性.您的代码中应该只有很少的地方需要以任何明确的方式引用容器.因此它并没有真正显着增加耦合.

或者换句话说,实际上只需要很少的非bean对象需要访问弹簧容器.如果不是这种情况,那么你可能没有最佳地使用弹簧.大多数/所有需要容器的人应该只是实现BeanFactoryAwareApplicationContextAware