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

时间:2009-01-24 09:28:58

标签: design-patterns spring singleton

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

但是使用单例会使我的代码更加耦合且不易测试,许多线程中讨论的常见问题(例如What is so bad about Singletons

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

2 个答案:

答案 0 :(得分: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;
    } 
}

使用@Component注释上述类,或在application context xml中为AppContextManager声明一个bean。

现在,在non-singleton non-spring个实例中,使用以下代码段获取其他任何代码 春豆:

ApplicationContext ctx = ApplicationContextManager.getAppContext();
SomeSpringBean bean = ctx.getBean(SomeSpringBean.class);

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

答案 1 :(得分:7)

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

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

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