Categories
Spring Spring Core

Spring Annotation Based container configuration

In Spring Framework we have three different ways to configure an IoC Container.

  1. XML Based Container Configuration
    1. Bean configuration will be in the form of XML meta-data. Refer this example for better understanding.
  2. Annotation Based Container Configuration
    1. Annotations will be used to configure each bean and its properties.
  3. Java Based Container Configuration
    1. Using Java Based container configuration, Java code and Annotations will be used to configure IoC Container.

Please read here to know more about IoC Container.

In this article we will look at Annotation-based container configuration with an example code. 

Before proceeding with the Example code, we have to understand the difference between

<context:annotation-config /> and <context:component-scan base-package="..."></context:component-scan>. Both tags are used to activate the features of annotations in application classes. 

Difference between <context:annotation-config /> and <context:component-scan base-package=”…”></context:component-scan>

<context:annotation-config />

  • This will refer to the components that are already configured with IoC Container.
  • By using this you have to define your Bean either in an XML Configuration or Java Based configuration(Using @Bean and @Configuration annotations).
  • For Example : Look at this Article

<context:component-scan base-package=”…”></context:component-scan>

  • It will scan all the Beans defined in the “base-package” attribute, instantiate and configure the Beans annotated with Stereotype annotations.
  • When compared with <context:annotation-config/>, we don’t need to Define bean in XML or Java Configuration externally.
  • <context:annotation-config/> is internally implemented in <context:component-scan/>
  • AutowiredAnnotationBeanPostProcessor and CommonAnnotationBeanPostProcessor are implicitly included when using ComponentScan, These two will automatically detect components and wire together.
  • It helps us to achieve fully annotation based container configuration in Spring and Spring Boot.

We have two different ways to Configure Spring application with <context:component-scan/> to achieve annotation based container configuration.

Type 1 : Using XML configuration file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

	<context:component-scan base-package="net.geekcoders.example"></context:component-scan>
	
</beans>

In this approach you can use XML configuration file to intimate IoC Container, that you are using annotations to define Beans and to look at the mentioned package under “base-package” attribute.

Type 2 : Java Class(Recommended)

@Configuration
@ComponentScan(basePackages = {"net.geekcoders.example"})
public class AppConfig {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		context.register(AppConfig.class);
		context.refresh();	
	}
}
  • It is recommended to use Java class with @Configuration and @ComponentScan annotations in your application to avoid confusions. 
  • It is an easy way to configure your container with Bean’s you want. 

Let us look at the example of Annotation-based container configuration using Spring.

Step 1 : Configuring Annotation based container

Create AppConfig.java class under src folder(Name of Class file and folder structure is your choice) and paste the below code.

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import net.geekcoders.controller.EmployeeController;

@Configuration
@ComponentScan(basePackages = {"net.geekcoders.controller","net.geekcoders.service","net.geekcoders.dao"})
public class AppConfig {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		context.register(AppConfig.class);
		context.refresh();
		EmployeeController controller = context.getBean("employeeController",EmployeeController.class);
		controller.createEmployee();
	}
}

@Configuration – Defines the current class is a Configuration class of Spring application.

@ComponentScan – IoC container will search for the classes with Stereotype annotations, configure and assemble for use.

basePackages – providing a list of packages to scan for the Bean’s. IoC Container will not scan for the beans other than these packages.

The above annotations is equivalent to :

<context:component-scan base-package="net.geekcoders.controller,net.geekcoders.service,net.geekcoders.dao"></context:component-scan>

Step 2 : Controller Class

Create EmployeeController.java under “net.geekcoders.controller” and copy below code.

package net.geekcoders.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import net.geekcoders.service.EmployeeManager;

@Controller
public class EmployeeController {
	@Autowired
	private EmployeeManager employeeManager;
	public EmployeeController() {
		System.out.println("Controller Layer :: EmployeeController");
	}
	
	public void createEmployee() {
		this.getEmployeeManager().addNewEmployee();
	}
	
	/**
	 * @return the employeeManager
	 */
	public EmployeeManager getEmployeeManager() {
		return employeeManager;
	}
	/**
	 * @param employeeManager the employeeManager to set
	 */
	public void setEmployeeManager(EmployeeManager employeeManager) {
		this.employeeManager = employeeManager;
	}
}

The annotation @Controller says the class is a Bean and it’s a Controller Layered Bean. @Autowiring annotation to instantiate a bean by the IoC Container.

Step 3 : DAO Layer

Interface :

Create an Interface named “EmployeeDAO.java” and copy below code.

package net.geekcoders.dao;

public interface EmployeeDAO {
	boolean addNewEmployee();
}
Implementation Class :

Create a Class “EmployeeDAOImpl.java” and implement the EmployeeDAO interface.

package net.geekcoders.dao;

import org.springframework.stereotype.Repository;

@Repository
public class EmployeeDAOImpl implements EmployeeDAO{

	@Override
	public boolean addNewEmployee() {
		System.out.println("DAO Layer :: EmployeeDAOImpl");
		return true;
	}

}

Step 4 : Service Layer

Interface :

Create an Interface named “EmployeeManager.java” and copy below code.

package net.geekcoders.service;

public interface EmployeeManager {
	public boolean addNewEmployee();
}
Implementation Class :

Create a Class named “EmployeeManagerImpl.java” and implement it with EmployeeManager.java.

package net.geekcoders.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import net.geekcoders.dao.EmployeeDAO;

@Service
public class EmployeeManagerImpl implements EmployeeManager {
	@Autowired
	private EmployeeDAO employeeDao;

	@Override
	public boolean addNewEmployee() {
		System.out.println("Service Layer :: EmployeeManagerImpl");
		return this.getEmployeeDao().addNewEmployee();
	}

	/**
	 * @return the employeeDao
	 */
	public EmployeeDAO getEmployeeDao() {
		return employeeDao;
	}

	/**
	 * @param employeeDao the employeeDao to set
	 */
	public void setEmployeeDao(EmployeeDAO employeeDao) {
		this.employeeDao = employeeDao;
	}

}

The final structure of the application will look like the screenshot below.

Now run the application, you can see the below output in your console.

When you run the program from the AppConfig.java class :

  • IoC Container will get Created first(AnnotationConfigApplicationContext)
  • AppConfig will then initialize as a Configuration class and scan for the Bean’s based on the parameter we provided in basePackage attribute under @ComponentScan annotation.
  • IoC will configure and instantiate the Bean’s found during component scan.
  • Using the getBean method, the EmployeeController bean will get referred and createEmployee() method will be called.
  • createEmployee method will call addNewEmployee of a Manager class and then addNewEmployee method of a DAO class.
  • All the Sysout will print in the console as shown above.

That’s all for now on the Spring Annotation-based container configuration article with example code…

Happy Reading!!!

2 replies on “Spring Annotation Based container configuration”

Thanks you so much for the article…. very useful….each and every step is clear and understandable….

Leave a Reply

Your email address will not be published. Required fields are marked *