@Autowired, @Resource and @Inject

All these annotations are used to inject dependent objects in spring.
Lets see what is their differences

@Resource -> javax.annotation
@Inject -> javax.inject
@Autowired -> org.springframework.beans.factory.annotation

Lets start with the below example

Vehicle.java

1
2
3
4
5
package com.kb.autowire_resource_inject;
 
public interface Vehicle {
 
}
package com.kb.autowire_resource_inject;

public interface Vehicle {

}

TwoWheeler.java

1
2
3
4
5
6
7
8
package com.kb.autowire_resource_inject;
 
import org.springframework.stereotype.Component;
 
@Component
public class TwoWheeler implements Vehicle {
 
}
package com.kb.autowire_resource_inject;

import org.springframework.stereotype.Component;

@Component
public class TwoWheeler implements Vehicle {

}

FourWheeler.java

1
2
3
4
5
6
7
8
package com.kb.autowire_resource_inject;
 
import org.springframework.stereotype.Component;
 
@Component
public class FourWheeler implements Vehicle {
 
}
package com.kb.autowire_resource_inject;

import org.springframework.stereotype.Component;

@Component
public class FourWheeler implements Vehicle {

}

Now lets autowire the dependent bean as below

Scenario 1 -> Inject using Interface type

1
2
3
4
5
6
7
8
@Resource
Vehicle vehicle;
 
@Autowired
Vehicle vehicle;
 
@Inject
Vehicle vehicle;
@Resource
Vehicle vehicle;

@Autowired
Vehicle vehicle;

@Inject
Vehicle vehicle;

All the above annotations are doing the same thing that is trying to inject the dependent object by Type.

And type is Vehicle but it has 2 implementations (TwoWheeler and FourWheeler)
Hence stuck with ambiguity exception as below

Scenario 2 -> Inject using field type as concrete class

1
2
3
4
5
6
7
8
@Resource
TwoWheeler vehicle;
 
@Autowired
TwoWheeler vehicle;
 
@Inject
TwoWheeler vehicle;
@Resource
TwoWheeler vehicle;

@Autowired
TwoWheeler vehicle;

@Inject
TwoWheeler vehicle;

Now all the above annotations get successful injection of dependent objects.
Reason – all are trying to inject by type and type of the vehicle is concrete class TwoWheeler hence no ambiguity for injecting.

Scenario 3 -> injecting using field name

1
2
3
4
5
6
7
8
@Resource
Vehicle twoWheeler;
 
@Autowired
Vehicle twoWheeler;
 
@Inject
Vehicle twoWheeler;
@Resource
Vehicle twoWheeler;

@Autowired
Vehicle twoWheeler;

@Inject
Vehicle twoWheeler;

Now all the above annotations will inject the dependent object successfully.

Reason : its injecting by name , whenever we use @Component on the class, automatically class name itself is registered as a spring bean.

And TwoWheeler class register as twoWheeler with container and twoWheeler bean is only one available inside container so no ambiguity.

Scenario 4 -> Qualifier with default bean name

1
2
3
4
5
6
7
8
9
10
11
@Resource
@Qualifier("twoWheeler")
private Vehicle vehicle;
 
@Autowired
@Qualifier("twoWheeler")
private Vehicle vehicle;
 
@Inject
@Qualifier("twoWheeler")
private Vehicle vehicle;
@Resource
@Qualifier("twoWheeler")
private Vehicle vehicle;

@Autowired
@Qualifier("twoWheeler")
private Vehicle vehicle;

@Inject
@Qualifier("twoWheeler")
private Vehicle vehicle;

All the above annotation injects the dependent bean successfully.
Reason : all are injecting by using qualifier name which is thoWheeler and we have only one bean with this name in the container.

Scenario 5 -> Injecting list of beans

1
2
3
4
5
6
7
8
@Resource
private List<Vehicle> vehicles;
 
@Autowired
private List<Vehicle> vehicles;
 
@Inject
private List<Vehicle> vehicles;
@Resource
private List<Vehicle> vehicles;

@Autowired
private List<Vehicle> vehicles;

@Inject
private List<Vehicle> vehicles;

all the above annotations injects the dependencies to the List of supertype class Vehicle.

Scenario 6 -> special behavior of @Resource during beans conflict while injecting

1
2
3
4
5
6
7
8
9
10
11
@Resource
@Qualifier("noSuchBean")
private Vehicle twoWheeler;
 
@Autowired
@Qualifier("noSuchBean")
private Vehicle twoWheeler;
 
@Inject
@Qualifier("noSuchBean")
private Vehicle twoWheeler;
@Resource
@Qualifier("noSuchBean")
private Vehicle twoWheeler;

@Autowired
@Qualifier("noSuchBean")
private Vehicle twoWheeler;

@Inject
@Qualifier("noSuchBean")
private Vehicle twoWheeler;

In above scenario twoWheeler is not injected using @Autowired and @Inject
But twoWheeler is injected using @Resource.

Reason -> @Resource uses the variable name which is twoWheeler to make dependency injection and ignores the @Qualifier.
But @Autowired and @Inject fails as they try to find a bean name specified in @Qualifier.

So @Autowired and @Inject works very similar but @Resource has bit different feature.

The order of choosing injection type

@Autowired and @Inject

1. Match by Type -> bean with same Data type of the variable should be available in spring container
2. Restricts by Qualifier -> If bean of variable’s data type not found or many implementation of the type available then it looks for any qualifier defined and if defined it uses Qualifier and wont go for 3rd option
3. Matches by Name –> searches the bean in the spring whose id should be same as variable name defined while autowiring.

@Resource

1. Match by Name -> first it searches for the bean in spring whose id should be same as variable name declared.
2. Match by Type -> bean with same Data type of the variable should be available in spring container
3. Restricts by Qualifier(ignores if 1st attempt said above by name matches)

About the Author

Karibasappa G C (KB)
Founder of javainsimpleway.com
I love Java and open source technologies and very much passionate about software development.
I like to share my knowledge with others especially on technology 🙂
I have given all the examples as simple as possible to understand for the beginners.
All the code posted on my blog is developed,compiled and tested in my development environment.
If you find any mistakes or bugs, Please drop an email to kb.knowledge.sharing@gmail.com

Connect with me on Facebook for more updates

Share this article on