Build Your REST API with Spring - VIDEO Courses
It is very common confusion among the spring developers that what is the real difference between these three (@Resource, @Autowired and @Inject) annotations used for injecting the objects. I have come across this question from our readers so dedicated this post for explaining the main difference between these three annotations. Infact, these three work very much similar in most of the cases, there is slight differnce in few cases. I would explain that in this post. lets start from the basic details about these three annotations.
- @Resource – Defined in the javax.annotation package and part of Java
- @Inject – Defined in the javax.inject package and part of Java
- @Autowired – Defined in the package org.springframework.bean.factory and part of Spring framework.
Here I am creating a simple interface Car which has two implementation classes Volkswagen and Toyota. We are going to inject these three types to understand the difference between these annotations. Lets look at the class below. These are only the code snippets, if you want to run this example please have a complete setup of your spring application.
Also read:
- Spring MVC Framework with Example
- Spring Framework Interview Questions
- Spring Aspect Oriented Programming (AOP)
Car.java
package javabeat.net.basic; public interface Car { }
Volkswagen.java
package javabeat.net.basic; import org.springframework.stereotype.Component; @Component public class Volkswagen implements Car{}
Toyota.java
package javabeat.net.basic; import org.springframework.stereotype.Component; @Component public class Toyota implements Car{}
Inject Interface
@Resource private Car car; @Autowired private Car car; @Inject private Car car;
The following exception is thrown when executing the all the above code:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [javabeat.net.basics.Car] is defined: expected single matching bean but found 2: [volkswagen, toyota]
Field Type
@Resource private Volkswagen car; @Autowired private Volkswagen car; @Inject private Volkswagen car;
The above code works fine for all the above definitions. All the three types inject the type of bean “Volkswagen” by using the bean type.
Qualifier name
@Resource @Qualifier("volkswagen") private Car car; @Autowired @Qualifier("volkswagen") private Car car; @Inject @Qualifier("volkswagen") private Car car;
All the above three annotations inject Volkswagen bean by considering the @Qualifier annotation.
Conflicting Information
@Resource @Qualifier("nkl") private Car volkswagen; @Autowired @Qualifier("nkl") private Car volkswagen; @Inject @Qualifier("nkl") private Car volkswagen;
In the above code, @Resource works fine and inject the Volkswagen type. But, @Autowired and @Injects throws the follwing exception.
org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [javabeat.net.basics.Car] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=nkl)}
The main difference is that, @Autowired and @Inject works similar for 100% without any differentiation.These two annotations using AutowiredAnnotationBeanPostProcessor to inject dependencies. But,@Resource uses CommonAnnotationBeanPostProcessor to inject dependencies and there is difference in the order of checking.
@Autowired and @Inject
- Matches by Type
- Restricts by Qualifiers
- Matches by Name
@Resource
- Matches by Name
- Matches by Type
- Restricts by Qualifiers (ignored if match is found by name)
I hope this article would have provided good insight into these three annotations. If you have any questions, please write it in the comments section.