当前位置: 首页 > 知识库问答 >
问题:

了解spring@AutoWired的用法

郎正平
2023-03-14

我正在阅读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(); 
    } 
}

将调用哪种设计方法?我如何确保红色类的设计方法会被调用而不是蓝色?

共有2个答案

田嘉慕
2023-03-14

示例中没有提到“实现相同接口的类”。MovieCatalog是一种类型,CustomerPreferenceDao是另一种类型。spring很容易把他们区分开来。

在spring 2.x中,bean的连接主要是通过bean ID或名称实现的。spring 3.x仍然支持这一点,但通常会有一个特定类型的bean实例--大多数服务都是单例。为它们创建名称是很乏味的。于是,spring开始支持“按类型自动驾驶”(autowire by type)。

示例所展示的是您可以用来将bean注入字段、方法和构造函数的各种方法。

XML已经包含了spring需要的所有信息,因为您必须在每个bean中指定完全限定的类名。但是,您需要对接口稍微小心一点:

这种自动连接将会失败:

 @Autowired
 public void prepare( Interface1 bean1, Interface1 bean2 ) { ... }

由于Java不再在字节码中保留参数名,spring再也无法区分这两个bean了。修复方法是使用@qualifier:

 @Autowired
 public void prepare( @Qualifier("bean1") Interface1 bean1,
     @Qualifier("bean2")  Interface1 bean2 ) { ... }
邵胜涝
2023-03-14

DR

@autowired注释使您不必在XML文件中(或任何其他方式)自己进行连接,只需为您找到需要注入的内容并为您完成这些操作。

充分解释

@autowired批注允许您跳过其他地方要注入的内容的配置,而只是为您执行该操作。假设您的包是com.mycompany.movies,您必须将此标记放在XML(应用程序上下文文件)中:

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

此标记将执行自动扫描。假设必须成为bean的每个类都有正确的注释,如@component(对于简单bean)或@controll(对于servlet控件)或@repository(对于DAO类),并且这些类都在com.mycompany.movies包下,spring将找到所有这些,并为每一个创建一个bean。这是在类的两次扫描中完成的--第一次,它只是搜索需要变成豆子的类,并绘制它需要做的注射,在第二次扫描中,它注射豆子。当然,您可以在更传统的XML文件中或使用@configuration类(或三者的任意组合)定义bean。

@autowired注释告诉spring需要在哪里进行注入。如果您将它放在setMovieFinder方法上,它就会理解(通过前缀set+@autowired注释)需要注入一个bean。在第二次扫描中,spring搜索MovieFinder类型的bean,如果找到这样的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不是空的,并且在尝试启动应用程序时快速失败,并且在需要实际使用bean时避免NullPointerException

更新:为了完成图片,我创建了一个关于@configuration类的新问题。

 类似资料:
  • 问题内容: 我正在阅读spring 3.0.x参考文档以了解Spring Autowired注释: 3.9.2 @Autowired和@Inject 我无法理解以下示例。我们需要在XML中做一些工作才能使其工作吗? 例1 例子2 如何自动装配两个类以实现相同的接口并使用相同的类? 例: 将调用哪种设计方法?如何确保Red类的设计方法被调用而不是Blue? 问题答案: TL; DR @Autowir

  • 问题内容: 在Spring会连接的类中使用 @Autowired的 优缺点是什么? 只是为了澄清,我是在专门谈论 @Autowired 注释,而不是XML的自动 装配 。 我可能只是不了解它,但是对我来说,这几乎就像是一种反模式- 您的类开始意识到它们与DI框架相关联,而不仅仅是POJO。也许我是惩罚的嘴,但我喜欢为bean设置外部XML配置,并且我喜欢使用显式的接线,因此我确切知道在哪里接线。

  • 问题内容: 我遇到了一个例子: 我很好奇如何获取集合,因为没有设置方法,而且它是私有的。 问题答案: Java允许上一个字段或方法的访问控制被关断(是的,有一个安全检查到第一通路)经由方法,其是反射框架(二者的一部分Field和从继承)。一旦发现并写入了该字段,其余的工作就变得很简单了。只是一个简单的编程问题。 分享

  • 本文向大家介绍详解Spring @Autowired 注入小技巧,包括了详解Spring @Autowired 注入小技巧的使用技巧和注意事项,需要的朋友参考一下 今天和同事讨论到Spring自动注入时,发现有这么一段代码特别地困惑,当然大致的原理还是可以理解的,只不过以前从来没有这么用过。想到未来可能会用到,或者未来看别人写的代码时不至于花时间解决同样的困惑,所以小编还是觉得有必要研究记录一下。

  • 我正在学习Spring,据我所知,当我们对一个具有泛型名称(而不是setter方法)的方法使用@Annotation时,该方法的参数是自动连线的。

  • 问题内容: 是否通过@Autowired自动检测到?使用@Qualifier时是否按名称进行依赖项注入?我们如何使用这些批注进行setter和构造函数注入? 问题答案: 你可以与一起使用。实际上,如果发现模棱两可的bean类型,spring会询问你是否明确选择了bean,在这种情况下,你应该提供限定符 例如在以下情况下,有必要提供一个限定词 编辑: 在Lombok 1.18.4中,最终可以避免使用