我正在尝试使用最新的 spring 5.0.0.Final 和我的 EAR 项目,该项目在web.xml中使用context-param定义了一个父上下文 ,参数名称为 locatorFactorySelector和parentContextKey但 spring 无法加载父上下文。当我检查ContextLoaderListener源代码时,似乎没有应用逻辑来选择父上下文。这里我的问题是spring 5是否提供任何默认的ContextLoader实现来满足父上下文的加载或spring 5丢弃,如果不是支持这个的方法是什么,我是否必须实现我们自己的?
4 回答
基于 locatorFactorySelector 的父上下文的加载在 ContextLoader#loadParentContext() 处处理。但是他们将其更改为在此提交中返回 null 。
正如 javadoc 所说,我认为您可以创建一个新的 ContextLoaderListener 并覆盖此方法以返回父上下文:
public class FooContextLoaderListener extends ContextLoaderListener{
@Override
protected ApplicationContext loadParentContext(ServletContext servletContext) {
//load and return the parent context ......
}
}
然后使用这个 ContextLoaderListener 来启动 Spring:
<listener>
<listener-class>org.foo.bar.FooContextLoaderListener</listener-class>
</listener>
对我来说,下面这段代码工作得很好。
public class BeanFactoryContextLoaderListener extends ContextLoaderListener {
private static Logger log = Logger.getLogger(BeanFactoryContextLoaderListener.class);
@Override
protected ApplicationContext loadParentContext(ServletContext servletContext) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beanRefFactory.xml");
return ctx;
}
}
显然我也在 web.xml 中添加了一个监听器。
我的团队最近遇到了同样的问题。我们想开始使用 Webflux,它需要 Spring 5。这是我所做的:
- 手动重新引入BeanFactoryLocator 机制。从 Spring 4 中获取以下类,将其放入您的代码并修复包:
AbstractUrlMethodNameResolver
AnnotationMethodHandlerAdapter
BeanFactoryLocator
BeanFactoryReference
BootstrapException
ContextSingletonBeanFactoryLocator
DefaultAnnotationHandlerMapping
HandlerMethodInvocationException
HandlerMethodInvoker
HandlerMethodResolver
InternalPathMethodNameResolver
MethodNameResolver
NoSuchRequestHandlingMethodException
ServletAnnotationMappingUtils
SingletonBeanFactoryLocator
SourceHttpMessageConverter
WebUtils
XmlAwareFormHttpMessageConverter
- 按照 Subhranil 从这个线程的建议,使用自定义 ContextLoaderListener 加载与 Spring 4 中相同的父上下文。然后在 web.xml 中使用它。
- 在每个 WAR 的 spring-servlet.xml 中添加
DefaultAnnotationHandlerMapping
以便它扫描控制器。还需要伴随豆类。AnnotationMethodHandlerAdapter
它对我们有用。
显然,使用SPR-15154删除了定位父上下文的机制(另请参见相应的 Github 问题spring-framework#19720)。
一种解决方法是扩展org.springframework.web.context.ContextLoaderListener
并重新实现此 stackoverflow 答案loadParentContext
中描述的方法。
在 Spring 5.x 中可能有更好的解决父上下文加载的方法,我仍然需要弄清楚。
如果您所需要的只是您正在寻找的任何 Spring 托管类中的上下文参数ServletContextAware
。
只需实现该类并覆盖其方法即可获取ServletContext
对象。稍后您还可以使用该对象获取上下文参数。ServletContext
查看一个非常相似的问题。