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.