Spring Stereotype Annotations

In spring autowiring, @Autowired annotation handles only wiring part. We still have to define the beans so the container is aware of them and can inject them for us.

With @Component, @Repository, @Service and @Controller annotations in place and automatic component scanning enabled, Spring will automatically import the beans into the container and inject to dependencies. These annotations are called Stereotype annotations as well.

Before jumping to example use of these annotations, let’s learn quick facts about these annotations which will help us in making a better decision about when to use which annotation.

Table of contents

1. Stereotype annotations
2. Enable component scanning
3. How to use stereotype annotations
4. Difference between @Component and @Bean
5. Demo

1. Spring bean stereotype annotations

1.1. @Component annotation

The @Component annotation marks a java class as a bean so the component-scanning mechanism of spring can pick it up and pull it into the application context. To use this annotation, apply it over class as below:

@Component
public class EmployeeDAOImpl implements EmployeeDAO {
    ...
}

1.2. @Repository annotation

Although above use of @Component is good enough but we can use more suitable annotation that provides additional benefits specifically for DAOs i.e. @Repository annotation. The @Repository annotation is a specialization of the @Component annotation with similar use and functionality. In addition to importing the DAOs into the DI container, it also makes the unchecked exceptions (thrown from DAO methods) eligible for translation into Spring DataAccessException.

1.3. @Service annotation

The @Service annotation is also a specialization of the component annotation. It doesn’t currently provide any additional behavior over the @Component annotation, but it’s a good idea to use @Service over @Component in service-layer classes because it specifies intent better. Additionally, tool support and additional behavior might rely on it in the future.

1.4. @Controller annotation

@Controller annotation marks a class as a Spring Web MVC controller. It too is a @Component specialization, so beans marked with it are automatically imported into the DI container. When we add the @Controller annotation to a class, we can use another annotation i.e. @RequestMapping; to map URLs to instance methods of a class.

In realtime usages, we will face very rare situations where we will need to use @Component annotation. Most of the time, we will using @Repository, @Service and @Controller annotations. @Component should be used when the class does not fall into either of three categories i.e. controller, manager and dao.

If we want to define name of the bean with which they will be registered in DI container, we can pass the name in annotation attribute itself e.g. @Service (“employeeManager”).

2. Enable component scanning

Above four annotations will be scanned and configured only when they are scanned by DI container of Spring framework. To enable this scanning, we will need to use “context:component-scan” tag in our applicationContext.xml file.

<context:component-scan base-package="com.howtodoinjava.demo.service" />
<context:component-scan base-package="com.howtodoinjava.demo.dao" />
<context:component-scan base-package="com.howtodoinjava.demo.controller" />

The context:component-scan element requires a base-package attribute, which, as its name suggests, specifies a starting point for a recursive component search. We may not want to give top package for scanning to spring, so you should declare three component-scan elements, each with a base-package attribute pointing to a different package.

When component-scan is declared, you no longer need to declare context:annotation-config, because autowiring is implicitly enabled when component scanning is enabled.

3. Using @Component, @Repository, @Service and @Controller annotations

As I already said that you use @Repository, @Service and @Controller annotations over DAO, manager and controller classes. But in real life, at DAO and manager layer we often have separate classes and interfaces. Interface for defining the contract, and classes for defining the implementations of contracts.

Where to use these annotations? Let’s find out.

Always use the annotations over concrete classes; not over interfaces.

public interface EmployeeDAO
{
    //...
}

@Repository
public class EmployeeDAOImpl implements EmployeeDAO
{
    //...
}

Once you have these stereotype annotations on beans, you can directly use bean references defined inside concrete classes. Note the references are of type interfaces. Spring DI container is smart enough to inject the correct instance in this case.

4. Difference between @Component and @Bean annotations

In Spring, both annotations are quite different.

@Component used to auto-detect and auto-configure beans using classpath scanning. There’s an implicit one-to-one mapping between the annotated class and the bean (i.e. one bean per class).

@Bean is used to explicitly declare a single bean, rather than letting Spring do it automatically for us.

Another big difference is that @Component is a class level annotation where as @Bean is a method level annotation and ,by default, name of the method serves as the bean name.

5. Demo

5.1. Bean definitions

public interface EmployeeDAO 
{
	public EmployeeDTO createNewEmployee();
}

@Repository ("employeeDao")
public class EmployeeDAOImpl implements EmployeeDAO
{
	public EmployeeDTO createNewEmployee()
	{
		EmployeeDTO e = new EmployeeDTO();
		e.setId(1);
		e.setFirstName("Lokesh");
		e.setLastName("Gupta");
		return e;
	}
}
public interface EmployeeManager 
{
	public EmployeeDTO createNewEmployee();
}

@Service ("employeeManager")
public class EmployeeManagerImpl implements EmployeeManager
{
	@Autowired
	EmployeeDAO dao;
	
	public EmployeeDTO createNewEmployee()
	{
		return dao.createNewEmployee();
	}
}
@Controller ("employeeController")
public class EmployeeController 
{
        @Autowired
	EmployeeManager manager;
	
	public EmployeeDTO createNewEmployee()
	{
		return manager.createNewEmployee();
	}
}
public class EmployeeDTO {

	private Integer id;
	private String firstName;
	private String lastName;
}

5.2. Run the demo

Let’s test the above configuration and annotations:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.howtodoinjava.demo.service.EmployeeManager;

public class TestSpringContext 
{
	public static void main(String[] args) 
	{
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

		//EmployeeManager manager = (EmployeeManager) context.getBean(EmployeeManager.class);
		
		//OR this will also work
		
		EmployeeController controller = (EmployeeController) context.getBean("employeeController");
		
		System.out.println(controller.createNewEmployee());
	}
}

Program Output.

Jan 22, 2015 6:17:57 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1b2b2f7f: 
startup date [Thu Jan 22 18:17:57 IST 2015]; root of context hierarchy

Jan 22, 2015 6:17:57 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

INFO: Loading XML bean definitions from class path resource [applicationContext.xml]

Employee [id=1, firstName=Lokesh, lastName=Gupta]

Drop me a comment/query if something needs more explanation.

Happy Learning !!

Leave a Reply

58 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions, and frequently asked interview questions.

Our Blogs

REST API Tutorial