@Resource vs @Autowired

264,051

Solution 1

In spring pre-3.0 it doesn't matter which one.

In spring 3.0 there's support for the standard (JSR-330) annotation @javax.inject.Inject - use it, with a combination of @Qualifier. Note that spring now also supports the @javax.inject.Qualifier meta-annotation:

@Qualifier
@Retention(RUNTIME)
public @interface YourQualifier {}

So you can have

<bean class="com.pkg.SomeBean">
   <qualifier type="YourQualifier"/>
</bean>

or

@YourQualifier
@Component
public class SomeBean implements Foo { .. }

And then:

@Inject @YourQualifier private Foo foo;

This makes less use of String-names, which can be misspelled and are harder to maintain.


As for the original question: both, without specifying any attributes of the annotation, perform injection by type. The difference is:

  • @Resource allows you to specify a name of the injected bean
  • @Autowired allows you to mark it as non-mandatory.

Solution 2

Both @Autowired (or @Inject) and @Resource work equally well. But there is a conceptual difference or a difference in the meaning

  • @Resource means get me a known resource by name. The name is extracted from the name of the annotated setter or field, or it is taken from the name-Parameter.
  • @Inject or @Autowired try to wire in a suitable other component by type.

So, basically these are two quite distinct concepts. Unfortunately the Spring-Implementation of @Resource has a built-in fallback, which kicks in when resolution by-name fails. In this case, it falls back to the @Autowired-kind resolution by-type. While this fallback is convenient, IMHO it causes a lot of confusion, because people are unaware of the conceptual difference and tend to use @Resource for type-based autowiring.

Solution 3

The primary difference is, @Autowired is a spring annotation. Whereas @Resource is specified by the JSR-250, as you pointed out yourself. So the latter is part of Java whereas the former is Spring specific.

Hence, you are right in suggesting that, in a sense. I found folks use @Autowired with @Qualifier because it is more powerful. Moving from some framework to some other is considered very unlikely, if not myth, especially in the case of Spring.

Solution 4

I would like to emphasize one comment from @Jules on this answer to this question. The comment brings a useful link: Spring Injection with @Resource, @Autowired and @Inject. I encourage you to read it entirely, however here is a quick summary of its usefulness:

How annotations select the right implementation?

@Autowired and @Inject

  1. Matches by Type
  2. Restricts by Qualifiers
  3. Matches by Name

@Resource

  1. Matches by Name
  2. Matches by Type
  3. Restricts by Qualifiers (ignored if match is found by name)

Which annotations (or combination of) should I use for injecting my beans?

  1. Explicitly name your component [@Component("beanName")]

  2. Use @Resource with the name attribute [@Resource(name="beanName")]

Why should I not use @Qualifier?

Avoid @Qualifier annotations unless you want to create a list of similar beans. For example you may want to mark a set of rules with a specific @Qualifier annotation. This approach makes it simple to inject a group of rule classes into a list that can be used for processing data.

Does bean injection slow my program?

Scan specific packages for components [context:component-scan base-package="com.sourceallies.person"]. While this will result in more component-scan configurations it reduces the chance that you’ll add unnecessary components to your Spring context.


Reference: Spring Injection with @Resource, @Autowired and @Inject

Solution 5

This is what I got from the Spring 3.0.x Reference Manual :-

Tip

If you intend to express annotation-driven injection by name, do not primarily use @Autowired, even if is technically capable of referring to a bean name through @Qualifier values. Instead, use the JSR-250 @Resource annotation, which is semantically defined to identify a specific target component by its unique name, with the declared type being irrelevant for the matching process.

As a specific consequence of this semantic difference, beans that are themselves defined as a collection or map type cannot be injected through @Autowired, because type matching is not properly applicable to them. Use @Resource for such beans, referring to the specific collection or map bean by unique name.

@Autowired applies to fields, constructors, and multi-argument methods, allowing for narrowing through qualifier annotations at the parameter level. By contrast, @Resource is supported only for fields and bean property setter methods with a single argument. As a consequence, stick with qualifiers if your injection target is a constructor or a multi-argument method.

Share:
264,051
mlo55
Author by

mlo55

Updated on July 08, 2022

Comments

  • mlo55
    mlo55 almost 2 years

    Which annotation, @Resource (jsr250) or @Autowired (Spring-specific) should I use in DI?

    I have successfully used both in the past, @Resource(name="blah") and @Autowired @Qualifier("blah")

    My instinct is to stick with the @Resource tag since it's been ratified by the jsr people.
    Anyone has strong thoughts on this?

  • Snekse
    Snekse over 12 years
    This might see like a silly question, but when you use this style of injection, do you need a public setter for foo or a constructor in SomeBean with a Foo param?
  • Snekse
    Snekse over 12 years
    @Snekse - Got my answer: stackoverflow.com/questions/3536674/…
  • Bozho
    Bozho over 12 years
    nope. You don't need any of that. Just the field. (Spring populates it via reflection)
  • Boris Treukhov
    Boris Treukhov over 11 years
    Yes, this is what should be an accepted answer. For example if you have a @Resource annotated field, and field name matches the id of a bean in container then Spring will throw org.springframework.beans.factory.BeanNotOfRequiredTypeExcep‌​tion if their types differ - this is because beans are first matched by name in @Resource annotation, not by type. But if name of the property doesn't match the name of the bean, then Spring will wire them by type.
  • Boris Treukhov
    Boris Treukhov over 11 years
    @Bozho This answer actually does not show the difference between @Resource and @Autowired, actual answer is the one posted by @Ichthyo, I think this one must be updated.
  • Bozho
    Bozho over 11 years
    yes. In fact I sometimes answer questions by providing a better alternative to the approach. But I included the answer to the original question below, for completeness
  • Stefan Haberl
    Stefan Haberl over 10 years
    +1, because @Autowired with @Qualifier really is more powerful than the JSR standard @Resource annotation (think of optional dependencies for instance with @Autowired(required=false). You can't do that with @Resource)
  • Anver Sadhat
    Anver Sadhat over 10 years
    You can refer the other post that tells the difference between this two when you try to use a simple MAP. stackoverflow.com/questions/13913752/…
  • Jules
    Jules about 10 years
    Note that to use @Inject you need an additional dependency. Maven artifact and/or jar file download can be found here: search.maven.org/…
  • Jules
    Jules about 10 years
    +1 for actually answering the question rather than simply recommending an entirely different "best practice" as the accepted answer does. I also found this blog post, which shows results of several common scenarios with all three annotation styles, helpful: blogs.sourceallies.com/2011/08/…
  • Stephan
    Stephan almost 10 years
    For the reader, please find a summary of the article pointed by @Jules here: stackoverflow.com/a/23887596/363573
  • Ricardo van den Broek
    Ricardo van den Broek almost 9 years
    One implication of this: When you want to inject a Map/List bean, @Autowire can't and won't work. You will have to use @Resource in that case.
  • Daniel Alexiuc
    Daniel Alexiuc over 8 years
    Never gonna happen. And even if it did - doing a find/replace on annotation names is going to be the least of your problems.
  • jayendra bhatt
    jayendra bhatt about 7 years
    @autowire will be by type if it is written over a setter method , if its on the reference then it will be by name.
  • Ilya Serbis
    Ilya Serbis over 5 years
    For the current version see docs.spring.io/spring/docs/current/spring-framework-referenc‌​e/… (the tip was updated)
  • john16384
    john16384 over 3 years
    Since this answer confused me ("... @Resource has a built-in fallback, which kicks in when resolution by-name fails"), I'd like to point out that when using @Resource with a name, it will never ignore the name and fallback to inject something that only matches by type (Spring 5). If you use @Resource without specifying a name, then it does indeed inject by type. I think using @Resource without the name parameter should probably be considered bad practice.