Spring - @Autowired vs @Resource

I have always had trouble recognizing how spring chooses beans for dependency injection when 2 implementations are available. I have long wondered how @Autowired chooses the beans. While reading about this, I also came across @Resource annotation in the spring docs. I have documented the differences between how each selects the bean.

@Autowired is one the ways we can achieve Dependency Injection in Spring. The same can be used to inject dependencies on setter methods, instance variables and also constructors(constructors don’t have to be public though. It is good practice to make the instance variables final and use contructor injection). In addition, spring also supports @Resource annotation introduced in JSR-250.

We can inject dependencies in the application using both @Autowired and @Resource but there are a couple of differences in how each selects the bean to inject. @Autowired uses AutowiredAnnotationBeanPostProcessor to select the beans while @Resource uses CommonAnnotationBeanPostProcessor.

So I created the below interface with 3 implementations. They are identified by cat, dog, dog1 and I am going to see how to inject one of the dependencies using both @Autowired and @Resource.

public interface Animal {
    String name();
}

@Service(value = "cat")
public class Cat implements Animal{
    @Override public String name(){
        return "Cat";
    }
}

@Service(value = "dog")
public class Dog implements Animal {
    @Override public String name(){
        return "Dog";
    }
}

@Service(value = "dolphin")
public class Dolphin implements Animal{
    @Override public String name(){
        return "Dolphin";
    }
}

Here are my findings. Beans are injected to the interface in the order specified in the table below.

@Autowired @Resource
matches by type matches by name
restricts by qualifier matches by type
matches by name restricts by qualifier

@Autowired
private Animal animal;

This wiring fails with an exception because Spring recognizes 3 dependencies that can be matched to animal and all remaining rules also fail.


We can use @Qualifier annotation to filter the dependencies further.

@Autowired
@Qualifier("cat")
private Animal animal;

@Autowired
private Animal cat;

Another option is to change the variable name to cat in which first 2 rules will fail but the third rule will succeed so that @Autowired will inject Cat object to the variable.


@Resource first maps by the variable name so that the below works.

@Resource
private Animal cat;

It succeeds at the first rule itself, matches by name.


@Resource(name="cat")
private Animal animal;

When using @Resource we don’t need @Qualifier annotation. That functionality is implicity provided by @Resource itself when we provide a value to the argument name.

Here the first rule fails but the second rules succeeds.


I prefer using @Resource annotation with name to inject the correct bean rather than @Autowired with @Qualifier. Also I consider it a good practice to name component/service explicitly. I don’t see any performance improvement of one over the other though but syntax preference. We also have @Inject but it is very similar to @Autowired.

I have attached a source code to play around with. It can be downloaded here.