<

I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE COURSE

1. Overview

The tutorial illustrates how to Bootstrap a Web Application with Spring and also discusses how to make the jump from XML to Java without having to migrate the entire XML configuration completely.

Further reading:

Spring Boot Tutorial – Bootstrap a Simple Application

This is how you start understanding Spring Boot.

Read more

Configure a Spring Boot Web Application

Some of the more useful configs for a Spring Boot application.

Read more

Migrating from Spring to Spring Boot

See how to properly migrate from a Spring to Spring Boot.

Read more

2. The Maven pom.xml

<project xmlns=...>
   <modelVersion>4.0.0</modelVersion>
   <groupId>org</groupId>
   <artifactId>rest</artifactId>
   <version>0.1.0-SNAPSHOT</version>
   <packaging>war</packaging>

   <dependencies>

      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-webmvc</artifactId>
         <version>${spring.version}</version>
         <exclusions>
            <exclusion>
               <artifactId>commons-logging</artifactId>
               <groupId>commons-logging</groupId>
            </exclusion>
         </exclusions>
      </dependency>
      
   </dependencies>

   <build>
      <finalName>rest</finalName>

      <plugins>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.7.0</version>
            <configuration>
               <source>1.8</source>
               <target>1.8</target>
               <encoding>UTF-8</encoding>
            </configuration>
         </plugin>
      </plugins>
   </build>

   <properties>
      <spring.version>5.0.2.RELEASE</spring.version>
   </properties>

</project>

 

3. The Java-based Web Configuration

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "org.baeldung")
public class AppConfig{
   
}

First, the @Configuration annotation – this is the main artifact used by the Java-based Spring configuration; it is itself meta-annotated with @Component, which makes the annotated classes standard beans and as such, also candidates for component-scanning.

The main purpose of @Configuration classes is to be sources of bean definitions for the Spring IoC Container. For a more detailed description, see the official docs.

The @EnableWebMvc is used to provide Spring Web MVC configuration that enables the @Controller and the @RequestMapping annotations; It’s equivalent to this in XML:

<mvc:annotation-driven />

Moving on to @ComponentScan – this configures the component scanning directive, effectively replacing the XML:

<context:component-scan base-package="org.baeldung" />

As of Spring 3.1, the @Configuration are excluded from classpath scanning by default – see this JIRA issue. Before Spring 3.1 though, these classes should have been excluded explicitly:

excludeFilters = { @ComponentScan.Filter( Configuration.class ) }

The @Configuration classes should not be auto-discovered because they are already specified and used by the container – allowing them to be rediscovered and introduced into the Spring context will result in the following error:

Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name ‘webConfig’ for bean class [org.rest.spring.AppConfig] conflicts with existing, non-compatible bean definition of same name and class [org.rest.spring.AppConfig]

3.1. The web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns=...>

   <context-param>
      <param-name>contextClass</param-name>
      <param-value>
         org.springframework.web.context.support.AnnotationConfigWebApplicationContext
      </param-value>
   </context-param>
   <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>org.baeldung</param-value>
   </context-param>
   <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>

   <servlet>
      <servlet-name>rest</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>org.baeldung.spring</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
   </servlet>
   <servlet-mapping>
      <servlet-name>rest</servlet-name>
      <url-pattern>/api/*</url-pattern>
   </servlet-mapping>

   <welcome-file-list>
      <welcome-file />
   </welcome-file-list>

</web-app>

First, the root context is defined and configured to use AnnotationConfigWebApplicationContext instead of the default XmlWebApplicationContext. The newer AnnotationConfigWebApplicationContext accepts @Configuration annotated classes as input for the Container configuration and is needed in order to set up the Java-based context.

Unlike XmlWebApplicationContext, it assumes no default configuration class locations, so the “contextConfigLocation” init-param for the Servlet must be set. This will point to the java package where the @Configuration classes are located; the fully qualified name(s) of the classes are also supported.

Next, the DispatcherServlet is configured to use the same kind of context, with the only difference that it’s loading configuration classes out of a different package.

Other than this, the web.xml doesn’t change from an XML to a Java-based configuration.

4. Conclusion

The presented approach allows for a smooth migration of the Spring configuration from XML to Java, mixing the old and the new. This is important for older projects, which may have a lot of XML based configuration that cannot be migrated all at once.

This way, in a migration, the XML beans can be ported in small increments.

In the next article on REST with Spring, I cover setting up MVC in the project, configuration of the HTTP status codes, payload marshaling, and content negotiation.

As always, the code presented in this article is available over on Github. This is a Maven based project, so it should be easy to import and run as it is.

I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE LESSONS

  Subscribe  
newest oldest most voted
Notify of
Chris Beams
Guest
Chris Beams

Hi Eugen,

Note that as of Spring 3.1 RC2, use of [email protected](Configuration.class) is no longer necessary. See https://jira.springsource.org/browse/SPR-8808.

Would you mind updating your examples to depend on RC2 and eliminating this bit from the @ComponentScan definition?

Thanks for a great series of posts!

Eugen Paraschiv
Guest

Thank you for letting me know (as well as for the actual work). The update is now included in the article.

Amol Khanolkar
Guest
Amol Khanolkar

Can you tell me some advantages of using java based configurations over XML based and when to choose which one?

Torben Vesterager
Guest
Torben Vesterager

Simple – you have one file for configuration and functionality – instead of jumping between 2

Eugen Paraschiv
Guest

Type safety is a big one, and ease of use is a close second.

Stephane
Guest
Stephane

And you can use a debugger if needed.

Eugen Paraschiv
Guest

I updated the article – thanks.

Stephane
Guest
Stephane

It’d be nice to also include a showcase on how to replace the web.xml file by a class implementing the WebApplicationInitializer interface.

Eugen Paraschiv
Guest

I am planning to discuss that in an upcoming article.

Stephane
Guest
Stephane

I could in fact do it, and it wasn’t that hard. The only thing that I could not cut is how to move the elements of the log4j config into a Java config. Google was dry on this one. Maybe your next article would shed some light on this 🙂 Thanks again.

Stephane
Guest
Stephane

It’s funny, my comment was automatically closed by a tag.

Anuj Patel
Guest
Anuj Patel

Thanks ! It really helps to clear concepts and will help while doing actual Implementation