Java程序员必须掌握的Spring依赖管理原理

依赖注入( Dependency Injection
)的意思就是对象通过构造器函数参数,工厂方法的参数,或者成员属性,定义了对象的依赖对象;容器在创建该对象时会负责注入这些依赖。这个过程是控制反转的,即不是由即将创建的对象来管理自己的依赖的发现和实例化,而是有Spring容器来实现。

Spring
中依赖注入有两种形式,第一种就是基于构造函数的注入,即通过调用构造函数,传入参数,也就是依赖来完成整个依赖注入流程;第二种就是基于 setter
方法的注入。

构造函数的参数的匹配,要避免歧义,如指定类型,指定参数的次序等。如果是按照参数名字匹配,则必须开启 debug
模式进行编译,否则参数名字是不保留的。如果不想开启 debug
模式编译,则可以使用 @ConstructorProperties
注解。

setter
方法注入是先调用没有参数的默认构造函数构建对象,或者没有参数的静态工厂方法,实例化 bean
后,调用 setter
方法来将该对象注入。

通过使用依赖注入,可以使代码更简洁,更好地实现对象之间解耦。另外,通过依赖注入管理的的对象是 POJO
类,可以更好地进行测试。

如何选择合适的依赖注入方法?

最佳实践是通过构造器方法注入主要依赖对象,通过 setter
方法注入可选的依赖对象。虽然可以在 setter
方法上加上 @Required
注解来实现主要依赖对象注入,但一般还是推荐使用构造器注入必须的依赖。

使用构造器注入,可以使得应用的组件作为不可变的对象,而且可以保证注入依赖是非 null
的。另外,构造器注入返回的是一个完整的初始状态的实例。但是,一般不推荐大量使用构造方法注入,如果出现这种情况,则说明代码需要重构。

setter
方法适合注入可选的依赖,这些依赖可能有默认值,而且在其他位置使用这些依赖时务必要进行 null
值检查。使用 setter
方法的一个好处是可以修改或者重新配置,或者需要时再注入。如基于 JMX MBean
的管理。

Spring依赖解析流程

首先 ApplicationContext
会被创建和初始化,会加载包括描述所有 bean
的元数据。这些配置元数据可以通过 XML
Java
代码或者注解来指定。

对于每一个 bean
,它的依赖表现形式是成员属性,构造器参数,或者静态工厂方法的参数。在 bean
真正创建时, Spring
容器会提供这些依赖的对象。这些参数可能是需要设置的默认值,也可能是另外一个 bean
的引用。

Spring
容器会验证每个 bean
的配置信息。并且在 bean
真正创建时才设置设置属性值或者参数值。

Spring
中,单例作用域的 bean
会提前初始化,在 Spring
容器创建时就进行了实例化。对于其他的作用域的 bean
,则只在需要时才进行创建。之所以单例作用域的 bean
会被提前初始化,主要是为了解决依赖检查的问题,下文的循环依赖一节会详细说明。

Spring
内部会构建一个创建 bean
的依赖图,按照这依赖关系来创建 Bean

循环依赖解决

如果使用构造函数注入,则不能有循环依赖的情况。如 A
构造器依赖 B
,同时 B
也构造器依赖 A
Spring IoC
容器会在运行时检测到循环依赖,抛 BeanCurrentlyInCreationException
异常。一种解决办法是通过 setter
方法来解决循环依赖的情况。

Spring
会在容器加载时检测配置问题,如引用不存在或者循环依赖。 Spring
会在必要时才解析依赖,即尽可能晚的来解析依赖关系。延迟解析依赖可能导致后期请求获取对象时报错,如抛出一个异常,如丢失指定对象或者属性。这种配置的延迟的可见性导致的问题使得 ApplicationContext
的实现要求单例作用域的 bean
提前记性初始化。虽然会耗费内存和时间,因为并不是按需创建这些单例作用域的 bean
,但是可以在 ApplicationContext
创建时就可以发现配置问题。

下文会介绍通过指定 bean
的可以通过配置来覆盖默认的行为,使得单例作用域的 bean
也是延迟初始化。

如果没有循环依赖存在,则在注入依赖对象时,这些依赖的对象就已经初始化完成了。即如果 A
依赖 B
,则在 A
初始化时, B
已经初始化完成了。也就是说, Bean
是在相关依赖设置完成,并且相关的生命周期方法调用完毕后,才算是完成了初始化。

bean的延迟初始化

默认情况下 ApplicationContext
是提前初始化单例作用域的 bean
,作为 ApplicationContext
初始化的一部分。这样可以尽快的发现配置问题。可以通过指定 bean
lazy-init="true"
,让 bean
在需要时才被初始化。

自动注入依赖

在Spring中可以自动注入依赖,可以减少指定属性或者构造器参数,还可以随着配置对象的变化来更新注入的对象。

自动注入依赖的模式有:通过名称注入,通过类型注入,和通过构造器注入。

原文 

https://juejin.im/post/5cb6a65b6fb9a0689f4c2553

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Java程序员必须掌握的Spring依赖管理原理

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址