DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Coding
  3. Frameworks
  4. Bootstraping a web application with Spring 3.1 and Java based Configuration, part 1

Bootstraping a web application with Spring 3.1 and Java based Configuration, part 1

Eugen Paraschiv user avatar by
Eugen Paraschiv
·
Oct. 22, 11 · Interview
Like (1)
Save
Tweet
Share
1.90K Views

Join the DZone community and get the full member experience.

Join For Free

This is the first of a series of posts about setting up a RESTfull web application using Spring 3.1 with Java based configuration. The post will focus on bootstrapping the web application, discussing how to make the jump from XML to Java without having to completely migrate the entire XML configuration.

 

The Java based web configuration

@Configuration
@ImportResource( { "classpath*:/rest_config.xml" } )
@ComponentScan( basePackages = "org.rest",
   excludeFilters = { @Filter( Configuration.class ) } )
public class WebConfig{
   
   @Bean
   public PropertyPlaceholderConfigurer properties(){
      PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
      final Resource[] resources = new ClassPathResource[ ] {
         new ClassPathResource( "persistence.properties" ),
         new ClassPathResource( "restfull.properties" )
      };
      ppc.setLocations( resources );
      ppc.setIgnoreUnresolvablePlaceholders( true );
      return ppc;
   }
   
}

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.

Then, @ImportResource is used to import the existing XML based Spring configuration. This may be configuration which is still being migrated from XML to Java, or simply legacy configuration that you wish to keep. Either way, importing it into the Container is essential for a successful migration, allowing small steps without to much risk. The equivalent XML annotation that is replaced is:

<import resource=”classpath*:/rest_config.xml” />

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

<context:component-scan base-package=”org.rest” />

The configuration classes are filtered/excluded out of component scanning; this is because they are already specified to 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.WebConfig] conflicts with existing, non-compatible bean definition of same name and class [org.rest.spring.WebConfig]

And finally, using the @Bean annotation to configure the properties support – PropertyPlaceholderConfigurer is initialized in a @Bean annotated method, indicating it will produce a Spring bean managed by the Container. This new configuration has replaced the following XML:

<context:property-placeholder
location=”classpath:persistence.properties, classpath:restfull.properties”
ignore-unresolvable=”true”/>

 

The web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   id="WebApp_ID" version="3.0">
   
   <display-name>rest</display-name>
   
   <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.rest.spring.WebConfig</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 DispatcherServlet is 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 fully qualified name(s) of the Java based Spring configuration.

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

 

The Maven pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation=
   "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>org</groupId>
   <artifactId>rest</artifactId>
   <version>0.0.1-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>
      <dependency>
         <groupId>cglib</groupId>
         <artifactId>cglib-nodep</artifactId>
         <version>${cglib.version}</version>
         <scope>runtime</scope>
      </dependency>
      
   </dependencies>

   <build>
      <finalName>rest</finalName>
      
      <plugins>
         
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
               <source>1.6</source>
               <target>1.6</target>
               <encoding>UTF-8</encoding>
            </configuration>
         </plugin>
         
      </plugins>

   </build>
   
   <repositories>
      <repository>
         <id>spring-maven-snapshot</id>
         <name>Springframework Maven Snapshot Repository</name>
         <url>http://maven.springframework.org/snapshot</url>
         <snapshots>
            <enabled>true</enabled>
         </snapshots>
      </repository>
   </repositories>

   <properties>
      <spring.version>3.1.0.BUILD-SNAPSHOT</spring.version>
      <cglib.version>2.2.2</cglib.version>
   </properties>

</project>

The Spring framework snapshot repository is included so that Maven will be able to access the latest Spring snapshots – 3.1.0.BUILD-SNAPSHOT. I’m using the snapshots for this post because some really useful stuff has been added since 3.1.0.M2, especially in the area of Java based configuration for MVC. For the purposes of this post however, 3.1.0.M2 works fine, as none of the new additions are in use for the bootstrapping part. In order to use this version, the snapshot repository should be replaced with:

<repository>
   <id>org.springframework.maven.milestone</id>
   <name>Maven Central Compatible Spring Milestone Repository</name>
   <url>http://maven.springframework.org/milestone</url>
   <snapshots>
      <enabled>false</enabled>
   </snapshots>
</repository>

Justification of the cglib dependency

You may wonder why cglib is a dependency – it turns out there is a valid reason to include it – the entire configuration cannot function without it. If removed, Spring will throw:

Caused by: java.lang.IllegalStateException: CGLIB is required to process @Configuration classes. Either add CGLIB to the classpath or remove the following @Configuration bean definitions

The reason this happens is explained by the way Spring deals with @Configuration classes. These classes are effectively beans, and because of this they need to be aware of the Context, and respect scope and other bean semantics. This is achieved by dynamically creating a cglib proxy with this awareness for each @Configuration class, hence the cglib dependency.

Also, because of this, there are a few restrictions for Configuration annotated classes:

  • Configuration classes should not be final
  • They should have a constructor with no arguments

 

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, the web.xml and bootstrapping of the application is the first step in a migration, after which the remaining XML beans can be ported in small increments.

In part 2, I will cover the MVC configuration and how to set up a RESTful API with JSON payload with only Java based configuration. In the meantime, you can check out the github project.

From http://www.baeldung.com/2011/10/20/bootstraping-a-web-application-with-spring-3-1-and-java-based-configuration-part-1/

Spring Framework Java (programming language) Web application

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • 11 Observability Tools You Should Know
  • DevOps for Developers: Continuous Integration, GitHub Actions, and Sonar Cloud
  • Solving the Kubernetes Security Puzzle
  • Monolithic First

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: