zoukankan      html  css  js  c++  java
  • spring 依赖注入总结--为什么官方推荐构造器注入

    公司小伙伴使用了构造器注入,说是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找机会.求大佬推荐啊

  • 相关阅读:
    yum报错Python版本不兼容
    MySQL——checkpoint
    MySQL体系结构——内存
    MySQL体系结构——存储引擎
    ORA-00972: identifier is too long 问题处理
    day08面向对象、jsonpath操作、写日志
    day07mock edis加密
    数据库增删改查封装
    day06数据库、发送邮件、操作excel等
    pycharm的使用
  • 原文地址:https://www.cnblogs.com/ydymz/p/10396201.html
Copyright © 2011-2022 走看看