Spring的核心技术(六)---基于Setter的依赖注入

来源:互联网 发布:python ui界面开发 编辑:程序博客网 时间:2024/05/30 05:41

基于Setter方法的依赖注入

容器调用没有参数的构造函数或没有参数的静态工厂方法来创建Bean的实例,然后调用Bean实例上的Setter方法来实现依赖注入。

下面的例子展示了一个只能使用setter方法来注入依赖的类。这是个标准的Java类,它不依赖于容器指定的接口、基类或注解。

public class SimpleMovieLister {
 
    // the SimpleMovieLister has a dependency on the MovieFinder
    private MovieFinder movieFinder;
 
    // a setter method so that the Spring container can inject a MovieFinder
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
 
    // business logic that actually uses the injected MovieFinder is omitted...
 
}

ApplicationContext管理它的Bean时支持基于构造器和基于Setter的依赖注入,也可以同时支持这两种依赖注入方式。以BeanDefinition的形式来配置相关依赖,然后使用这些依赖域PropertyEditor的实例相互协同把相关的属性从一种格式转换成另外的一种格式。但是,大多数的Spring的用户都不会直接(如编程的方式)使用这些类来工作,而是使用XML的Bean定义、注解组件(如使用@Component、@Controller等类注解)、或者基于Java的@Configuration类的@Bean方法。然后这些资源被间接的转化进BeanDefinition的实例中,并全部加载到一个Spring的IoC容器实例中。

如何使用基于构造器和基于Setter的依赖注入

因为基于构造器和基于Setter的依赖注入可以混合使用,所以经验告诉我们,对于强制性依赖使用基于构造器的依赖注入,而可选的依赖使用Setter方法或配置方法是一个好的规则。注意在Setter方法上使用@Required注解能够让相关的属性成为必需的依赖。

Spring团队通常建议使用构造器的方法来完成依赖注入,因为这样能够把应用程序的组件作为不变的对象来实现,并确保必需的依赖不为Null,另外返回给客户端代码的由构造器注入的组件是完全处于初始化状态。还要注意的是,构造器有很多参数不是一个很好的编码习惯,这意味着相关的类肩负了太多的责任,因此需要重构以便让相关的功能适当的分离。

Setter方式的依赖注入应该主要用于可选的依赖,通常要在相关类的内部关联合理的默认值。否则在使用相关依赖的地方一定要执行非空检查。Setter注入的一个好处是后续可以使用Setter方法来重新配置或注入相关依赖。通过JMX MBeans来管理的Bean是一个很好的使用Setter方式注入的案例

依赖注入(DI)的这两种风格对于特殊的类是非常意义的。有些时候,在处理没有源代码的第三方的类的时候,依赖注入的这些风格就会派上用场。例如,如果第三方的类没有公开任何Setter方法,那么构造器注入就是仅有的依赖注入方式。

依赖解析的过程

容器按照下列方式来执行Bean的依赖解析。

1. 创建ApplicationContext,用记录所有Bean的配置元数据来完成初始化。可以通过XML、Java代码或注解来指定配置元数据。

2. 对于每个Bean,它们的依赖是以属性、构造参数、或静态工程方法参数的形式来传递。这些依赖被提供给Bean后,Bean就实际的被创建了。

3. 每个属性或构造器参数是一个实际设置的值的定义,或者指向容器中的另一个Bean。

4. 每个属性或构造器参数的值被从特定的格式转换成属性或构造器参数的实际类型。默认情况下,Spring能够把一个字符串格式的值转换成所有的内置类型,如int、long、String、boolean等。

创建容器时Spring的容器要验证每个Bean的配置。但是相关Bean的属性直到实际创建时才会被设置。在创建容器时,Bean是单作用域且要提前实例化(这是默认设置)。Bean的作用域的定义请看“Bean的作用域”,否则相关的Bean只有在请求时才被创建。Bean的创建会导致Bean的图谱的创建,即创建和关联Bean的依赖以及相关的级联依赖等。需要注意的在Bean的图谱创建的后期可能会出现依赖间的不匹配,这样就会影响到第一个创建的Bean。


0 0
原创粉丝点击