Spring *Aware 接口与注入所需对象相比有什么好处?

Aiv*_*var 1 spring dependency-injection applicationcontext

Spring有多种*Aware接口,例如。ApplicationContextAware向实现者添加一个设置者。与简单地通过常规 DI 方式(例如构造函数注入)请求依赖项相比,使用这些接口是否有任何好处?

换句话说,我应该什么时候选择

@Service
class MyService implements ApplicationContextAware {
    private ApplicationContext applicationContext;

    void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
Run Code Online (Sandbox Code Playgroud)

超过

@Service
class MyService implements ApplicationContextAware {
    private ApplicationContext applicationContext;

    public MyService(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }
}
Run Code Online (Sandbox Code Playgroud)

或者

@Service
class MyService implements ApplicationContextAware {
    @Autowired
    private ApplicationContext applicationContext;
}
Run Code Online (Sandbox Code Playgroud)

Paw*_*ski 6

所有 3 个示例具有相同的效果。只是存在一些细微差别,最终还是风格问题。

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

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

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

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

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

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