4

I was trying with latest spring 5.0.0.Final with my EAR project which has a parent context defined in web.xml using context-param with param names locatorFactorySelector and parentContextKey but spring could not able to load the parent context. When i checked the ContextLoaderListener source code it seems like there is no logic applied to pick parent context. Here my question is does spring 5 provide any default implementation of ContextLoader which caters loading of parent context or spring 5 dropped, if not what is the approach to support this, do i have to implement our own ?

Sreekanth
  • 539
  • 1
  • 7
  • 24
  • Any update from spring team? or do they left supporting through Stackoverflow ? – Sreekanth Oct 30 '17 at 12:03
  • did you ever figure this out? i believe i'm having the same problem. Beans are not being loaded from the shared context in 5, but did fine in 4. – MeBigFatGuy Apr 10 '19 at 01:14
  • No, not yet. we are still sticking with 4. The same was reported in the spring issue tracker https://jira.spring.io/browse/SPR-16258 and they have moved the issue to github https://github.com/spring-projects/spring-framework/issues/20805 – Sreekanth Apr 12 '19 at 04:27

4 Answers4

2

The loading of the parent context based on locatorFactorySelector were handled at ContextLoader#loadParentContext(). But they changed it to return null in this commit.

As said by the javadoc , I think you can create a new ContextLoaderListener and override this method to return the parent context:

public class FooContextLoaderListener extends ContextLoaderListener{

    @Override
    protected ApplicationContext loadParentContext(ServletContext servletContext) {
        //load and return the parent context ......
    }

}

Then use this ContextLoaderListener to start up Spring :

<listener>
    <listener-class>org.foo.bar.FooContextLoaderListener</listener-class>
</listener>

For me this below piece of code worked fine.

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;
        }

}

Obviously I added a listener too in web.xml.

2

My team recently bumped into the same problem. We wanted to start using Webflux and it requires Spring 5. Here is what I did:

  1. Manually reintroduce BeanFactoryLocator mechanism. Take following classes from Spring 4, put it into your code and fix packages:
AbstractUrlMethodNameResolver
AnnotationMethodHandlerAdapter
BeanFactoryLocator
BeanFactoryReference
BootstrapException
ContextSingletonBeanFactoryLocator
DefaultAnnotationHandlerMapping
HandlerMethodInvocationException
HandlerMethodInvoker
HandlerMethodResolver
InternalPathMethodNameResolver
MethodNameResolver
NoSuchRequestHandlingMethodException
ServletAnnotationMappingUtils
SingletonBeanFactoryLocator
SourceHttpMessageConverter
WebUtils
XmlAwareFormHttpMessageConverter
  1. Following Subhranil's advice from this thread, use custom ContextLoaderListener which loads parent context same as in Spring 4. Then use it in web.xml.
  2. In each WAR's spring-servlet.xml add DefaultAnnotationHandlerMapping so it scans for controllers. Accompanying beans like AnnotationMethodHandlerAdapter are also needed.

It worked for us.

Dharman
  • 30,962
  • 25
  • 85
  • 135
-1

If all you need is your context-param in any of your spring managed class you are looking for ServletContextAware.

Just implement that class and override its method to get the ServletContext object. Later you can also get the context-params using the ServletContext object.

Check out a very similar question.

Abdullah Khan
  • 12,010
  • 6
  • 65
  • 78
-1

Apparently, the mechanism for locating the parent context was removed with SPR-15154 (see also the corresponding Github issue spring-framework#19720).

One workaround is to extend org.springframework.web.context.ContextLoaderListener and re-implement the loadParentContext method is described in this stackoverflow answer.

There is probably a better way to solve parent context loading in Spring 5.x, which I still have to figure out.

MyKey_
  • 837
  • 1
  • 7
  • 22