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,
- Configuration and Bean Annotaion(@Configuration and @Bean)
- Import Annotation(@Import)
- 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.
Hi,
Its the crystal clear explanation about java based container configuration in spring.Keep it up.
[Reply]
giftsam Reply:
December 2nd, 2010 at 11:03 pm
Thanks for your comment Muneeswaran!!
[Reply]
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.
[Reply]
giftsam Reply:
December 2nd, 2010 at 11:02 pm
Yes, You are right. Thanks for your comment and notification. I had updated the article!!
[Reply]
Thanks, very useful and clear
[Reply]
Thank you very much, this is a great tutorial!
[Reply]