Spring *感知接口与注入所需对象的好处是什么?

What's the benefit of Spring *Aware interfaces vs. injecting required objects?

Spring 有各种 *Aware 接口,例如。 ApplicationContextAware 为实现者添加了 setter。使用这些接口是否比通过常规 DI 方式(例如构造函数注入)简单地请求依赖项有任何好处。

换句话说,我更喜欢什么时候

@Service
class MyService implements ApplicationContextAware {
    private ApplicationContext applicationContext;

    void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

超过

@Service
class MyService implements ApplicationContextAware {
    private ApplicationContext applicationContext;

    public MyService(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }
}

@Service
class MyService implements ApplicationContextAware {
    @Autowired
    private ApplicationContext applicationContext;
}

3个例子效果一样。 只是有些细微差别,最终还是风格问题。

第一个示例中 - Spring扫描实现某些标记接口的组件,ApplicationContextAware是其中之一,并执行接口的方法DI 运行时在参数中提供的实际 applicationContext 实例。

第二个示例 仅适用于 Spring 4.3 及更高版本。 当您的 bean 具有指定其依赖项的单个构造函数时,即使没有注释,也假定通过构造函数进行依赖注入。

第三个只是通过@Autowired注释进行的简单注入。

对于哪种方式更好,没有简单的答案。 ApplicationContextAware 接口的文档甚至建议,如果您需要 applicationContext 只是为了查找 bean(例如,当您必须使用方法注入技术时),您可能使用其他方法会更好。

总结一下: 第一、第二和第三之间的选择只是在不同 IoC/DI 风格之间的选择,以及是否跳过可选的 @Autowired 注释。

P.S.
您的第二个和第三个示例根本不必实现 ApplicationContextAware 接口。事实上,编译器会抱怨你没有为 ApplicationContect 对象提供 setter。

在您的代码片段中

  1. 第一种方法完全没问题,这是他们获得该方法的标准方法 对象。

  2. 在第二种方法中我不确定,但你可能会得到错误,因为你不是 重写 setApplicationContext() 方法。

  3. 最后但同样重要的是,在第三种方法中你会得到错误,因为你不是 重写 setApplicationContext() 方法。

    如果我们在第三个代码段中覆盖 setApplicationContext(),那么首先是 IOC 容器 注入 null bcoz @Autowired 无法注入 ApplicationContext 对象

    [线程“主”中的异常java.lang.NullPointerException:无法调用 “org.springframework.context.ApplicationContext.getBean(String, java.lang.Class)” 因为“this.ctx”为空]

    然后覆盖 setApplicationContext() 执行,它将以方法 1 的方式注入 ApplicationContext 对象。因此 1 和 3 相同

结论 :: 注入 spring 提供的特殊 propeties/object 像 ApplicationContext 对象我们必须实现 ApplicationContextAware 接口 (XxxAware 各自的接口 properties/object)