Spring : Difference between @Autowired, @Inject and @Resource
Points To Remember
- @Inject is not a spring feature you need to include javax inject dependency in order to use @Inject.
- @Autowired is Spring annotation used to inject dependency just like @Inject. It use @Qualifier annotation to differentiate between the beans.
- @Resource is also Spring annotation, but it uses bean name to inject dependencies and differentiate between beans.
Problem Statement :: Structure
In order to show how @Autowired @Inject and @Resource annotations work we will create 3 services- Interface PersonService, this is the interface for all person related operations.
- Class EngineerService, this is the service that will do operations for engineer.
- Class ManagerService, this is the service that will do operations for manager.
So the above structure looks like as shown in the code below.
- public interface PersonService {
- public String getName();
- }
- @Service
- public class EngineerService implements PersonService {
- @Override
- public String getName() {
- return "EngineerService";
- }
- }
- @Service
- public class ManagerService implements PersonService {
- @Override
- public String getName() {
- return "ManagerService";
- }
- }
Test with @Autowired annotations
Parent Reference Type and name
- @RestController
- public class PersonController {
- @Autowired
- private PersonService personService;
- @Resource
- private PersonService personService;
- @Inject
- private PersonService personService;
- }
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException
Parent Reference Type and Child Reference Name
- @RestController
- public class PersonController {
- @Autowired
- private PersonService engineerService;
- @Resource
- private PersonService engineerService;
- @Inject
- private PersonService engineerService;
- }
Note :: When beans are created, they are created by name of the class, EngineerService will resolve to engineerService and its bean will be resolved by name engineerService. Hence when we try to use it with PersonService engineerService , this will inject engineerService bean.-
- public interface PersonService {
- public String getName();
- }
- @Service
- @Qualifier(value = "engineer")
- public class EngineerService implements PersonService {
- @Override
- public String getName() {
- return "EngineerService";
- }
- }
- @Service
- @Qualifier(value = "manager")
- public class ManagerService implements PersonService {
- @Override
- public String getName() {
- return "ManagerService";
- }
- }
- @RestController
- public class PersonController {
- @Autowired
- @Qualifier(value = "engineer")
- private PersonService personService;
- @Resource
- @Qualifier(value = "engineer")
- private PersonService personService;
- @Inject
- @Qualifier(value = "engineer")
- private PersonService personService;
- }
Ambiguous Qualifiers with Parent Reference Type and name
- public interface PersonService {
- public String getName();
- }
- @Service
- @Qualifier(value = "person")
- public class EngineerService implements PersonService {
- @Override
- public String getName() {
- return "EngineerService";
- }
- }
- @Service
- @Qualifier(value = "person")
- public class ManagerService implements PersonService {
- @Override
- public String getName() {
- return "ManagerService";
- }
- }
- @RestController
- public class PersonController {
- @Autowired
- @Qualifier(value = "person")
- private PersonService personService;
- @Resource
- @Qualifier(value = "person")
- private PersonService personService;
- @Inject
- @Qualifier(value = "person")
- private PersonService personService;
- }
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException
This is because spring will not be able to find a unique bean with the qualifier "person".Ambiguous Qualifiers with Parent Reference type and Child Reference name
- public interface PersonService {
- public String getName();
- }
- @Service
- @Qualifier(value = "engineer")
- public class EngineerService implements PersonService {
- @Override
- public String getName() {
- return "EngineerService";
- }
- }
- @Service
- @Qualifier(value = "manager")
- public class ManagerService implements PersonService {
- @Override
- public String getName() {
- return "ManagerService";
- }
- }
- @RestController
- public class PersonController {
- @Autowired
- @Qualifier(value = "engineer")
- private PersonService engineerService;
- @Resource
- @Qualifier(value = "engineer")
- private PersonService engineerService;
- @Inject
- @Qualifier(value = "engineer")
- private PersonService engineerService;
- }
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionExceptionBut, @Resouce will still inject the EngineerService bean.
Hence following conclusion can be made on the basis of the above test scenario's
- All, @Autowired, @Inject and @Resource throws exception with Ambiguous Bean names.
- If Unique Qualifiers are used, all will inject the specified beans.
- If Ambiguous beans are there only @Resouce can inject beans based on names of Bean name.
No comments: