Spring干货集|Bean依赖你又觉得行了?(下)

简介: Spring干货集|Bean依赖你又觉得行了?(下)

2.2 setter注入

通过调用无参构造器或无参静态工厂方法实例化bean后,通过容器在bean上调用setter方法来完成基于setter注入。

如下案例是一个不依赖于特定于容器的接口,基类或注解,而且只能setter注入方式DI的POJO类。

image.png

ApplicationContext为其管理的bean的提供了构造器和setter DI的支持。也支持在已通过构造器注入某些依赖后,还支持setter DI。可通过BeanDefinition的形式配置依赖项,将其与PropertyEditor实例结合使用,以将属性从一种格式转为另一种。但大多数开发者并非以编程方式直接使用这些类,而是使用


XML形式的 bean定义


带注解的组件,即被@Component,@Controller等注解的类


基于Java的@Configuration类中的@Bean方法


然后将这些源在内部转换为BeanDefinition实例,并用于加载整个IoC容器实例。



3 构造器注入还是 setter 注入呢?


这么详细地分别介绍完后,那么到底哪种 DI 方式好呢?

由于可混用构造器和setter DI,因此将构造器用于强制性依赖项,并搭配将setter方法或配置方法用于可选依赖项是个很好的最佳实践。

注意,可在setter方法上使用@Required注解,以使该属性成为必需的依赖;但最好使用带有编程式验证的参数的构造器注入。


而且注意,Spring团队推荐构造器注入,因为它可以让开发者将应用的组件实现为不可变对象,并确保所需的依赖项不为null。此外,构造器注入的组件始终以完全初始化的状态返回给客户端(调用)代码。不过注意了哦,大量的构造器自变量是一种坏代码,因为这意味着该类可能承担了太多职责(违反单一职责的编程原则),应对其重构以更好地解决关注点的解耦问题。


Setter注入主要应仅用于可以在类中分配合理的默认值的可选依赖项。否则,必须在代码使用依赖项的所有地方都执行判空检查。setter注入的一个好处是,setter方法使该类的对象在以后可重新配置或注入。


使用对特定类最有意义的DI方案。有时,在处理没有源代码的第三方类库时,将为你做出选择。例如,若第三方类库未公开任何setter方法,则构造器注入可能就是DI的唯一可用方案咯。



4 deponds-on 属性有何用?



你以为这个东西面试没人问?看图!

image.png

若一个bean是另一个的依赖,则通常意味着将一个bean设为另一个的属性。通常可使用XML形式配置元数据中的<ref/>元素完成此操作。但有时bean之间的依赖关系不那么直接。一个示例是何时需要触发类中的静态初始化器,例如用于数据库驱动程序注册。depends-on属性可显式强制初始化一或多个使用该元素的bean之前的bean。


看如下案例,使用depends-on属性表示对单个bean的依赖关系:

image.png

要表示对多个 bean 的依赖,请提供 bean 名称列表作为依赖属性的值(逗号、空格和分号都是有效的分隔符):

image.png

depends-on属性既可以指定一个 初始化期(initialization-time) 依赖项,也可指定一个对应的析构期(destruction-time)依赖项。在销毁给定bean之前,首先销毁定义与给定bean的依赖关系的依赖bean。因此,depends-on还可以用来控制关闭顺序。



5 lazy-init属性有何作用?



在默认的初始化过程中,ApplicationContext会及早地创建并配置所有的单例bean。一般来说,这种预实例化是有好处的,毕竟相比于若干天后的亡羊补牢,这样可立即发现配置或上下文环境的错误。

当然了,如果你的业务决定了不想要这种默认行为,也可将bean定义标记为延迟初始化来防止对单例bean的预实例化。延迟初始化的bean告诉IoC容器在首次请求时而不是在应用启动阶段就创建一个bean实例。


如下案例:


XML形式,通过<bean/>标签内的lazy-init属性控制

image.png

注解形式

image.png

无需多虑,默认值为true就是要延迟初始化。

image.png

当上述的配置被  ApplicationContext 使用时,在 ApplicationContext 启动时不会预实例化惰性bean,未使用该属性的非惰性bean才会被预实例化。


不过需要注意的是,当lazy-init bean是未lazy-init的单例bean的依赖时,ApplicationContext在启动阶段还是会创建lazy-init bean,因为它必须要满足单例的依赖关系,lazy-init bean会被注入到其它未lazy-init 的单例bean中。


另外如果需要,可通过<bean/>标签内的 default-lazy-init 属性控制容器级别的延迟初始化,案例如下:

image.png

参考

目录
相关文章
|
4天前
|
Java uml Spring
手写spring第四章-完善bean实例化,自动填充成员属性
手写spring第四章-完善bean实例化,自动填充成员属性
13 0
|
21天前
|
Java 应用服务中间件 Spring
Spring系列文章:Bean的作⽤域
Spring系列文章:Bean的作⽤域
|
3天前
|
前端开发 Java 数据格式
【Spring系列笔记】定义Bean的方式
在Spring Boot应用程序中,定义Bean是非常常见的操作,它是构建应用程序的基础。Spring Boot提供了多种方式来定义Bean,每种方式都有其适用的场景和优势。
17 2
|
4天前
|
XML Java 数据格式
手写spring第七章-完成便捷实现bean对象初始化和销毁方法
手写spring第七章-完成便捷实现bean对象初始化和销毁方法
6 0
|
4天前
|
XML Java 数据格式
手写spring第六章-实现应用上下文,完成bean的扩展机制
手写spring第六章-实现应用上下文,完成bean的扩展机制
10 0
|
4天前
|
设计模式 搜索推荐 Java
手写spring第三章-重构,使用依赖关系完善实例化bean操作
手写spring第三章-重构,使用依赖关系完善实例化bean操作
11 0
|
6天前
|
XML 人工智能 Java
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
|
12天前
|
存储 缓存 Java
Spring解决循环依赖
Spring解决循环依赖
|
14天前
|
Java 数据库连接 开发者
浅谈Spring的Bean生命周期
浅谈Spring的Bean生命周期
20 1
|
18天前
|
XML Java 数据格式
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
21 0
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道