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的元数据。这些配置元数据可以通过XMLJava代码或者注解来指定。

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

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

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

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

循环依赖解决

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

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

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

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

bean的延迟初始化

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

自动注入依赖

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

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

总结

本文总结了Spring中的依赖管理的基本原理和常见的问题,具体的依赖注入配置语法还需要参考Spring的官方文档来进行。

参考资料

  1. 官方文档-Dependencies

Java程序员必须掌握的Spring依赖管理原理相关推荐

  1. 面向Java程序员的20大Spring REST面试问题答案

    大家好,过去两周来,我一直在与Spring教程共享一些REST,今天,我将向申请Web开发人员角色的Java开发人员共享一些常见的Spring和REST面试问题. 由于Spring Framework ...

  2. Java程序员必会的Spring AOP在实际项目中的应用

    很久没有用过Java的AOP,最近接触到了一个需求,恰好可以用AOP的思想来实现,就此总结一下. 目录 AOP简介 ① pointcut(切入点) ② advice(通知) ③ aspect(切面) ...

  3. Java程序员须知的七个日志管理工具

    本文由 ImportNew - 赖 信涛 翻译自 takipiblog.欢迎加入翻译小组.转载请见文末要求. Splunk vs. Sumo Logic vs. LogStash vs. GrayLo ...

  4. 成都培训Java程序员有前途吗?

    成都培训Java程序员有前途吗?作为培训出身的Java程序员关心自己的前途方向,易牛云朗沃认为大家可以结合自身的知识技术,能力特点来选择发展路线.以当下的互联网发展形式来讲,研发程序员和全栈程序员是较 ...

  5. Java程序员进阶——Spring依赖注入原理分析

    Spring依赖注入原理分析 下面谈谈Spring是如何实现反转模式IOC或依赖注入模式DI: 平时,我们需要生成一个对象,使用new语法,如一个类为A public class A{public v ...

  6. 为什么说 Java 程序员到了必须掌握 Spring Boot 的时候?

    作者:纯洁的微笑(真名:张强),高级 Java 工程师.架构师,GitChat 畅销课程作者.曾从零参与公司技术平台建设,组织平台进行过四次大架构升级.目前在一家第三方支付公司做技术总监,负责微服务架 ...

  7. 作为一名Java程序员,这些Spring知识点面试官常考

    点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! 作者 | 丸纸 来源 | 极客时间 毋庸置疑,Spring 早已成为 Java 后端开发事实 ...

  8. net4.0 程序没反应_@Java程序员,精通Spring,你不得不知道的那些书

    程序员书库(ID:OpenSourceTop)编译 链接:https://www.whizlabs.com/blog/spring-framework-books/ Java是业界最著名的语言之一,不 ...

  9. java面试spring_针对Java程序员的二十大Spring REST面试问题答案

    java面试spring 大家好,过去两周来,我一直在与Spring教程共享一些REST,今天,我将向申请Web开发人员角色的Java开发人员共享一些常见的Spring和REST采访问题. 由于Spr ...

最新文章

  1. java接口的定义及使用细节
  2. 生产环境下JAVA进程高CPU占用故障排查
  3. 已知3个坐标点xy画圆弧_这25张图片,让你彻底看懂25个复杂的数学公式!
  4. 一文简单弄懂tensorflow_【TensorFlow】一文弄懂CNN中的padding参数
  5. .NET Core中间件与依赖注入的一些思考
  6. 【转】ASP.NET MVC生命周期介绍
  7. cf不能全屏win7的解决方法_win10玩cf不能全屏的解决方法教程
  8. M语言中的操作符说明:函数与圆括号()
  9. SHP格式数据点线面无边界坐标生成经纬度边界点集合数据
  10. html梯形选项卡,梯形标签页
  11. 更好地保护眼睛从现在做起!
  12. 翻斗式塑料雨量传感器
  13. chorme浏览器显示“您的浏览器受管理”是被植入病毒或其它程序了吗?
  14. 软件公司绩效考核(大家提提建议)
  15. Apollo搭建使用
  16. 买工业路由器看什么参数
  17. 系统级程序设计第二次作业
  18. echars显示地图
  19. 素人做知识付费,还有没有机会
  20. 拼多多什么是非官方交易行为判定

热门文章

  1. 20145209刘一阳《JAVA程序设计》第1周学习总结
  2. 产品经理业务流程图的绘制流程分享
  3. C++自学笔记(3)
  4. 华为交换机VRP用户界面配置及Telnet登录实验
  5. STL总结之deque
  6. 你还不会小程序啊?手把手带你做第一个和服务器交互的小程序
  7. 快速排序方法——python实现
  8. 关于js的冒泡--新手踩坑案例
  9. 最新LAMP源码搭建网站平台PHP5.5.1 + Apache2.4.6 + mysql5.6.12
  10. Java对象锁和类锁全面解析(多线程synchronized关键字)