Difference between @Resource @Autowired @Inject

@Resource vs @Autowired vs @Inject

Overview
I’ve been asked several times to explain the difference between injecting Spring beans with ‘@Resource’, ‘@Autowired’, and ‘@Inject’. While I received a few opinions from colleagues and read a couple of posts on this topic I didn’t feel like I had a complete picture.

Annotations 
ANNOTATION
PACKAGE
SOURCE
@Resource
javax.annotation
Java
@Inject
javax.inject
Java
@Qualifier
javax.inject
Java
@Autowired
org.springframework.bean.factory
Spring
The Code
I am using below code to check the difference in between @Resource @Autowired and @Inject annotations. I wanted to know how ‘@Resource’, ‘@Autowired’, and ‘@Inject’ resolved dependencies. I have created an interface called ‘Party’ and created two implementations classes. This allowed me to inject beans without using the concrete type. This provided the flexibility I needed to determine how Spring resolves beans when there are multiple type matches.
public interface Party {

}

‘Person’ is a component and it implements ‘Party’.

package com.sourceallies.person;

@Component
public class Person implements Party {

}

‘Organization’ is a component and it implements ‘Party’.

package com.sourceallies.organization;

@Component
public class Organization implements Party {

}

Test Our Code
Test 1: Ambiguous Beans
In this test I injected a ‘Party’ bean that has multiple implementations in the Spring context and we will use DI in different classes to inject the Party Depenndacy.

@Resource
private Party party;
@Autowired
private Party party;
@Inject
private Party party;

In all three cases a ‘NoSuchBeanDefinitionException’is thrown. While this exception’s name implies that no beans were found, the message explains that two beans were found. All of these annotations result in the same exception.

org.springframework.beans.factory.NoSuchBeanDefinitionException:
No unique bean of type
[com.sourceallies.Party] is defined: expected single matching bean but found 2:[organization, person]

All three annotation behaved in the same way and throw NoSuchBeanDefinitionException when they found more than one bean in the spring context.

Test 2: Field Name
In this test I named the Party field person. By default beans marked with ‘@Component’ will have the same name as the class. Therefore the name of the class ‘Person’ is person.

@Resource
private Party person;
@Autowired
private Party person;
@Inject
private Party person;
All of these styles inject the ‘Person’ bean successfully.

Test 3: With Qualifier
In this test I add a bad ‘@Qualifier’(which is not available in our Spring context) and a matching field name.

@Resource
@Qualifier("bad")
private Party person;

@Autowired
@Qualifier("bad")
private Party person;

@Inject
@Qualifier("bad")
private Party person;

In this case the field marked with ‘@Resource’uses the field name and ignores the ‘@Qualifier’. As a result the ‘Person’ bean is injected.
However the ‘@Autowired’ and ‘@Inject’ field throw a ‘NoSuchBeanDefinitionException’ error because it can not find a bean that matches the ‘@Qualifier’.

Summary
Below is the priority sequence of three annotation
@Autowired and @Inject
Matches by Type
Restricts by Qualifiers
Matches by Name
@Resource
Matches by Name
Matches by Type
Restricts by Qualifiers (ignoredif match is found by name)
 
Resource does not works on setter method / in constructor. Spring recommends to use Autowire as it supports in constructor.