是否有一种方法可以在Spring应用程序中静态/全局地请求ApplicationContext的副本?
假设主类启动并初始化了应用程序上下文,它是否需要通过调用堆栈向下传递给任何需要它的类,或者类是否有一种方法来请求先前创建的上下文?(我假设它必须是单例的?)
是否有一种方法可以在Spring应用程序中静态/全局地请求ApplicationContext的副本?
假设主类启动并初始化了应用程序上下文,它是否需要通过调用堆栈向下传递给任何需要它的类,或者类是否有一种方法来请求先前创建的上下文?(我假设它必须是单例的?)
当前回答
这里有一个很好的方法(不是我的,原始参考在这里: http://sujitpal.blogspot.com/2007/03/accessing-spring-beans-from-legacy-code.html
我使用过这种方法,效果很好。基本上,它是一个简单的bean,包含对应用程序上下文的(静态)引用。通过在spring配置中引用它来初始化它。
看看原来的裁判,非常清楚。
其他回答
在你执行任何其他建议之前,问自己这些问题…
为什么我要获取ApplicationContext? 我是否有效地使用ApplicationContext作为服务定位器? 我可以完全避免访问ApplicationContext吗?
在某些类型的应用程序(例如Web应用程序)中,这些问题的答案比在其他应用程序中更容易,但无论如何都值得一问。
访问ApplicationContext确实违反了整个依赖注入原则,但有时您没有太多选择。
即使在添加了@Autowire之后,如果你的类不是一个RestController或Configuration class, applicationContext对象仍然是空的。尝试用下面创建新类,它工作正常:
@Component
public class SpringContext implements ApplicationContextAware{
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws
BeansException {
this.applicationContext=applicationContext;
}
}
然后,你可以在同一个类中根据你的需要实现一个getter方法,比如通过:
applicationContext.getBean(String serviceName,Interface.Class)
我使用一种简单、标准化的方法允许外部访问我自己的任何单例Spring bean。使用这个方法,我继续让Spring实例化Bean。我是这么做的:
定义与外围类类型相同的私有静态变量。 在类的每个构造函数中将该变量设置为this。如果类没有构造函数,则添加一个用于设置变量的默认构造函数。 定义一个返回单例变量的公共静态getter方法。
这里有一个例子:
@Component
public class MyBean {
...
private static MyBean singleton = null;
public MyBean() {
...
singleton = this;
}
...
public void someMethod() {
...
}
...
public static MyBean get() {
return singleton;
}
}
然后我可以在单例bean上调用someMethod,在我代码中的任何地方,通过:
MyBean.get().someMethod();
如果您已经子类化了您的ApplicationContext,您可以直接将这种机制添加到它中。否则,您可以子类化它来完成这个任务,或者将这个机制添加到任何可以访问ApplicationContext的bean中,然后使用它来从任何地方访问ApplicationContext。重要的是,正是这个机制让您能够进入Spring环境。
你可以实现ApplicationContextAware或者使用@Autowired:
public class SpringBean {
@Autowired
private ApplicationContext appContext;
}
SpringBean将注入ApplicationContext,在其中实例化此bean。例如,如果你有一个非常标准的上下文层次结构的web应用程序:
main application context <- (child) MVC context
并且SpringBean是在主上下文中声明的,它将被注入主上下文; 否则,如果它是在MVC上下文中声明的,它将被注入MVC上下文。
这里有一个很好的方法(不是我的,原始参考在这里: http://sujitpal.blogspot.com/2007/03/accessing-spring-beans-from-legacy-code.html
我使用过这种方法,效果很好。基本上,它是一个简单的bean,包含对应用程序上下文的(静态)引用。通过在spring配置中引用它来初始化它。
看看原来的裁判,非常清楚。