Understanding Spring @Autowired usage

0 votes

I am reading the spring 3.0.x reference documentation to understand Spring Autowired annotation:

3.9.2 @Autowired and @Inject

I am not able to understand the below examples. Do we need to do something in the XML for it to work?

EXAMPLE 1

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Autowired
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // ...
}

EXAMPLE 2

public class MovieRecommender {

    private MovieCatalog movieCatalog;

    private CustomerPreferenceDao customerPreferenceDao;

    @Autowired
    public void prepare(MovieCatalog movieCatalog,
                    CustomerPreferenceDao customerPreferenceDao) {
        this.movieCatalog = movieCatalog;
        this.customerPreferenceDao = customerPreferenceDao;
    }

    // ...
}

How can the two classes be autowired implementing the same interface and using the same class?

Example:

class Red implements Color
class Blue implements Color

class myMainClass{
    @Autowired 
    private Color color;

    draw(){
        color.design(); 
    } 
}

Which design method will be called? How do I make sure the design method of Red class will be called and not Blue?

Nov 30, 2018 in Java by Daisy
• 8,050 points
335 views

1 answer to this question.

0 votes

TL;DR

The @Autowired annotation spares you the need to do the wiring by yourself in the XML file (or any other way) and just finds for you what needs to be injected where, and does that for you.

Full explanation

The @Autowired annotation allows you to skip configurations elsewhere of what to inject and just does it for you. Assuming your package is com.mycompany.movies you have to put this tag in your XML (application context file):

<context:component-scan base-package="com.mycompany.movies" />

This tag will do an auto-scanning. Assuming each class that has to become a bean is annotated with a correct annotation like @Component (for simple bean) or @Controller (for a servlet control) or @Repository (for DAO classes) and these classes are somewhere under the package com.mycompany.movies, Spring will find all of these and create a bean for each one. This is done in 2 scans of the classes - the first time it just searches for classes that need to become a bean and maps the injections it needs to be doing, and on the second scan it injects the beans. Of course, you can define your beans in the more traditional XML file or with a @Configuration class (or any combination of the three).

The @Autowired annotation tells Spring where an injection needs to occur. If you put it on a method setMovieFinder it understands (by the prefix set + the @Autowired annotation) that a bean needs to be injected. In the second scan, Spring searches for a bean of type MovieFinder, and if it finds such bean, it injects it to this method. If it finds two such beans you will get an Exception. To avoid the Exception, you can use the @Qualifier annotation and tell it which of the two beans to inject in the following manner:

@Qualifier("redBean")
class Red implements Color {
   // Class code here
}

@Qualifier("blueBean")
class Blue implements Color {
   // Class code here
}

Or if you prefer to declare the beans in your XML, it would look something like this:

<bean id="redBean" class="com.mycompany.movies.Red"/>

<bean id="blueBean" class="com.mycompany.movies.Blue"/>

In the @Autowired declaration, you need to also add the @Qualifier to tell which of the two color beans to inject:

@Autowired
@Qualifier("redBean")
public void setColor(Color color) {
  this.color = color;
}

If you don't want to use two annotations (the @Autowired and @Qualifier) you can use @Resource to combine these two:

@Resource(name="redBean")
public void setColor(Color color) {
  this.color = color;
}

The @Resource (you can read some extra data about it in the first comment on this answer) spares you the use of two annotations and instead you only use one.

I'll just add two more comments:

  1. Good practice would be to use @Inject instead of @Autowired because it is not Spring-specific and is part of the JSR-330 standard.
  2. Another good practice would be to put the @Inject / @Autowired on a constructor instead of a method. If you put it on a constructor, you can validate that the injected beans are not null and fail fast when you try to start the application and avoid a NullPointerException when you need to actually use the bean.
answered Nov 30, 2018 by Sushmita
• 6,880 points

Related Questions In Java

0 votes
1 answer

@Autowired annotation in Spring Framework

The @Autowired annotation provides more accurate control over where ...READ MORE

answered Aug 2, 2018 in Java by geek.erkami
• 2,320 points
120 views
0 votes
1 answer
0 votes
1 answer

@Component vs @Repository vs @Service in Spring Framework

As you might be knowing, all these ...READ MORE

answered May 29, 2018 in Java by geek.erkami
• 2,320 points
799 views
0 votes
1 answer

Autowired field pointing NULL in Spring

The field annotated @Autowired is null because ...READ MORE

answered Jun 6, 2018 in Java by avi
• 160 points
5,039 views
0 votes
2 answers

Setting Proxy for JVM usage

JVM uses the proxy to make HTTP ...READ MORE

answered Aug 26 in Java by Sirajul
• 29,340 points
242 views
0 votes
1 answer

Bean life cycle in Spring Bean Factory Container

Bean life cycle in Spring Bean Factory ...READ MORE

answered Aug 29, 2018 in Java by code.reaper12
• 3,450 points
501 views
0 votes
1 answer

How to download a file from spring controllers?

@RequestMapping(value = "/files/{file_name}", method = RequestMethod.GET) public void ...READ MORE

answered Sep 4, 2018 in Java by code.reaper12
• 3,450 points
164 views
0 votes
1 answer

Why is my Spring @Autowired field null?

If you are not coding a web ...READ MORE

answered Dec 27, 2018 in Java by Daisy
• 8,050 points
3,436 views
0 votes
3 answers

How autowiring works in Spring?

First, and most important - all Spring ...READ MORE

answered Jan 11 in Java by developer_1
• 3,300 points
72 views
+1 vote
1 answer

How can I find memory usage of my application in Android?

You can get memory info programmatically and ...READ MORE

answered Jan 10 in Java by Sushmita
• 6,880 points
60 views