789

I am going through some blogs on SpringSource and in one of the blogs, author is using @Inject and I suppose he can also use @Autowired.

Here is the piece of code:

@Inject private CustomerOrderService customerOrderService;

I am not sure about the difference between @Inject and @Autowired and would appreciate it if someone explained their difference and which one to use under what situation?

Mahozad
  • 18,032
  • 13
  • 118
  • 133
Rachel
  • 100,387
  • 116
  • 269
  • 365
  • 3
    I don't have an answer, since I'm new to this too, but this might help http://sakaenakajima.wordpress.com/2010/08/10/spring-3-annotation-autowired-and-inject/ – Sagar V Aug 22 '11 at 02:44
  • Duplicate: http://stackoverflow.com/questions/13657787/import-custom-java-class – RustyShackleford Jan 27 '16 at 21:44
  • 3
    The difference between '@Inject' and '@Autowired' is explained well in this article https://alextheedom.wordpress.com/2016/02/13/insights-from-stackoverflow-most-voted-for-spring-4-questions/#3 – Alex Theedom May 04 '16 at 22:08
  • Please have a look at this link: https://www.concretepage.com/spring/spring-autowired-annotation#required-false This feature is supported in @Inject automatically without any (required=false) attribute – Ziaullhaq Savanur Jun 18 '20 at 08:21

11 Answers11

830

Assuming here you're referring to the javax.inject.Inject annotation. @Inject is part of the Java CDI (Contexts and Dependency Injection) standard introduced in Java EE 6 (JSR-299), read more. Spring has chosen to support using the @Inject annotation synonymously with their own @Autowired annotation.

So, to answer your question, @Autowired is Spring's own annotation. @Inject is part of a Java technology called CDI that defines a standard for dependency injection similar to Spring. In a Spring application, the two annotations works the same way as Spring has decided to support some JSR-299 annotations in addition to their own.

thi gg
  • 1,969
  • 2
  • 22
  • 47
pap
  • 27,064
  • 6
  • 41
  • 46
  • 129
    So in theory if you used @Inject you could replace spring with another DI framework e.g. Guice and inject your dependencies in the same way. – Alex Barnes Jan 25 '12 at 14:30
  • 76
    At the risk of being pedantic: `@Inject` is a separate JSR (JSR-330) from CDI (JSR-299). – Brad Cupit Nov 05 '13 at 22:12
  • 49
    If you rely on JSR-* annotations only, sure, you *can* replace you DI framework. But will you? Once you've started using spring, chances are you've used a lot more of it than just DI. You won't just make a change; and even if you do, it's not a few search & replaces that is going to make or break the move. On the other hand, Spring's own annotations offer you a lot more functionality. Mastering a good framework will give you more than hardly using many. – Agoston Horvath Aug 10 '15 at 15:03
  • 28
    I agree with you that we dont change the DI frameworks often . However if our source code has multiple packages and if you want to build a common package which you want to share across multiple projects and then going with `@Inject` JSR annotation is better than using `@Autowired` which locks your code base with spring DI. – Aditya Feb 26 '16 at 07:53
  • 5
    Using `@Inject` alone won't ensure framework independence. You'd also need to declare injectable beans without framework dependent mechanisms like Spring's `@Component` or `application.xml`, but use `@Named` and `@Singleton` on class level. No idea if any Spring project really declares beans like that today - I even never heard of any project which migrated from Spring to JEE... – Marcus K. Apr 11 '18 at 11:13
  • Please have a look at this link: https://www.concretepage.com/spring/spring-autowired-annotation#required-false This feature is supported in @Inject automatically without any (required=false) attribute – Ziaullhaq Savanur Jun 18 '20 at 08:18
  • So I suppose this CDI is not in OpenJDK? – Deqing Aug 13 '21 at 11:34
174

Here is a blog post that compares @Resource, @Inject, and @Autowired, and appears to do a pretty comprehensive job.

From the link:

With the exception of test 2 & 7 the configuration and outcomes were identical. When I looked under the hood I determined that the ‘@Autowired’ and ‘@Inject’ annotation behave identically. Both of these annotations use the ‘AutowiredAnnotationBeanPostProcessor’ to inject dependencies. ‘@Autowired’ and ‘@Inject’ can be used interchangeable to inject Spring beans. However the ‘@Resource’ annotation uses the ‘CommonAnnotationBeanPostProcessor’ to inject dependencies. Even though they use different post processor classes they all behave nearly identically. Below is a summary of their execution paths.

Tests 2 and 7 that the author references are 'injection by field name' and 'an attempt at resolving a bean using a bad qualifier', respectively.

The Conclusion should give you all the information you need.

nicholas.hauschild
  • 42,483
  • 9
  • 127
  • 120
  • 4
    That article is a great explanation of the the three annotations. I had to re-read it after the first swipe; but, an excellent article. – Thomas Jun 19 '15 at 12:21
  • 1
    Thanks a lot! The article answered multiple of my answers in my search of finding the differences and similarities between Spring and JavaEE, as well as a few other questions I had. – Kevin Cruijssen Nov 18 '16 at 14:12
  • Please have a look at this link: https://www.concretepage.com/spring/spring-autowired-annotation#required-false This feature is supported in @Inject automatically without any (required=false) attribute – Ziaullhaq Savanur Jun 18 '20 at 08:18
47

To handle the situation in which there is no wiring, beans are available with @Autowired required attribute set to false.

But when using @Inject, the Provider interface works with the bean which means that the bean is not injected directly but with the Provider.

TechSpellBound
  • 2,505
  • 6
  • 25
  • 36
amits
  • 471
  • 4
  • 2
  • 9
    This is so important, and has been overlooked in the most upvoted answers. – Igor Donin Jan 20 '16 at 16:32
  • By default required parameter is set to true for Autowired. Ref: http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Autowired.html – tranquil Mar 07 '17 at 08:25
31

The key difference(noticed when reading the Spring Docs) between @Autowired and @Inject is that, @Autowired has the 'required' attribute while the @Inject has no 'required' attribute.

dimas
  • 2,487
  • 6
  • 40
  • 66
Lucky
  • 16,787
  • 19
  • 117
  • 151
  • 2
    what do u mean by required? – mattyman Jun 21 '16 at 09:58
  • 4
    @mattymanme From the docs, _"By default, the autowiring fails whenever zero candidate beans are available; the default behavior is to treat annotated methods, constructors, and fields as indicating required dependencies. This behavior can be changed by setting the required attribute to false"._ E.g: `@Autowired(required=false)`.In simple terms, _"The `required` attribute indicates that the property is not required for autowiring purposes, the property is ignored if it cannot be autowired."_ – Lucky Jun 21 '16 at 10:42
  • look in to source code public interface Autowired { /** * Declares whether the annotated dependency is required. */ boolean required() default true; } public interface Inject {} – tarn Apr 18 '17 at 06:27
27

As of Spring 3.0, Spring offers support for JSR-330 dependency injection annotations (@Inject, @Named, @Singleton).

There is a separate section in the Spring documentation about them, including comparisons to their Spring equivalents.

Harshal Patil
  • 6,659
  • 8
  • 41
  • 57
Andre Steingress
  • 4,381
  • 28
  • 28
  • Question here, what do you mean when you say Spring supports JSR? Doesn't the container support JSR independent of Spring, and a requirement for the container to be J2EE compliant? Do you mean that it wraps the functionality? If Spring didn't "support" it, wouldn't the annotation from javax still work by default? – Dan Chase Jul 08 '17 at 02:51
  • It's not a must to run Spring in a JEE container, you can also use it in a servlet/JSP container like Tomcat and still have the JSR-330 support. Spring is a separate DI container, it does not "interchange" CDI beans with the host JEE server if its that what you mean. You may either use CDI in a JEE container, or Spring beans - but you can't use both (out of the box). – Andre Steingress Sep 07 '17 at 15:25
16

@Autowired annotation is defined in the Spring framework.

@Inject annotation is a standard annotation, which is defined in the standard "Dependency Injection for Java" (JSR-330). Spring (since the version 3.0) supports the generalized model of dependency injection which is defined in the standard JSR-330. (Google Guice frameworks and Picocontainer framework also support this model).

With @Inject can be injected the reference to the implementation of the Provider interface, which allows injecting the deferred references.

Annotations @Inject and @Autowired- is almost complete analogies. As well as @Autowired annotation, @Inject annotation can be used for automatic binding properties, methods, and constructors.

In contrast to @Autowired annotation, @Inject annotation has no required attribute. Therefore, if the dependencies will not be found - will be thrown an exception.

There are also differences in the clarifications of the binding properties. If there is ambiguity in the choice of components for the injection the @Named qualifier should be added. In a similar situation for @Autowired annotation will be added @Qualifier qualifier (JSR-330 defines it's own @Qualifier annotation and via this qualifier annotation @Named is defined).

Arash
  • 1,692
  • 5
  • 21
  • 36
  • Even though the '@Inject' does not have a required attribute the Java Docs state: Injection of members annotated with '@Inject' is required. Which seems to imply that if an member is not found its inject will fail. See Java Docs: http://docs.oracle.com/javaee/7/api/javax/inject/Inject.html – Alex Theedom Feb 13 '16 at 12:09
16

Better use @Inject all the time. Because it is java configuration approach(provided by sun) which makes our application agnostic to the framework. So if you spring also your classes will work.

If you use @Autowired it will works only with spring because @Autowired is spring provided annotation.

tech.yenduri
  • 586
  • 5
  • 7
  • 17
    Sun is dead. Long live the sun. – Amrinder Arora Feb 13 '16 at 14:35
  • 12
    how often are you going to change the framework? just curious – Kay Apr 18 '17 at 00:38
  • 2
    On most of projects I saw Autowired rather than Inject. I understand the rationale of the answer but I cannot upvote. – Witold Kaczurba Mar 23 '18 at 23:03
  • I understand the agnostic approach, but I think at this level it just doesn't work. If you would like to be agnostic, don't use any frameworks, because they ultimately define how you write your code and after that if you prefer to change it, you'll end up with a code future devs will never understand why was it written like that. However on higher levels, like defining the API of your code, I agree with the agnostic approach. "Code for the interface, not for the implementation." – Adam Bodrogi Jan 02 '23 at 23:25
15

In addition to the above:

  1. The default scope for @Autowired beans is Singleton whereas using JSR 330 @Inject annotation it is like Spring's prototype.
  2. There is no equivalent of @Lazy in JSR 330 using @Inject.
  3. There is no equivalent of @Value in JSR 330 using @Inject.
CodeSlave
  • 425
  • 6
  • 21
Keyur Vyas
  • 191
  • 1
  • 6
12

@Inject has no 'required' attribute

Harshal Patil
  • 6,659
  • 8
  • 41
  • 57
Mike
  • 20,010
  • 25
  • 97
  • 140
  • What's no 'required'? – Ranjithkumar Jan 27 '22 at 12:28
  • By writing @Autowired(required = false) you can finish the initialization of your component even if Spring was unable to wire (inject) the member. @Inject will throw an exception in such case, without the opportunity to continue with construction/injection. – Adam Horvath Feb 04 '22 at 11:50
1

@Autowired(required=false) By default the dependency injection for @Autowired must be fulfilled because the value of required attribute is true by default. We can change this behavior by using @Autowired(required=false). In this case if bean is not found for dependency injection, it will not through error.

Please have look at https://www.concretepage.com/spring/spring-autowired-annotation#required-false

But @Inject doesn’t need (required=false) it will not through error if dependency is not found

Ziaullhaq Savanur
  • 1,848
  • 2
  • 17
  • 20
0

The @Inject annotation is one of the JSR-330 annotations collection. This has Match by Type,Match by Qualifier, Match by Name execution paths. These execution paths are valid for both setter and field injection.The behavior of @Autowired annotation is same as the @Inject annotation. The only difference is the @Autowired annotation is a part of the Spring framework. @Autowired annotation also has the above execution paths. So I recommend the @Autowired for your answer.

ebeneditos
  • 2,542
  • 1
  • 15
  • 35
Kushani5j
  • 73
  • 1
  • 1
  • 8