java - 了解 Spring @Autowired 的用法

标签 java spring autowired spring-3

我正在阅读 spring 3.0.x 引用文档以了解 Spring Autowired 注解:

3.9.2 @Autowired and @Inject

我无法理解以下示例。我们是否需要在 XML 中做一些事情才能让它工作?

示例 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;
    }

    // ...
}

如何 Autowiring 两个类,实现相同的接口(interface)并使用相同的类?

例子:

class Red implements Color
class Blue implements Color

class myMainClass{
    @Autowired 
    private Color color;

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

将调用哪种设计方法?如何确保调用 Red 类的设计方法而不是 Blue?

最佳答案

TL;DR

@Autowired 注释让您无需自己在 XML 文件中进行接线(或任何其他方式),只需为您找到需要注入(inject)的内容并为您执行此操作.

完整解释

@Autowired 注释允许您跳过其他地方的注入(inject)配置,并为您完成它。假设你的包是 com.mycompany.movi​​es 你必须把这个标签放在你的 XML(应用程序上下文文件)中:

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

此标签将进行自动扫描。假设每个必须成为 bean 的类都使用正确的注释进行注释,例如 @Component(对于简单 bean)或 @Controller(对于 servlet 控件)或 @Repository(对于 DAO 类)并且这些类位于包 com.mycompany.movi​​es 下的某个位置,Spring 将找到所有这些并为每一个。这是在对类的 2 次扫描中完成的——第一次它只是搜索需要成为 bean 的类并映射它需要进行的注入(inject),然后在第二次扫描中注入(inject) bean。当然,您可以在更传统的 XML 文件或 @Configuration 中定义您的 bean。类(或三者的任意组合)。

@Autowired 注释告诉 Spring 需要在哪里进行注入(inject)。如果你把它放在一个方法 setMovieFinder 上,它会理解(通过前缀 set + @Autowired 注释)需要注入(inject)一个 bean。在第二次扫描中,Spring 搜索 MovieFinder 类型的 bean,如果找到这样的 bean,则将其注入(inject)此方法。如果它找到两个这样的 bean,你会得到一个 Exception。为了避免Exception,你可以使用@Qualifier注解并告诉它注入(inject)两个bean中的哪一个,方式如下:

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

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

或者,如果您更喜欢在 XML 中声明 bean,它看起来像这样:

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

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

@Autowired 声明中,您还需要添加 @Qualifier 以告知要注入(inject)两个颜色 bean 中的哪一个:

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

如果您不想使用两个注解(@Autowired@Qualifier),您可以使用 @Resource 将它们组合起来二:

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

@Resource(您可以在此答案的第一条评论中阅读有关它的一些额外数据)使您无需使用两个注释,而是只使用一个。

我将再添加两条评论:

  1. 好的做法是使用 @Inject 而不是 @Autowired 因为它不是 Spring 特定的并且是 part of the JSR-330 standard .
  2. 另一个好的做法是将 @Inject/@Autowired 放在构造函数而不是方法上。如果将其放在构造函数上,则可以验证注入(inject)的 bean 不为空,并在尝试启动应用程序时快速失败,并在需要实际使用 bean 时避免 NullPointerException。<

更新:为了完成图片,我创建了一个 new question关于 @Configuration 类。

关于java - 了解 Spring @Autowired 的用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19414734/

相关文章:

java - Spring Webflow 中的数据绑定(bind)问题

java - Adwords 库中的枚举成员为 null

java - Spring Boot 类 Size 未找到 @Size(min=1,max=18)

java - 更新 JPA 实体中的所有对象

java - web.xml、beans.xml、applicationContext.xml等的区别

jquery - Spring MVC 中的数组作为 PathVariable

spring - 如何使 Spring bean 线程安全

java - 创建名称为 'accountController' 的 bean 时出错

java - FastDateFormat HHmmssS 行为类似于 HHmmSSS

java - 读取 BufferedReader