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?
Suppose I have a bean named HelloWorld which has a member attribute points to another bean User. With annotation @Autowired, as long as getBean is called in the runtime, the returned HelloWorld instance will automatically have user attribute injected with User instance.
Spring @Autowired annotation is used for automatic dependency injection. Spring framework is built on dependency injection and we inject the class dependencies through spring bean configuration file.
@Bean is just for the metadata definition to create the bean(equivalent to tag). @Autowired is to inject the dependancy into a bean(equivalent to ref XML tag/attribute).
So the answer is: No, @Autowired does not necessarily mean you must also use @Component . It may be registered with applicationContext. xml or @Configuration+@Bean .
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 an @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:
@Inject
instead of @Autowired
because it is not Spring-specific and is part of the JSR-330
standard.@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.Update: To complete the picture, I created a new question about the @Configuration
class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With