基于Setter的依赖注入
通过调用无参数构造函数或无参数静态工厂方法以实例化您的bean之后,容器通过在bean上调用setter方法来完成基于setter的DI。
下面的示例显示只能通过使用纯setter注入来进行依赖项注入的类。 此类是常规的Java。 它是一个POJO,不依赖于特定于容器的接口,基类或注释。
public class SimpleMovieLister {
// SimpleMovieLister依赖于MovieFinder
private MovieFinder movieFinder;
// setter方法,以便Spring容器可以注入MovieFinder
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// 实际使用注入的MovieFinder的业务逻辑被省略...
}
ApplicationContext 支持它管理的bean的基于构造函数和基于setter的DI。在已经通过构造函数方法注入了某些依赖项之后,它还支持基于setter的DI。
您可以以BeanDefinition的形式配置依赖项,将其与PropertyEditor实例结合使用以将属性从一种格式转换为另一种格式。
但是,大多数Spring用户并不直接(即以编程方式)使用这些类,而是使用XML bean定义,带注释的组件(即以**@ Component**,@ Controller 等进行注释的类)或 @Bean方法来处理这些类。 基于Java的**@Configuration类。 然后将这些源在内部转换为BeanDefinition**实例,并用于加载整个Spring IoC容器实例。
基于构造函数或基于setter的DI?
由于可以混合使用基于构造函数的DI和基于设置程序的DI,因此,将构造函数用于强制性依赖项,将setter方法或配置方法用于可选性依赖项是一个很好的经验法则。请注意,可以在setter方法上使用@Required批注,以使该属性成为必需的依赖项。但是,最好使用带有参数的程序验证的构造函数注入。
Spring团队通常提倡构造函数注入,因为它可以让您将应用程序组件实现为不可变对象,并确保所需的依赖项不为null。此外,构造函数注入的组件始终以完全初始化的状态返回到客户端(调用)代码。附带说明一下,大量的构造函数自变量是一种不好的代码味道,这表明该类可能承担了太多的职责,应将其重构以更好地解决关注点分离问题。
Setter注入主要应仅用于可以在类中分配合理的默认值的可选依赖项。否则,必须在代码使用依赖项的任何地方执行非空检查。 setter注入的一个好处是,setter方法使该类的对象在以后可以重新配置或重新注入。因此,通过JMX MBean进行管理是用于setter注入的引人注目的用例。
使用最适合特定班级的DI风格。有时,在处理您没有源代码的第三方类时,将为您做出选择。例如,如果第三方类未公开任何setter方法,则构造函数注入可能是DI的唯一可用形式。