了解 Spring @Autowired 的用法 [英] Understanding Spring @Autowired usage

查看:27
本文介绍了了解 Spring @Autowired 的用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读 spring 3.0.x 参考文档以了解 Spring Autowired 注释:

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

3.9.2 @Autowired 和@Inject

我无法理解以下示例.我们需要在 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.movi​​es 你必须把这个标签放在你的 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.movi​​es 包下的某个位置,Spring 会找到所有这些并创建一个 bean每一个.这是在对类的 2 次扫描中完成的 - 第一次它只搜索需要成为 bean 的类并映射它需要执行的注入,然后在第二次扫描时注入 bean.当然,您可以在更传统的 XML 文件中或使用 @Configuration 定义 bean类(或三者的任意组合).

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).

@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来告诉注入两种颜色的bean中的哪一种:

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.

我再补充两条评论:

  1. 好的做法是使用 @Inject 而不是 @Autowired 因为它不是 Spring 特定的,而是 JSR-330 标准的一部分.
  2. 另一个好的做法是将 @Inject/@Autowired 放在构造函数而不是方法上.如果你把它放在构造函数上,你可以验证注入的 bean 不为空,并且在尝试启动应用程序时会快速失败,并在需要实际使用 bean 时避免 NullPointerException.莉>
  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.

更新:为了完成图片,我创建了一个关于<代码的新问题>@Configuration 类.

Update: To complete the picture, I created a new question about the @Configuration class.

这篇关于了解 Spring @Autowired 的用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆