Reputation: 109
I have a legacy application which uses web.xml configuration. The web.xml looks something like this.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring/common-beans-context.xml
</param-value>
</context-param>
<servlet>
<servlet-name>dispatcherOne</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcherOne-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherOne</servlet-name>
<url-pattern>/test/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>dispatcherTwo</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcherTwo-context.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherTwo</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
To Convert this to Spring Boot Application,
I have done the below changes:
@Bean
public XmlWebApplicationContext xmlWebApplicationContext() {
XmlWebApplicationContext applicationContext = new XmlWebApplicationContext();
applicationContext.setConfigLocations("classpath:spring/common-beans-context.xml");
applicationContext.refresh();
return applicationContext;
}
@Bean
public ServletRegistrationBean<DispatcherServlet> mvcTestServlet(XmlWebApplicationContext applicationContext) {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
// create child application context
XmlWebApplicationContext childApplicationContext = new XmlWebApplicationContext();
childApplicationContext.setConfigLocation("classpath:spring/dispatcherOne-context.xml");
// set parent from the previous method
childApplicationContext.setParent(applicationContext);
dispatcherServlet.setApplicationContext(childApplicationContext);
childApplicationContext.refresh();
ServletRegistrationBean<DispatcherServlet> servletRegistrationBean = new ServletRegistrationBean<DispatcherServlet>(
dispatcherServlet, "/test/*");
servletRegistrationBean.setName("dispatcherOne");
servletRegistrationBean.addUrlMappings("/test/*");
servletRegistrationBean.setLoadOnStartup(1);
return servletRegistrationBean;
}
@Bean
public ServletRegistrationBean<DispatcherServlet> mvcServlet(XmlWebApplicationContext applicationContext) {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
// similar to the previous method..
// 1. create local applicationContext and then set parent.
}
I added childApplicationContext.refresh() to see if the beans were loading properly but what i think is happening is that the two dispatcher servlets are not able to access the beans defined in the parentContext. and are throwing beans not found exception even though they're available in parentContext
Is there a workaround for this?
or is there any other way I can achieve this ?
Upvotes: 1
Views: 1258
Reputation: 124536
To create a Spring Boot application and re-using your existing config do the following and don't create a context yourself. You are basically trying to outsmart or work-around Spring Boot with what you are currently doing.
Create a class annotated with @SpringBootApplication
and use @ImportResource
to let Spring Boot creat the main application context.
@SpringBootApplication
@ImportResource("classpath:spring/common-beans-context.xml")
public YourApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(YourApplication.class, args);
}
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(YourApplication.class);
}
}
Now as you have 2 DispatcherServlet
s in your original config you need to add 2 ServletRegistrationBean
to set the URL etc.
@Bean
public ServletRegistrationBean<DispatcherServlet> dispatcherServletOneRegistration() {
ServletRegistrationBean<DispatcherServlet> registration = new ServletRegistrationBean(new DispatcherServlet(), "/test/*");
registration.setLoadOnStartup(1);
registration.setName("dispatcherOne");
registration.setInitParameters(Collections.singletonMap("contextConfigLocation", "classpath:spring/dispatcherOne-context.xml");
return registration;
}
And more or less the same for the second servlet.
@Bean
public ServletRegistrationBean<DispatcherServlet> dispatcherServletTwoRegistration() {
ServletRegistrationBean<DispatcherServlet> registration = new ServletRegistrationBean(new DispatcherServlet(), "/");
registration.setLoadOnStartup(1);
registration.setName("dispatcherTwo");
registration.setInitParameters(Collections.singletonMap("contextConfigLocation", "classpath:spring/dispatcherTwo-context.xml");
return registration;
}
Upvotes: 2