我需要从非bean对象获取spring应用程序上下文。在SO中的另一个线程中,接受的答案建议使用单例来获取应用程序上下文。 Getting Spring Application Context
但是使用单例会使我的代码更加耦合且不易测试,许多线程中讨论的常见问题(例如What is so bad about Singletons)
问题是,有一种优雅的方法可以在不使用单例的情况下从非bean对象获取应用程序上下文吗?
答案 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对象需要访问弹簧容器。如果不是这种情况,那么你可能没有最佳地使用弹簧。大多数/所有需要容器的人应该只是实现BeanFactoryAware或ApplicationContextAware