user1902183 user1902183 - 3 months ago 21
Java Question

How to configure Spring MVC with pure Java-based configuration?

I have, what I would consider a pretty simple Spring MVC setup. My applicationContext.xml is this:

<mvc:annotation-driven />
<mvc:resources mapping="/css/**" location="/css/" />
<context:property-placeholder location="classpath:controller-test.properties" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/views/" p:suffix=".jsp" />


My web.xml is currently this:

<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>


I am trying to convert this set up to pure Java-based config. I've searched the web and so far, I've come up with stuff that explains (some what) how to do the Java config but doesn't explain how to register that Java config with the environment, i.e., the web context.

What I have so far in terms of @Configuration is this:

@Configuration
@EnableWebMvc
@PropertySource("classpath:controller.properties")
@ComponentScan("com.project.web")
public class WebSpringConfig extends WebMvcConfigurerAdapter {

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
}

@Bean
public ViewResolver configureViewResolver() {
InternalResourceViewResolver viewResolve = new InternalResourceViewResolver();
viewResolve.setPrefix("/WEB-INF/views/");
viewResolve.setSuffix(".jsp");

return viewResolve;
}

@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
configurer.enable();
}
}


How do I register this with the web container? I am using the latest spring (4.02).

Thanks!

Answer

You need to make following changes to web.xml in order to support java based configuration. This will tell the the DispatcherServlet to load configuration using the anotation based java configuraion AnnotationConfigWebApplicationContext. you only need to pass the location of your javaconfig file to contextConfigLocation param. as below

<servlet>
  <servlet-name>springDispatcherServlet</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
    <param-name>contextClass</param-name>
    <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
   </init-param>
   <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/*path to your WebSpringConfig*/ </param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

Update: Doing the same without making changes to web.xml

You can even to this without web.xml as Servlet Specification 3.0 makes the web.xml optional. You only need to implement/configure WebApplicationInitializer interface to configures the ServletContext which will allow you to create, configre, registration of DispatcherServlet programmatically. The Good thing is that WebApplicationInitializer is detected automatically.

The summary is the one need to implementWebApplicationInitializer to get rid of web.xml.

 public class MyWebAppInitializer implements WebApplicationInitializer {

 @Override
 public void onStartup(ServletContext container) {
  // Create the 'root' Spring application context
  AnnotationConfigWebApplicationContext rootContext =
                       new AnnotationConfigWebApplicationContext();
  rootContext.register(WebSpringConfig.class);

  // Manage the lifecycle of the root application context
  container.addListener(new ContextLoaderListener(rootContext));

  // Create the dispatcher servlet's Spring application context
  AnnotationConfigWebApplicationContext dispatcherContext =
                     new AnnotationConfigWebApplicationContext();
  dispatcherContext.register(DispatcherConfig.class);

  // Register and map the dispatcher servlet
  ServletRegistration.Dynamic dispatcher =
    container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
    dispatcher.setLoadOnStartup(1);
    dispatcher.addMapping("/");
  }
}

Update: from comments
A slightly more convoluted explanation is also included in official Spring reference now Spring 4 Release Reference:

http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/web/WebApplicationInitializer.html

Comments