Categories
Spring Spring Core

Stereotype Annotations in Spring and Spring Boot

The @Component, @Controller, @Service and @Repository are the Stereotype annotations of Spring and Spring Boot

Instead of providing Bean Definitions in XML Configuration file Spring provides these Stereotype annotations that can be defined in Java class itself. 

Spring Automatically detects Stereotyped classes and configured with the ApplicationContext.

As per the above diagram, @Controller, @Service and @Repository are derived from @Component annotation to define a Bean in a more generic way. And it supports some specific functionalities also.

@Component

Spring will detect Component annotated classes and configure them with ApplicationContext automatically. 

You can use @Component annotation in Controller class, DAO Class or any other classes that should be configured as Bean. 

Example :
@Component
public class EmployeeController {
	public EmployeeController() {
		System.out.println("Employee Controller");
	}
}

@Controller

Instead of Using @Component for controller layer classes, you can provide @Controller annotation itself. It is recommended to provide annotations based on the specific layer.

@Service

As stated above, Service annotation is also a Stereotype annotation in Spring derived from @Component annotation. 

You can use Service annotation in your Service-Layer classes.

@Repository 

This can be used in DAO Layer classes. When compared with @Controller and @Service annotations, Repository is having added functionality to manage Unchecked Exceptions from DAO Classes. This will be useful when you use Hibernate or JPA as your DAO Provider.

Let us see the working example code on each annotation for better understanding and to understand the real use case in this article.

In the below example we have three layers, Controller, Service and DAO. Each layer will have one class configured with respective stereotype annotation. 

I’m using JDK 8, Spring 5.2.6 dependencies and Eclipse for development. You can copy below Spring Dependency in the pom.xml file to refer to Spring 5 Jar’s.

<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>5.2.6.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>5.2.6.RELEASE</version>
		</dependency>
	</dependencies>

The final structure of the Application will be like below.

Starter Class

Create a class with the main method and name it as AppConfig.java in src folder.

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();
	}

}

Since we are using Annotation based container configuration in this example, we don’t need applicationContext.xml(XML Configuration) here.

Controller Layer

Create EmployeeController class under “net.geekcoders.controller” package.

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;
	}
}

Service Layer

Create EmployeeManager interface and implement it in EmployeeManagerImpl class as below.

EmployeeManager :

package net.geekcoders.service;

public interface EmployeeManager {
	public boolean addNewEmployee();
}

EmployeeManagerImpl :

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;
	}

}

DAO Layer

Create EmployeeDAO interface and implement it under EmployeeDAOImpl class as like below.

EmployeeDAO :

package net.geekcoders.dao;

public interface EmployeeDAO {
	boolean addNewEmployee();
}

EmployeeDAOImpl : 

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;
	}

}

If you run the above example from AppConfig.java as a Java Application, you can see the below output.

Output

Key Terms :

  • If you noticed all the highlighted lines in the code snippets, we have used @Controller annotation for Controller layer, @Service for Service layer and @Repository for DAO layer respectively.
  • You can replace all the annotations with @Component annotation as well.
  • All other annotations are derived from @Component annotation.
  • @Repository annotation is additionally handling Unchecked exceptions from Hibernate and other ORM frameworks.
  • As like Repository annotation, Controller and Service annotations also will support additional features over @Component annotation. Hence, It is advised to use Layer specific annotation as defined in this example.

That’s all for now on Spring and Spring Boot Stereotype annotations!!!

Happy Reading!!!

One reply on “Stereotype Annotations in Spring and Spring Boot”

Leave a Reply

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