【问题标题】:Spring Framework 5.0.0.Final parent context not getting loadedSpring Framework 5.0.0.Final 父上下文未加载
【发布时间】:2018-04-04 18:06:34
【问题描述】:

我正在尝试使用最新的 spring 5.0.0.Final 与我的 EAR 项目,该项目具有使用 context-paramweb.xml 中定义的父上下文 参数名称为 locatorFactorySelectorparentContextKey 但 spring 无法加载父上下文。当我检查 ContextLoaderListener 源代码时,似乎没有应用逻辑来选择父上下文。这里我的问题是 spring 5 是否提供了 ContextLoader 的任何默认实现来满足父上下文的加载或 spring 5 丢弃,如果不是支持这一点的方法是什么,我是否必须实现我们自己的?

【问题讨论】:

  • 春季团队有任何更新吗?还是他们通过 Stackoverflow 离开支持?
  • 你有想过这个吗?我相信我有同样的问题。在 5 中没有从共享上下文中加载 Bean,但在 4 中做得很好。
  • 不,还没有。我们仍然坚持使用 4。春季问题跟踪器 jira.spring.io/browse/SPR-16258 报告了同样的情况,他们已将问题移至 github github.com/spring-projects/spring-framework/issues/20805

标签: spring spring-mvc spring-config


【解决方案1】:

我的团队最近遇到了同样的问题。我们想开始使用 Webflux,它需要 Spring 5。 这是我所做的:

  1. 手动reintroduceBeanFactoryLocator 机制。从 Spring 4 中获取以下类,将其放入您的代码并修复包:
AbstractUrlMethodNameResolver
AnnotationMethodHandlerAdapter
BeanFactoryLocator
BeanFactoryReference
BootstrapException
ContextSingletonBeanFactoryLocator
DefaultAnnotationHandlerMapping
HandlerMethodInvocationException
HandlerMethodInvoker
HandlerMethodResolver
InternalPathMethodNameResolver
MethodNameResolver
NoSuchRequestHandlingMethodException
ServletAnnotationMappingUtils
SingletonBeanFactoryLocator
SourceHttpMessageConverter
WebUtils
XmlAwareFormHttpMessageConverter
  1. 按照 Subhranil 在此线程中的建议,使用自定义 ContextLoaderListener 加载父上下文,与 Spring 4 中相同。然后在 web.xml 中使用它。
  2. 在每个 WAR 的 spring-servlet.xml add DefaultAnnotationHandlerMapping 中,它会扫描控制器。 Accompanying beansAnnotationMethodHandlerAdapter 一样也是需要的。

它对我们有用。

【讨论】:

    【解决方案2】:

    基于 locatorFactorySelector 的父上下文加载在 ContextLoader#loadParentContext() 处处理。但他们将其更改为在此 commit 中返回 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 中添加了一个监听器。

    【讨论】:

      【解决方案3】:

      显然,使用 SPR-15154 删除了定位父上下文的机制(另请参阅相应的 Github 问题 spring-framework#19720)。

      一种解决方法是扩展org.springframework.web.context.ContextLoaderListener 并重新实现loadParentContext 方法,如this stackoverflow answer 所述。

      在 Spring 5.x 中可能有更好的解决父上下文加载的方法,我仍然需要弄清楚。

      【讨论】:

      • 这是众所周知的,但不适用于 EAR 包装
      【解决方案4】:

      如果您只需要在您正在寻找的任何 Spring 托管类中的上下文参数ServletContextAware

      只需实现该类并覆盖其方法即可获得ServletContext 对象。稍后您还可以使用 ServletContext 对象获取 context-params

      查看一个非常相似的question

      【讨论】:

      • 不仅如此,上述问题仍然可以通过这种方式解决。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多