In spring autowiring, @Autowired
annotation handles only the 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 them to dependencies. These annotations are called Stereotype annotations as well.
1. Spring Stereotype Annotations
Spring provides the following 4 annotations for marking the specific usages of beans. For each annotation, if we want to define the name of the bean with which they will be registered in DI container, we can pass the name in the annotation attribute, e.g. @Service (“employeeService”).
1.1. @Component
The @Component
annotation marks a Java class as a bean so the component-scanning mechanism can pick it up and pull it into the application context. To use this annotation, apply it over the class as below:
@Component
public class EmployeeDAOImpl implements EmployeeDAO {
...
}
1.2. @Repository
Although the above use of @Component is good enough but we can use a 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
.
@Repository
public class EmployeeDAOImpl implements EmployeeDAO {
...
}
1.3. @Service
The @Service
annotation is also a specialization of 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.
@Service
public class EmployeeServiceImpl inplements EmployeeService {
//...
}
1.4. @Controller
@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.
@Controller
public class UserMgmtController {
//API handler methods
}
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.
2. Component Scanning
The above four annotations will be scanned and configured only when they are scanned by DI container. 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 the 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. Where to Place Stereotype Annotations?
As I already said that you use @Repository
, @Service
and @Controller
annotations over DAO, manager and controller classes. But in real life, we often have separate classes and interfaces at DAO and manager layers. We use an Interface for defining the contract, and classes for defining the implementations of contracts.
Where to use these annotations? Let’s find out.
Always use thespring streotype 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 other concrete classes. Note the references can be of type interfaces. Spring DI container is smart enough to inject the correct instance, in this case, using autowire by type.
An exception to this is to extend a Spring JPA-provided repository interface in which case we do not create the implementation class.
@Repository
public interface EmployeeRepository
extends PagingAndSortingRepository<EmployeeEntity, Long> {
}
4. Difference between @Component and @Bean Annotations
In Spring, @Component and @Bean. both annotations serve almost the same purpose still they are quite different.
- @Component is 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 declare a single bean, rather than automatically letting Spring do it for us.
Another big difference is that @Component
is a class-level annotation whereas @Bean
is a method-level annotation and, by default, the name of the method serves as the bean name.
5. Conclusion
In this Spring tutorial, we learned what Spring stereotype annotations are. we learned these annotations are best used on concrete classes and not over the interface.
Happy Learning !!