公司小伙伴使用了构造器注入,说是spring的官方推荐。但是,我问了三个问题,他都答不出来,感觉能写篇博文。

官方为什么推荐构造器注入?

构造器注入和属性注入的区别是啥?

你知道有几种注入方式吗?

可以看出当时我问题是由深入浅的,因为这哥们答不上,我只能降低难度了。问完发现然并卵,只是个纠结于规范的人。

那我就从后往前答。

二  注入方式

spring的注入方式就两种 配置注入,注解注入(自动装配)

源码里的beanfactory和xmlbeanfactory

而这两种方式都实现了三种注入方法,访问器注入(setterXXX,newXXX,initXXX等),属性注入(filed),构造器注入(constructor)。

里面花样比较多的是访问器注入,看网上还有静态方法注入,静态工厂注入,初始化注入,本质上就是在一个方法里面注入...

下图为注解注入的三种注入使用简易图。注意仅说明格式,该类使用是错误的,只需一种即可

ps.可以看出这三个注入,访问器和构造器都是一个方法,我们是不是可以是有两种注入?属性注入和方法注入?

那为什么我说三种,其实是基于配置注入区分的。(在自己的类注入,在自己的类注入其他类实例,在自己的类注入 其他类通过访问器生成的实例,没记错应该是这三个求打脸)

但是基于java8支持多注解,spring出了spring-boot,从而把配置丢掉的人不在小数

是的就是我。虽然配置化的项目泛用性强,但是配置一多,重复率比代码还高,所以盲目的追求项目的配置化并不好,spring就把这部分精简到代码里面了

三 注入方法的区别

通过优缺点的对比,相信大家能更加清楚的明白,为什么分三种

1.属性注入

优点:注入简单。简洁明了。(写了这么久代码,我发现简洁明了才是最重要的,语法糖都是异端)

缺点:循环依赖。重名依赖。依赖为空。被多方依赖的可能通过反射修改了内部的值。

2.构造器注入

优点:初始化。不可变性。数据检查,依赖不为空。

缺点:循环依赖。注入的一多就非常的臃肿。

3.访问器注入

优点:通过调用,可以让代码控制类依赖的顺序,解决循环依赖

缺点:注入的一多就非常的臃肿。

先反驳一下循环依赖,@Lazy标签了解下,所以第一个被排除的是访问器注入。而构造器注入和属性注入的循环依赖的报错提示也有点不同,前者编译时就报错,后者使用时报错

再说下重名依赖,@Qualifier标签了解下。

同理依赖为空,你写的代码为什么npe还好意思说是框架的缺点?这三个都是可以通过个人的代码技术解决的所以就放在一起了。

被多方依赖的可能通过反射修改了内部的值,也就是构造器注入的初始化和不可变性,该方法确实在多人协同写代码(调用同一个service时)有很大的帮助

所以简化下我上面说的优缺点,就变成这样

    属性注入                                构造器注入                    访问器注入

优点  简单,可读性高        数据检查;不可变性,多人协同安全  时代的眼泪

缺点  内部属性可变,多人协同出问题 注入多个就臃肿    

四 为什么官方推荐构造器注入 ?

说到底,不可变性,多人协同代码安全,只是菜鸡的自我安慰。国外顶级项目的开发团队,可能还不如我国一个外包项目组的人多。

代码写多了,当你发现周围的老是频繁的改动数据,线程不安全等,最简单的方法是换队友或者单干,因为你的一点点迁就,只会发现他有更多更大的问题。

官方着重的是数据检查,非空检查,循环依赖检查,重名检查等,正如前面说的

构造器注入和属性注入的循环依赖的报错提示也有点不同,前者编译时就报错,后者使用时报错

尽量把错误在编译时就发现才是最好好的开发习惯!机器的可信度远高于人类!(为什么我写这篇文章的原因就是在于此,网上很多相关文章,但是都没有答到点子上)

推荐构造器注入的理由就是这么简单

ps.有兴趣的看下这文章

spring官网文章

访问器注入vs构造器注入和required的使用 https://spring.io/blog/2007/07/11/setter-injection-versus-constructor-injection-and-the-use-of-required/

五 非spring下的属性,构造器和访问器创建对象的对比

这里说的和本篇文章无关,只是兴趣使然,写一写代码优化的思路。

属性是类加载创建对象,构造器是类初始化创建对象,访问器是创建指定对象。

访问器显然是需求指定的实现,不在讨论范围之内。那么属性和构造器呢?

显然加载了不使用,只是在浪费jvm的资源。所以使用构造器创建对象,性能更好。

ps.为什么这个和spring无关?

spring的基础ioc知道吧?所有的spring bean本质上我们都是反射调用,所以无论是构造器还是属性,对象早已被初始化到spring容器之了。

ps.ps 深圳java找机会.求大佬推荐啊

spring 依赖注入总结--为什么官方推荐构造器注入的更多相关文章

  1. 【Spring】浅谈spring推荐构造器注入

    一.前言 ​ Spring框架对Java开发的重要性不言而喻,其核心特性就是IOC(Inversion of Control, 控制反转)和AOP,平时使用最多的就是其中的IOC,我们通过将组件交由S ...

  2. spring in action学习笔记一:DI(Dependency Injection)依赖注入之CI(Constructor Injection)构造器注入

    一:这里先说一下DI(Dependency Injection)依赖注入有种表现形式:一种是CI(Constructor Injection)构造方法注入,另一种是SI(Set Injection) ...

  3. Spring.Net学习笔记(4)-属性及构造器注入

    一.开发环境 操作系统:Win10 编译器:VS2013 .Net版本:.net framework4.5 二.涉及程序集 Spring.Core.dll:1.3.1 Common.Logging.d ...

  4. spring为什么推荐使用构造器注入

    一.前言 ​ 项目中遇到一个问题:项目启动完成前,在A类中注入B类,并调用B类的某个方法. 那么调用B类的这个方法写在哪里呢,我选择写到构造器里,但是构造器先于Spring注入执行,那么执行构造器时, ...

  5. 浅谈spring为什么推荐使用构造器注入

    转载自: https://www.cnblogs.com/joemsu/p/7688307.html 一.前言 ​ Spring框架对Java开发的重要性不言而喻,其核心特性就是IOC(Inversi ...

  6. 【Spring】浅谈spring为什么推荐使用构造器注入

    一.前言 ​ Spring框架对Java开发的重要性不言而喻,其核心特性就是IOC(Inversion of Control, 控制反转)和AOP,平时使用最多的就是其中的IOC,我们通过将组件交由S ...

  7. Spring源码学习笔记9——构造器注入及其循环依赖

    Spring源码学习笔记9--构造器注入及其循环依赖 一丶前言 前面我们分析了spring基于字段的和基于set方法注入的原理,但是没有分析第二常用的注入方式(构造器注入)(第一常用字段注入),并且在 ...

  8. 学习Spring——依赖注入

    前言: 又开始动笔开了“学习Spring”系列的头…… 其实一开始写“学习SpringMVC”的几篇文章是出于想系统的了解下Spring以及SpringMVC,因为平时在公司中虽然每天都在使用Spri ...

  9. [原创]java WEB学习笔记98:Spring学习---Spring Bean配置及相关细节:如何在配置bean,Spring容器(BeanFactory,ApplicationContext),如何获取bean,属性赋值(属性注入,构造器注入),配置bean细节(字面值,包含特殊字符,引用bean,null值,集合属性list map propert),util 和p 命名空间

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

随机推荐

  1. 巧用Scrum与Kanban

    本文来自网易云社区 文\屈鹏飞 在互联网行业的项目管理实践中,敏捷和精益一直是大家所提倡的思想,其中Scrum和Kanban方法作为即敏捷又精益的典型代表,许多PM都在研究,笔者近期也在学习和实施Sc ...

  2. winform发布桌面程序后提示需开启“目录浏览”

    把发布文件里的publish.htm名字改为index.htm就好了

  3. SDUT OJ 数据结构实验之图论六:村村通公路(最小生成树)

    数据结构实验之图论六:村村通公路 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Descri ...

  4. RUCM简介

    一.动机 UCM:用例建模,主要用于结构化和文档需求方面. UCSs:用例规格说明书,通常是文本文档,所以描述中不可避免含有歧义. RUCM:限制性用例建模.目标 G1.使UCMs更加可理解并且更精确 ...

  5. 修剪草坪 单调队列优化dp BZOJ2442

    题目描述 在一年前赢得了小镇的最佳草坪比赛后,Farm John变得很懒,再也没有修剪过草坪.现在,新一轮的最佳草坪比赛又开始了,Farm John希望能够再次夺冠. 然而,Farm John的草坪非 ...

  6. python 3中 的subprocess

    commands好像python3.6被去除了,它现在被subprocess替代了 FUNCTIONS getoutput(cmd) Return output (stdout or stderr) ...

  7. 如何把win10系统迁移到SSD固态硬盘

    https://jingyan.baidu.com/article/5d368d1ec59ac43f60c05733.html 我之前将两个盘都已经固定在笔记本内,迁移完之后无论怎么改还是从原来的机械 ...

  8. C++_异常8-异常、类和基础

    异常.类和继承以三种方式相互关联. 首先,可以像标准C++库所做的那样,从一个异常类派生出另一个. 其次,可以在类定义中嵌套异常类声明来组合异常. 第三,这种嵌套声明本身可以被继承,还可以作为基类. ...

  9. stiff chemistry模型出现NaN错误

    通过定位可以看到,是usr_rates.f中出现了奇异值,因为我的代码中有这样一句话: 而同时我的ConH2在声明后没有赋初值,因此,当X_g(IJK,H2) < c_Limiter后,ConH ...

  10. rest-assured之获取响应数据(Getting Response Data)

    我们使用rest-assured可以获得响应内容,比如:我们发起一个get请求 get("/lotto") 并且获得响应内容,我们有多种方式可以实现: // 通过流的方式获得响应内 ...