了解Spring @Autowired用法 [英] Understanding Spring @Autowired usage
问题描述
我正在阅读spring 3.0.x参考文档,以了解Spring Autowired注释:
I am reading the spring 3.0.x reference documentation to understand Spring Autowired annotation:
我无法理解以下示例.我们是否需要在XML中做一些工作才能使其正常工作?
I am not able to understand the below examples. Do we need to do something in the XML for it to work?
示例1
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Autowired
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}
示例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?
示例:
class Red implements Color
class Blue implements Color
class myMainClass{
@Autowired
private Color color;
draw(){
color.design();
}
}
将调用哪种设计方法?如何确保Red类的设计方法被调用而不是Blue?
Which design method will be called? How do I make sure the design method of Red class will be called and not Blue?
推荐答案
TL; DR
@Autowired注释使您无需亲自在XML文件中(或任何其他方式)进行连接,而只是为您找到需要注入的内容,然后为您完成.
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.
完整说明
@Autowired
批注允许您跳过要注入的内容的其他配置,而只是为您完成配置.假设您的软件包是com.mycompany.movies
,则必须将此标签放入XML(应用程序上下文文件)中:
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" />
此标签将进行自动扫描.假设必须成为Bean的每个类都用正确的注释(例如@Component
(对于简单bean)或@Controller
(对于servlet控件)或@Repository
(对于DAO
类)进行注释,并且这些类在某处在包com.mycompany.movies
下,Spring将找到所有这些包,并为每个包创建一个bean.这是通过对类的2次扫描完成的-第一次是它仅搜索需要成为bean的类并映射它需要进行的注入,而在第二次扫描中,它将注入bean.当然,您可以在更传统的XML文件中定义bean,也可以使用 @Configuration 类(或三).
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).
@Autowired
注释告诉Spring需要在哪里进行注入.如果将其放在方法setMovieFinder
上,它将理解(通过前缀set
+ @Autowired
批注)需要注入一个bean.在第二次扫描中,Spring搜索类型为MovieFinder
的bean,如果找到了该bean,则将其注入此方法.如果它找到两个这样的bean,您将得到一个Exception
.为了避免Exception
,可以使用@Qualifier
批注,并通过以下方式告诉它要注入两个bean中的哪个:
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
}
或者,如果您更喜欢在XML中声明bean,则看起来像这样:
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"/>
在@Autowired
声明中,您还需要添加@Qualifier
来指示要注入的两个彩色豆中的哪个:
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;
}
如果您不想使用两个注释(@Autowired
和@Qualifier
),则可以使用@Resource
来将这两个注释组合在一起:
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;
}
@Resource
(您可以在此答案的第一个注释中阅读一些有关它的更多数据),从而避免使用两个注释,而只使用一个.
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.
我将再添加两条评论:
- Good practice would be to use
@Inject
instead of@Autowired
because it is not Spring-specific and is part of theJSR-330
standard. - 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 aNullPointerException
when you need to actually use the bean.
更新:为完成图片,我创建了一个有关
Update: To complete the picture, I created a new question about the @Configuration
class.
这篇关于了解Spring @Autowired用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!