【问题标题】:What's the benefit of Spring *Aware interfaces vs. injecting required objects?Spring *Aware 接口与注入所需对象相比有什么好处?
【发布时间】:2020-01-16 12:12:22
【问题描述】:

Spring 有各种*Aware-接口,例如。 ApplicationContextAware 为实现者添加了一个设置器。使用这些接口是否比通过常规 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;
}

【问题讨论】:

    标签: spring dependency-injection applicationcontext


    【解决方案1】:

    所有 3 个示例都具有相同的效果。 只是有一些细微差别,归根结底是风格问题。

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

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

    第三个只是@Autowired注解的普通注入。

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

    总结一下: 1st、2nd 和 3rd 之间的选择只是不同 IoC/DI 风格之间的选择,以及是否跳过可选的 @Autowired 注释。

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

    【讨论】:

      【解决方案2】:

      在您的代码 sn-ps 中

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

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

      3. 最后但并非最不重要的是,在第三种方法中,您将收到错误,因为您不是 覆盖setApplicationContext() 方法。

        如果我们在第三个 sn-p 中覆盖 setApplicationContext(),那么首先是 IOC Container 注入 null bcoz @Autowired 不能注入 ApplicationContext 对象

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

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

      结论 :: 要注入 spring 提供的特殊属性/对象,例如 ApplicationContext 对象,我们必须实现 ApplicationContextAware 交互(XxxAware 接口用于各个属性/对象)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-21
        • 1970-01-01
        • 2010-12-22
        • 2020-01-01
        • 2018-12-22
        • 2014-12-06
        • 1970-01-01
        相关资源
        最近更新 更多