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?


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.


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.

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.


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


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.