1.1. @Component annotationjava
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:spring
@Component public class EmployeeDAOImpl implements EmployeeDAO { ... }
1.2. @Repository annotationapp
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
.ide
1.3. @Service annotationpost
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.ui
1.4. @Controller annotationthis
@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.idea
@Component
annotation. Most of the time, we will use
@Repository
,
@Service
and
@Controller
annotations.
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.spa
<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.code
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? 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.
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.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; }
Let’s test the above configuration and annotations:
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()); } }