详解原生Spring中的控制反转和依赖注入-构造注入和Set注入

😉😉 学习交流群:

✅✅1:这是孙哥suns给大家的福利!

✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料

🥭🥭3:QQ群:583783824   📚📚  工作微信:BigTreeJava 拉你进微信群,免费领取!

🍎🍎4:本文章内容出自上述:Spring应用课程!💞💞

💞💞5:以上内容,进群免费领取呦~ 💞💞💞💞

文章目录

一:Spring中的注入

1:什么是注入

2:为什么注入

3:如何注入?

4:注入好处

5:Spring注入的过程

​编辑二:Set注入详解

1:JDK内置类型

2:用户自定义类型

(一):第一种方式

(二):第二种方式

3:Set注入简化写法

(一):基于属性的简化

(二):基于p空间简化属性

三:构造注入

1:开发步骤

2:构造方法的重载

3:注入的总结

四:反转控制和依赖注入

1:什么叫做控制反转

2:什么是依赖注入


一:Spring中的注入

1:什么是注入

        注入就是通过Spring的工厂类和spring的配置文件,对Spring所创建的对象进行赋值,为成员变量进行赋值

2:为什么注入

        为什么需要Spring工厂创建对象的时候给对象进行赋值呢?
        1:通过配置文件进行注入也可以实现解耦合的这样的作用,直接写死在代码当中会引发耦合效应
        2:通过编码的方式为成员边量进行赋值会出现耦合,注入的方式会避免这样的耦合的作用

3:如何注入?

    <bean id = "person" class = "com.pactera.spring.Person">
        <!--property标签是复制标签,name属性是对应bean类中的属性。-->
        <property name = "id">
            <value>10</value>
        </property>
        <property name = "name">
            <value>xjr</value>
        </property>
    </bean>

        这是注入的一种示例:为成员变量提供set和get方法,这是注入的第一步

4:注入好处

        使用Spring的依赖注入的好处就是可以基于Spring的配置文件来做对象的成员变量赋值工作,这样不需要在Java代码中显示的给对象成员变量赋值,起到了解耦合的作用!

5:Spring注入的过程

        Spring获取到配置文件路径之后,调用demo4j这个第三方组件来对xml配置文件进行解析,根据解析的内容创建对应的对象。对象创建之后,根据property标签中的配置的属性的值,根据对象的set和get方法进行赋值操作。

        Spring会通过底层属性对应的set方法进行赋值才完成对应的赋值操作,这种方式我们也称为set注入


二:Set注入详解

        针对于不同类型的成员变量,在标签中进行注入的方式也不一样,不过都得嵌套到property标签当中。

        JDK内置类型:JDK自定义的数据类型或者叫引用类型。

        用户自定义类型:用户自定义的类型

1:JDK内置类型

        1、string+8中基本类型。
        <property name = "id">
            <value>10</value>
        </property>
        <property name = "name">
            <value>xjr</value>
        </property>
        2、数组
        <property name="emails">
            <!--这个是为了定义数组-->
            <list>
                <value>suns@pactera.com</value>
                <value>cuilei@pactera.com</value>
                <value>kaixin@pactera.com</value>
            </list>
        </property>
         3、set集合
            <set>
                <!--在这里能用value标签是因为在Set<String>属于八中基本类型和String的范畴。-->
                <value>138111111111</value>
                <!--ref这个标签是给自定义类的注入进行使用的。-->
                <ref bean=""/>
                <!--set集合当中还可以套用set集合-->
                <set>
                </set>
            </set>
        4、list集合
        <property name="address">
            <list >
                <!--这是list集合的写法,list集合是有序的,list集合是可以重复的。-->
                <value>zpark</value>
                <value>shangdi</value>
                <value>xierqi</value>
                <set></set>
                <ref></ref>
                <list></list>
            </list>
        </property>
        5、map集合赋值方式
        <property name="qqs">
            <!--这里是map的写法。-->
            <map>
                <entry>
                    <key><value>suns</value></key>
                    <value>43222222222222</value>
                </entry>
                <entry>
                    <key><value>xiexei</value></key>
                    <value>43222222222222</value>
                </entry>
<!--                <entry>
                    当key或者value是对象的时候
                                        <key><value>zhang</value></key>
                                        <ref bean="">43222222222222</ref>
                                        <key><ref bean="">zhang</ref></key>
                                        <ref bean="">43222222222222</ref>
                </entry>-->
            </map>
        </property>

        properties类型的赋值中更加复杂的JDK类型比如说:date类型需要使用自定义类型转换器进行,这是在工厂的高级部分进行讲解。

2:用户自定义类型

(一):第一种方式

        1:第一步还是为成员变量提供get和set方法
        2:第二步在配置文件中进行注入

        补充说明:
        1:通过这样一种编译时耦合与接口+配置文件中定义注入类型的这样的形式,最大程度上降低了代码的耦合型
        2:这种写法代码冗余,而且会重复创建某个对象。写一个bean标签就会创建一个对象,而且注入的这个对象不可能被复用只能在这个对象中被引用,被注入的对象多次创建就会浪费虚拟机内存的资源

        以下是代码示例:

    /*
     * @Description:给自定义引用类型赋值。
     * @Author: DaShu
     * @Date: 2021/5/28 16:02
     * result:说明配置文件当中这样写可以实现自定义类型的注入。
     */
    //<bean id="userService" class = "com.pactera.spring.UserServiceImpl">
    //    <property name="userDao">
    //        <!--这个dao对象只使用一次,并且不会被其他对象使用。-->
    //        <bean class = "com.pactera.spring.UserDaoImpl"/>
    //    </property>
    //</bean>
    //<bean id="userService" class = "com.pactera.spring.UserServiceImpl">
    //    <property name="userDao">
    //        <ref bean="userDao"/>
    //    </property>
    //</bean>
    //<bean id="userDao" class="com.pactera.spring.UserDaoImpl"></bean>
    //<ref local = "">这个标签从spring4就已经废除了,这个只能引用本配置文件中的bean
    @Test
    public void test11() throws Exception {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
        UserService userService = (UserService)ctx.getBean("userService");
        Class clazz = userService.getClass();
        Field userDao = clazz.getDeclaredField("userDao");
        userDao.setAccessible(true);
        //Object o = userDao.get(userService);
        //System.out.println(o.getClass().getTypeName());//com.pactera.spring.UserDaoImpl
        System.out.println(userDao.getGenericType());
        System.out.println(userDao.getName());
        System.out.println(userDao.get(userService).getClass().hashCode() == UserDaoImpl.class.hashCode());//true
    }
    <bean id="userService" class = "com.pactera.spring.UserServiceImpl">
        <property name="userDao">
            <!--这个dao对象只使用一次,并且不会被其他对象使用。-->
            <bean class = "com.pactera.spring.UserDaoImpl"/>
        </property>
    </bean>

(二):第二种方式


3:Set注入简化写法

(一):基于属性的简化

执行test方法的快捷键是 ctrl+shift+f10
这是jdk类型的注入的形式。
<property name = "name">
    <value = "suns">
</property> 
该类型的简化写法
<property name = "name" value = "suns"/>
用value属性代替value标签。
注意:通过value属性只能简化八中基本类型和String类型。

用户自定义类型:
<property name = "userDao">
    <ref bean = "userDao">
</property> 
<property name= "userDao" ref = "userDao"/>
注意:这种方式只能替换ref属性的形式。

(二):基于p空间简化属性

适用于jdk的类型的简化:

        alt+enter可以导入这个命名空间P的配置,在这个配置当中,有了这个命名空间之后,Property标签就没用了


三:构造注入

        注入:通过Spring的配置文件,为成员变量赋值
        Set注入:Spring通过Set方法,通过配置文件,为成员变量赋值
        构造赋值:Spring通过构造方法,通过配置文件,为成员变量赋值

1:开发步骤

        提供有参构造方法、提供spring的配置文件进行配置

    <bean id = "customer" class="com.pactera.spring.constructor.Customer">
        <!--一个这样的标签对应一个这样的参数。并且顺序还是对应的。-->
        <constructor-arg index="0">
            <value>suns</value>
        </constructor-arg>
        <constructor-arg index="1">
            <value>102</value>
        </constructor-arg>
    </bean>
    /*
     * @Description:用于测试构造工厂
     * @Author: DaShu
     * @Date: 2021/5/31 11:21
     */
    @Test
    public void test13(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
        Customer customer = (Customer) ctx.getBean("customer");
        System.out.println(customer.toString());//Customer{name='suns', age=102}

    }


2:构造方法的重载

        参数的个数不同时通过constructor-arg标签的个数进行区分
        参数相同时,通过在这个标签中引入type标签就可以解决

3:注入的总结

        Set注入 vs  构造注入,未来这两种我们到底是使用什么注入
        1:未来实战:使用set注入会更多,构造注入会更多,有重载,更麻烦,
        2:Spring底层他自己的一些对象的配置,也是使用大量的set的注入,构造注入用的比较少。

四:反转控制和依赖注入

1:什么叫做控制反转

        控制:控制值得是对于对象创建、程序变量赋值的控制权,控制和注入的关系不是并列的关系,控制翻转依赖注入的,注入是控制翻转中的一个环节,例如:直接在代码中完成对于成员边量的赋值,这提高了代码的耦合,这样的控制权是在代码中的,提高了耦合性,将成员变量的赋值权交给Spring工厂和他的配置文件,这样就通过注入的方式,控制权是在Spring上边,解开了耦合性。

        控制反转也就是说:对于对象的创建、对象的成员变量的赋值的权利翻转到spring的工厂和配置文件当中,可以起到解耦合的作用,控制反转的好处解耦合的作用。

        底层实现:工厂设计模式,反射+配置文件

        代码编写中最好的降低耦合性的方式:
        反射+配置文件+耦合月接口,可以把代码的耦合性降低早最低。

2:什么是依赖注入

        通过Spring的工厂和配置文件为对象的成员变量赋值,依赖:我需要你的时候,你就是我的依赖:比如说:Service层中的Dao层的对象,就可以说Service层依赖dao层。Dao层是Service层的依赖。我依赖谁,就可以把他作为成员变量通过,spring的配置文件,创建他的对象,给我注入。好处:解耦合,通过提供set,get方法,最终通过Spring的配置文件完成对象的创建和注入

😉😉 学习交流群:

✅✅1:这是孙哥suns给大家的福利!

✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料

🥭🥭3:QQ群:583783824   📚📚  工作微信:BigTreeJava 拉你进微信群,免费领取!

🍎🍎4:本文章内容出自上述:Spring应用课程!💞💞

💞💞5:以上内容,进群免费领取呦~ 💞💞💞💞

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/197739.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java变量理解

成员变量VS局部变量的区别 语法形式&#xff1a;从语法形式上看&#xff0c;成员变量是属于类的&#xff0c;而局部变量是在代码块或方法中定义的变量或是方法的参数&#xff1b;成员变量可以被 public,private,static 等修饰符所修饰&#xff0c;而局部变量不能被访问控制修饰…

如何高效批量生成条形码?

条形码作为商品、库存和信息管理的基础工具&#xff0c;扮演着至关重要的角色。为了满足用户对于高效、专业、多样化的条形码生成需求&#xff0c;我们推出了一款专业高效的在线条形码生成工具。 网址&#xff1a;https://www.1txm.com/ 多样化条形码支持 易条形支持多种常见…

【算法萌新闯力扣】:旋转链表

力扣题目&#xff1a;旋转链表 开篇 今天是备战蓝桥杯的第25天和算法村开营第3天&#xff01;经过这3天的学习&#xff0c;感觉自己对链表的掌握程度大大地提升&#xff0c;尤其是在帮村里的同学讨论相关问题时。本篇文章&#xff0c;给大家带来一道旋转链表的题目&#xff0c…

leetcode:用队列实现栈(后进先出)

题目描述 题目链接&#xff1a;225. 用队列实现栈 - 力扣&#xff08;LeetCode&#xff09; 题目分析 我们先把之前写的队列实现代码搬过来 用队列实现栈最主要的是实现栈后进先出的特点&#xff0c;而队列的特点是先进先出&#xff0c;那么我们可以用两个队列来实现 一个队…

PTA-6-48 使用面向对象的思想编写程序描述动物

题目&#xff1a; 使用面向对象的思想编写程序描述动物&#xff0c;说明&#xff1a; &#xff08;1) 分析兔子和青蛙的共性&#xff0c;定义抽象的动物类&#xff0c;拥有一些动物共有的属性&#xff1a;名字、颜色、类别&#xff08;哺乳类、非哺乳类&#xff09;&#xff0c…

Redis 事件轮询

1 Redis 为什么快 数据存在内存中, 直接操作内存中的数据单线程处理业务请求避免了多线的上下文切换, 锁竞争等弊端使用 IO 多路复用支撑更高的网络请求使用事件驱动模型, 通过事件通知模式, 减少不必要的等待… 这些都是 Redis 快的原因。 但是这些到了代码层面是如何实现的呢…

出纳常用的月报表,熬夜做了这8份直接用!

做出纳&#xff0c;公司财务的日报表是必不可少的&#xff0c;收支了多少&#xff0c;支出了多少&#xff0c;这些都是要记录下来的&#xff01; 一份出纳日报表通常包含以下内容&#xff1a; 1. 日期&#xff1a;报告涵盖的具体日期&#xff0c;标明是哪一天的财务数据。 2. 收…

【论文阅读】An Experimental Survey of Missing Data Imputation Algorithms

论文地址&#xff1a;An Experimental Survey of Missing Data Imputation Algorithms | IEEE Journals & Magazine | IEEE Xplore 处理缺失数据最简单的方法就是是丢弃缺失值的样本&#xff0c;但这会使得数据更加不完整并且导致偏差或影响结果的代表性。因此&#xff0c;…

bash编程 数组和for循环的应用

bash编程 数组和for循环的应用 1、问题背景2、bash 定义数组3、for循环遍历输出数组所有元素4、编写bash脚本输出每个端口是否在监听状态 1、问题背景 linux服务器开机后&#xff0c;需要检查一组端口是否在监听&#xff0c;以便判断这些端口对应的服务是否在运行。可以考虑使…

别再让假的fiddler教程毒害你了,来看这套最全最新的fiddler全工具讲解

fiddler界面工具栏介绍 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; &#xff08;1&#xff09;WinConfig&#xff1a;windows 使用了一种叫做“AppContainer”的隔离技术&#xff0c;使得一些流量无法正常捕获&#xff0c;在 fiddler中点击 WinConfig…

轻巧高效的剃须好工具,DOCO黑刃电动剃须刀上手

剃须刀大家都用过&#xff0c;我比较喜欢电动剃须刀&#xff0c;尤其是多刀头的悬浮剃须刀&#xff0c;感觉用起来很方便&#xff0c;剃须效率也很高。最近我在用一款DOCO小蔻的黑刃电动剃须刀&#xff0c;这款剃须刀轻巧易用&#xff0c;而且性价比超高。 相比于同类产品&…

深度盘点:100 个 Python 数据分析函数总结

经过一段时间的整理&#xff0c;本期将分享我认为比较常用的100个实用函数&#xff0c;这些函数大致可以分为六类&#xff0c;分别是统计汇总函数、数据清洗函数、数据筛选、绘图与元素级运算函数、时间序列函数和其他函数。 技术交流 技术要学会交流、分享&#xff0c;不建议…

两个mongo表,A和B,以A中的_id记录的为准, 删掉B表中A表中没有的记录

可以使用 MongoDB 的聚合管道和 $lookup 操作符来实现这个需求。以下是一个示例的查询语句,假设集合 A 和集合 B 分别对应表 A 和表 B: db.B.aggregate([{$lookup: {from: "A",localField: "_id",foreignField:

单片机复位电路

有时候我们的代码会跑飞,这个时候基本上是一切推到重来.”推倒重来”在计算机术语上称为复位.复位需要硬件的支持,复位电路就是在单片机的复位管脚上产生一个信号&#xff0c;俗称复位信号.这个信号需要持续一定的时间,单片机收到该信号之后就会复位,从头执行。 复位原理: 那么…

【工业智能】Solutions

各类问题对应的解决方案 工艺参数推荐APC 排产调度智能算法强化学习 运筹优化空压机群控 预测 工艺参数推荐 APC 排产调度 智能算法 遗传算法 强化学习 DDQN 运筹优化 空压机群控 MIP混合整数规划 能耗优化 预测 电池容量预测 时序预测&#xff0c;回归预测 点击剩余…

【Vue】Vue3 配置全局 scss 变量

variables.scss $color: #0c8ce9;vite.config.ts // 全局css变量css: {preprocessorOptions: {scss: {additionalData: import "/styles/variables.scss";,},},},.vue 文件使用

创建一个带有背景图层和前景图层的渲染窗口

开发环境&#xff1a; Windows 11 家庭中文版Microsoft Visual Studio Community 2019VTK-9.3.0.rc0vtk-example demo解决问题&#xff1a; 创建一个带有背景图层和前景图层的渲染窗口&#xff0c;知识点&#xff1a;1. 画布转image&#xff1b;2. 渲染图层设置&#xff1b;3.…

.NET生成微信小程序推广二维码

前言 对于小程序大家可能都非常熟悉了&#xff0c;随着小程序的不断普及越来越多的公司都开始推广使用起来了。今天接到一个需求就是生成小程序码&#xff0c;并且与运营给的推广图片合并在一起做成一张漂亮美观的推广二维码&#xff0c;扫码这种二维码就可以进入小程序。为了…

Python二叉树用法介绍

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 二叉树是一种常见的数据结构&#xff0c;具有树形结构&#xff0c;每个节点最多有两个子节点。Python中有多种方式来表示和操作二叉树&#xff0c;本文将介绍二叉树的基本概念、构建、遍历和一些常见操作&#x…

Opencv-C++笔记 (19) : 分水岭图像分割

文章目录 一、基于距离变换与分水岭的图像分割1、图像分割2、距离和变换与分水岭距离变换常见算法有两种分水岭变换常见的算法 3、距离变换API函数接口4、watershed 分水岭函数API接口步骤 5、代码 一、基于距离变换与分水岭的图像分割 1、图像分割 图像分割(Image Segmentat…