小编典典

了解 Spring @Autowired 的用法

all

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

3.9.2 @Autowired 和
@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;
    }

    // ...
}

两个类如何自动装配实现相同的接口并使用相同的类?

例子:

class Red implements Color
class Blue implements Color

class myMainClass{
    @Autowired 
    private Color color;

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

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


阅读 120

收藏
2022-04-06

共1个答案

小编典典

TL;博士

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

完整解释

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

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

此标签将执行自动扫描。假设每个必须成为 bean 的类都使用正确的注解进行注解,例如@Component(for simple bean) or
@Controller(for a servlet control) or @Repository(for DAOclasses)
并且这些类位于 package 下的某个位置com.mycompany.movies,Spring 将找到所有这些并创建每人一颗豆子。这是在对类的 2
次扫描中完成的——第一次它只是搜索需要成为 bean 的类并映射它需要执行的注入,而在第二次扫描时它会注入 bean。当然,您可以在更传统的 XML
文件中或使用@Configuration类(或三者的任意组合)来定义您的
bean。

@Autowired注释告诉 Spring
需要在哪里进行注入。如果将它放在setMovieFinder它理解(通过前缀set+@Autowired注释)需要注入 bean
的方法上。在第二次扫描中,Spring 搜索类型为 的 bean MovieFinder,如果找到此类 bean,则将其注入此方法。如果它找到两个这样的
bean,你会得到一个Exception. 为避免Exception,您可以使用@Qualifier注解并告诉它要注入两个 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以告知要注入两个颜色 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 特定的并且是标准的一部分JSR-330
  2. 另一个好的做法是将@Inject/@Autowired放在构造函数而不是方法上。如果将它放在构造函数上,则可以验证注入的 bean 不为空,并且在您尝试启动应用程序时快速失败,并避免NullPointerException在您需要实际使用 bean 时。
2022-04-06