1. Overview
In this article, we’ll discuss the most common Spring annotations used to define different types of beans.
There are several ways to configure beans in a Spring container. You can declare them using XML configuration. You can declare beans using the @Bean annotation in a configuration class.
Or you can mark the class with one of the annotations from the org.springframework.stereotype package and leave the rest to component scanning.
2. Simple Component Scanning
Spring can automatically scan a package for beans if component scanning is enabled.
Here’s the simple way to do that with Java configuration:
@Configuration @ComponentScan("com.baeldung") public class JavaConfig { ... }
Using the the @ComponentScan annotation means that Spring will search for any annotated classes within the com.baeldung package and its subpackages.
When using XML configuration, the component scanning can be used just as easily:
<context:component-scan base-package="com.baeldung" />
3. @Component
@Component is the most generic annotation, simply ensuring that the class will be found during classpath scanning and that it will be registered in the context as a bean:
@Component public class Foo { ... }
All other annotations are specializations of @Component.
4. @Repository
DAO or Repository classes usually represent the database access layer in an application, and should be annotated with @Repository.
Here’s a quick example of such a repository for a Foo entity:
@Repository public class FooRepository { ... }
One advantage of using this annotation is that it has automatic persistence exception translation enabled. When using a persistence framework such as Hibernate, native exceptions thrown within classes annotated with @Repository will be automatically translated into subclasses of Spring’s DataAccessExeption.
To enable exception translation, we’ll need to declare your own PersistenceExceptionTranslationPostProcessor bean:
public @Bean PersistenceExceptionTranslationPostProcessor exceptionTranslation() { return new PersistenceExceptionTranslationPostProcessor(); }
Or, via XML configuration:
<bean class= "org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
5. @Service
The business logic of an application usually resides within the service layer – so we’ll use the @Service annotation to indicate that a class belong to that layer:
@Service public class FooService { @Autowired private FooDao fooDao; .... }
During the component scan, this bean will be found by Spring and added into the context during the bootstrapping process.
6. @Controller
The @Controller annotation tells the container that the class is an MVC controller, and is usually used with the @RequestMapping annotation, among others, from the Spring MVC module.
@Controller public class FooController { @RequestMapping("/home") public String getHomePage() { ... } }
7. Stereotype Annotations and AOP
When Spring stereotype annotations are used, it’s easy to create a pointcut that targets all classes that have a particular stereotype.
For example, suppose we want to measure execution time of methods from the DAO layer. We’ll create the following aspect (using AspectJ annotations) taking advantage of @Repository stereotype:
@Aspect @Component public class PerformanceAspect { @Pointcut("within(@org.springframework.stereotype.Repository *)") public void repositoryClassMethods() {}; @Around("repositoryClassMethods()") public Object measureMethodExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable { long start = System.nanoTime(); Object returnValue = joinPoint.proceed(); long end = System.nanoTime(); String methodName = joinPoint.getSignature().getName(); System.out.println( "Execution of " + methodName + " took " + TimeUnit.NANOSECONDS.toMillis(end - start) + " ms"); return returnValue; } }
In this example, we created a pointcut that matches all methods in classes annotated with @Repository. We used the @Around advice to then target that pointcut, and determine the execution time of the intercepted methods calls.
Using this approach, we may add logging, performance management, audit, or other behaviors to each application layer.
8. Conclusion
In this article we have examined the Spring stereotype annotations and learned what type of semantics these each represent.
We also learned how to use component scanning to tell the container where to find annotated classes.
Finally – we saw how these annotations lead to a clean, layered design and separation between the concerns of an application. They also make configuration smaller, as we no longer need to explicitly define beans manually.
The implementation of all these examples and code snippets can be found in my github project – this is an Eclipse based project, so it should be easy to import and run as it is.