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。
在您的代码片段中
第一种方法完全没问题,这是他们获得该方法的标准方法
对象。
在第二种方法中我不确定,但你可能会得到错误,因为你不是
重写 setApplicationContext()
方法。
最后但同样重要的是,在第三种方法中你会得到错误,因为你不是
重写 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)
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。
在您的代码片段中
第一种方法完全没问题,这是他们获得该方法的标准方法 对象。
在第二种方法中我不确定,但你可能会得到错误,因为你不是 重写
setApplicationContext()
方法。最后但同样重要的是,在第三种方法中你会得到错误,因为你不是 重写
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)