spring-projects / spring-projects/spring-framework
Make BeanNameViewResolver use a supplied ApplicationContext
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 60.2k
- Forks
- 38.8k
- Avg merge
- 5d 2h
- Merged PRs (30d)
- 27
Description
With the deprecation of the XmlViewResolver and ResourceBundleViewResolver it is harder to have multiple ViewResolver instances to resolve a view with the same name but for a different content-types.
I thought of using the BeanNameViewResolver however as that is ApplicationContextAware it gets the ApplicationContext it runs in injected, resulting in an error.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pdfViewResolver' defined in class path resource [com/apress/spring6recipes/court/config/ViewResolverConfiguration.class]: Cannot reinitialize with different application context: current one is [org.springframework.context.support.GenericApplicationContext@61b718e, started on Tue Oct 25 17:31:00 GMT 2022], passed-in one is [WebApplicationContext for namespace 'dispatcher-servlet', started on Tue Oct 25 17:31:00 GMT 2022]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:606)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:931)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:916)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:699)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:576)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:530)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:169)
at jakarta.servlet.GenericServlet.init(GenericServlet.java:158)
at jakarta.servlet.http.HttpServlet.init(HttpServlet.java:140)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:995)
at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:696)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:128)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:119)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:400)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1739)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:1589)
Caused by: org.springframework.context.ApplicationContextException: Cannot reinitialize with different application context: current one is [org.springframework.context.support.GenericApplicationContext@61b718e, started on Tue Oct 25 17:31:00 GMT 2022], passed-in one is [WebApplicationContext for namespace 'dispatcher-servlet', started on Tue Oct 25 17:31:00 GMT 2022]
at org.springframework.context.support.ApplicationObjectSupport.setApplicationContext(ApplicationObjectSupport.java:83)
at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:109)
at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:85)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:420)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1745)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599)
It would be nice if we could use the constructor to pass in an ApplicationContext to be used with the BeanNameViewResolver much like the DispatcherServlet does. This way you can have a small ApplicationContext with functional beans to resolve to views with the same name but for different content-types.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading BeanNameViewResolver, ApplicationObjectSupport, and the DispatcherServlet context-handling path described in the stack trace. Determine how a supplied ApplicationContext should be used without conflicting with ApplicationContextAware, then add focused coverage showing resolution from the supplied context and run the relevant Spring MVC tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring
- Domain
- web-dev
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100