Tech Brainwave

A Road Map for Innovative Technologies

Java based container configuration in Spring 3.0

Posted by giftsam Posted on Nov - 18 - 2010

Introduction
In Spring 3.0, the IOC container is configured by two ways, the first way is to configure the spring beans by an “XML file” and the second way is to configure the spring beans through the “Java based configuration” by using @Configuration annotation. Now in this article, we are going to learn how to configure the spring beans using the following Java based configuration annotations,

  1. Configuration and Bean Annotaion(@Configuration and @Bean)
  2. Import Annotation(@Import)
  3. Autowired and Qualifier Annotation(@Autowired and @Qualifier)

Required Jars
The required jars to implement the Java based container configuration is given below,

  • Spring3.04 jars(Download, Extract and add the jar files in the library folder)
  • cglib.jar
  • asm.jar

1. Configuration and Bean Annotation
For the Java based configuration, we should add the @Configuration to a java class inorder to configure the Spring IOC container and add the @Bean annotations to define the bean, So that this method will be executed by the Spring framework and returns the object. Let us name the class as “ApplicationConfigBean” and it should looks like the below,

Listing 1.1 – ApplicationConfigBean.java



package com.sample.config;
import com.sample.bean.Sample;
import com.sample.bean.SampleImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author giftsam
*/
@Configuration
public class ApplicationConfigBean
{
public @Bean Sample sample()
{
return new SampleImpl();
}

}

In the preceding code(Listing 1.1), the @Configuration spring annotation is used by the Spring IOC to configure the beans and the @Bean annotation will instruct the IOC container to execute the function. For your understandings, the above “ApplicationConfigBean” class will be defined in the xml like the below,


<beans>
<bean id="sample" class="com.sample.dao.sampleImpl"/>
</beans>

Next we shall create an interface named “Sample” and its implementation class “SampleImpl”. It should looks like the below,

Listing 1.2 – Sample.java



package com.sample.bean;
/**
* @author giftsam
*/
public interface Sample
{
void printValue();
}


Listing 1.3 – SampleImpl.java

 package com.sample.bean;
/**
* @author giftsam
*/
public class SampleImpl implements Sample
{
public void printValue()
{
System.out.println("Values are printed..");
}
}

Finally we need to test our sample application, using the class named “Tester” and it should looks like the below,

Listing 1.4 – Tester.java



package com.sample.tester;

import com.sample.config.AppsConfig;
import com.sample.bean.Sample;
import com.sample.bean.SampleImpl;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Tester
{
/**
* @param args
*/
public static void main(String[] args)
{
ApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationConfigBean.class);
Sample sample = ctx.getBean(SampleImpl.class);
sample.printValue();
}
}


In the preceding test class(Listing 1.4) the application context will accept annotated classes as input , particularly the @Configuration annotated class.

2. Import Annotation
A java class is annotated by the “@Import’ annotation inorder to load the @Bean definitions from an other configuration class and the equivalent tag for @Import annotation in the XML based declaration is <import/>. Now let us see an example of how the @Import annotation is used in Spring 3.0. For this we are going to create a configuration class named “ImporterApplicationConfig”, along with an interface named “Importer” and its implementation class “ImporterImpl”. It should looks like the below,

Listing 2.1 – ImporterApplicationConfig.java


package com.sample.config;

import com.sample.bean.Importer;
import com.sample.bean.ImporterImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
* @author giftsam
*/
@Configuration
@Import(ApplicationConfigBean.class)
public class ImporterApplicationConfig
{

public @Bean Importer sampleA()
{
return new ImporterImpl();
}
}

Listing 2.2 – Importer.java


package com.sample.bean;

/**
* @author giftsam
*/
public interface Importer
{
void printValue();
}

Listing 2.3 – ImporterImpl.java


package com.sample.bean;

/**
* @author giftsam
*/
public class ImporterImpl implements Importer
{
public void printValue()
{
System.out.println("Importer class values are printed..");
}
}

In the preceding Java class(Listing 2.1) “ImportApplicationConfig”, the class(Listing 1.1) “ApplicationConfigBean” is imported. That means, we can load the @Bean definitions of “ApplicationConfigBean” from the “ImportApplicationConfig” class. Now let us enforce this by writing a test class, we shall name the test class as “Launcher” and it should looks like the below,

Listing 2.4 – Launcher.java


package com.sample.tester;

import com.sample.bean.Sample;
import com.sample.bean.Importer;
import com.sample.bean.ImporterImpl;
import com.sample.bean.SampleImpl;
import com.sample.config.ImporterApplicationConfig;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @author giftsam
*/
public class Launcher
{
/**
* @param args
*/
public static void main(String[] args)
{
ApplicationContext context = new AnnotationConfigApplicationContext(ImporterApplicationConfig.class);
Sample sample = context.getBean(SampleImpl.class);
Importer importer = context.getBean(ImporterImpl.class);
sample.printValue();
importer.printValue();
}
}

The output of the above program will be


Values are printed..
Importer class values are printed..

3. Autowired and Qualifier Annotation
Autowired annotation can be injected in the @Configuration annotated class. If so, the @Configuration annotated class will consider the autowired injection just like an another bean. Injecting autowired annotation reduces the  XML in the configuration file. Let us create two classes named “Animal” and “Cow” and a XML configuration file named “config”. It should looks like the below,

Listing 3.1 – Animal.java



import org.springframework.beans.factory.annotation.Autowired;

/**
*
* @author Giftsam
*/
public class Animal
{
@Autowired
private Cow cow;
}


And the XML file for the above bean should looks like the below,

Listing 3.2 – config.xml


<context:annotation-config />
<bean id="Animal" class="com.sample.autowired.Animal"/>
<bean id="cow" class="com.sample.autowired.Cow"/>

For your understandings, Without Autowired annotation the above example(Listing 3.1 and 3.2) would be like the below,

Listing 3.3 – config.xml


<bean id="cow" class="com.sample.autowired.Cow"/>
<bean id="animal" class="com.sample.autowired.Animal">
<property name="cow" ref="cow" />
</bean>

And its corresponding java class would be like the below,

Listing 3.4 – Animal.java


public class Animal{
private Cow cow;
public void setCow(Cow cow) {
this.cow = cow;
}

Now we had clearly understand that Autowired reduces the XML in the configuration file.  As well as,  it can be used in the methods and constructors. An important thing, If more than one bean is checked we should use @Qualifier annotation, otherwise Spring will throw an exception. @Qualifier annotation should be declared like the below,


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class Animal
{
@Autowired
@Qualifier("cow")
}

Conclusion
“Java based configuration” is not a complete replacement for “XML based configuration”. Whatever its up to us. Developer who developes or the project architect should decide whether to use the XML based configuration or Java based configuration or the combination of both. Thats all folks. I hope this article gives you the basic knowledge to do the Java based configuration in Spring 3.0. If you find this article is useful for you, dont forget to leave your valuable comments. Have a joyous code day.

Categories: Java, Spring

6 Responses so far.

  1. Hi,

    Its the crystal clear explanation about java based container configuration in spring.Keep it up.

    Thumb up 0 Thumb down 0

    [Reply]

    giftsam Reply:

    Thanks for your comment Muneeswaran!!

    Thumb up 0 Thumb down 0

    [Reply]

  2. Kris says:

    Thanks for this post. Very useful.

    In your Tester snippet 1.4, shouldn’t the line

    new AnnotationConfigApplicationContext(AppsConfig.class);

    read
    new AnnotationConfigApplicationContext(ApplicationConfigBean.class);

    I did not see a AppsConfig class. Can you clarify.

    Thumb up 0 Thumb down 0

    [Reply]

    giftsam Reply:

    Yes, You are right. Thanks for your comment and notification. I had updated the article!!

    Thumb up 0 Thumb down 0

    [Reply]

  3. Pietro Aragona says:

    Thanks, very useful and clear

    Thumb up 1 Thumb down 0

    [Reply]

  4. Sergei says:

    Thank you very much, this is a great tutorial!

    Thumb up 0 Thumb down 0

    [Reply]