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

news2024/9/24 5:23:27

😉😉 学习交流群:

✅✅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:以上内容,进群免费领取呦~ 💞💞💞💞

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

KMP算法【数据结构】

KMP算法 KMP算法是一种改进的字符串匹配算法 Next[j] k :一个用来存放子串返回位置的数组&#xff0c;回溯的位置用字母k来表示。其实就是从匹配失败位置&#xff0c;找到他前面的字符串的最大前后相等子串长度。默认第一个k值为-1(Next[0] -1),第二个k值为0(Next[1] 0),我…

C++ 背包理论基础01 + 滚动数组

背包问题的重中之重是01背包 01背包 有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品只能用一次&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 每一件物品其实只有两个状态&#xff0c;取或者不…

E云管家开发自动转发朋友圈

简要描述&#xff1a; 转发朋友圈&#xff0c;直接xml数据。(对谁不可见) 请求URL&#xff1a; http://域名地址/forwardSns 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参…

手机便签app哪个比较好用?

手机便签类软件的种类是比较多的&#xff0c;不管是安卓手机品牌还是苹果手机品牌的手机&#xff0c;在手机的应用商店中搜索“便签”&#xff0c;大家会找到很多便签类软件。那么&#xff0c;手机便签APP哪个比较好用呢&#xff1f; 在选择手机便签APP时&#xff0c;大家比较…

STM32F103C8T6第7天:

1. 智能小车&#xff1a;让小车动起来&#xff08;360.64&#xff09; 硬件接线 B-2A – PB0B-1A – PB1A-1B – PB2A-1A – PB10其余接线参考上官一号小车项目。 cubemx配置 代码&#xff08;28.smartCar_project1/MDK-ARM&#xff09; 2. 智能小车&#xff1a;串口控制小…

python爬虫进阶教程之如何正确的使用cookie

文章目录 前言一、获取cookie二、程序实现三、动态获取cookie四、其他关于Python爬虫技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料六、Pytho…

自学成为android framework工程师需要准备哪些装备-千里马车载车机系统开发学习

背景 hi&#xff0c;粉丝朋友们&#xff1a; 大家好&#xff01;经常有很多学员买课同学都会问到需要准备哪些装备&#xff0c;我也回答了很多学员了&#xff0c;今天就搞一篇文章来统一说明一下&#xff0c;告诉一下大家如果你想从一个framework新手变成一个framework开发的高…

微服务--04--SpringCloudGateway 网关

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.网关路由1.1 认识网关在SpringCloud当中&#xff0c;提供了两种网关实现方案&#xff1a; 1.2.快速入门1.3.路由过滤 2.网关登录校验2.1.鉴权思路分析2.2.网关过滤…

vue+echarts实现依赖关系无向网络拓扑结图节点折叠展开策略

目录 引言 一、设计 1. 树状图&#xff08;不方便呈现节点之间的关系&#xff0c;次要考虑&#xff09; 2. 力引导依赖关系图 二、力引导关系图 三、如何实现节点的Open Or Fold 1. 设计逻辑 节点展开细节 节点收缩细节 代码实现 四、结果呈现 五、完整代码 引言 我…

使用Kafka、Flink、Druid构建实时数据系统架构

1. 背景 对于很多数据团队来说&#xff0c;要满足实时需求并不容易。为什么&#xff1f;因为作流程&#xff08;数据采集、预处理、分析、结果保存&#xff09;涉及大量等待。等待数据发送到 ETL 工具&#xff0c;等待数据批量处理&#xff0c;等待数据加载到数据仓库中&#…

数据库的增删查改(CRUD)基础版

CRUD: create增加、retrieve查询、update更新、delete删除 注意一点&#xff1a;MySQL对大小写是不敏感的 目录 新增&#xff08;create&#xff09; 全列插入 指定列插入 多行插入 查询&#xff08;Retrieve&#xff09; 列查询 全列查询 指定列查询 表达式查询 …

【蓝桥杯 LCA 差分】 砍树

题目分析&#xff1a; 这道题还是比较裸的一道书上差分的题目了 对于每一对标记点(x,y) 他们之间的路径就是 x − > L C A ( x , y ) − > y x->LCA(x,y)->y x−>LCA(x,y)−>y 这条路径上的每一条边都要经过。 那么对于一条边&#xff0c;什么时候砍掉这条…

网工内推 | 外企网工,五险一金,弹性工作,最高30k*14薪

01 金蝶软件&#xff08;中国&#xff09;有限公司 招聘岗位&#xff1a;网络工程师 职责描述&#xff1a; 1、合理规划公司网络&#xff0c;保障网络架构的合理性、可靠性及前瞻性&#xff1b; 2、负责公司网络运维&#xff0c;处理日常运维事件&#xff0c;保障网络的稳定可…

Leetcode算法系列| 3. 无重复字符的最长子串

目录 1.题目2.题解C# 解法一&#xff1a;滑动窗口算法C# 解法二&#xff1a;索引寻找Java 解法一&#xff1a;滑动窗口算法Java 解法二&#xff1a;遍历字符串 1.题目 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例1: 输入: s "ab…

springboot中4级配置文件优先级

springboot中4级配置文件优先级

C++STL库常用详解与原理

CSTL库 学习方法&#xff1a;使用STL的三个境界&#xff1a;能用&#xff0c;明理&#xff0c;能扩展。 常用库 库名称所需头文件数据结构string#include<string>串vector#include<vector>动态数组list#include<list>带头双向循环链表queue#include<queu…

双馈风机频率二次跌落,永磁风机一次调频火电水电光伏储能直流一次调频,虚拟惯性下垂控制,虚拟同步机VSG控制,二次调频也可继续深入研究

双馈风机(永磁同步风机)虚拟惯性控制下垂控制参与系统一次调频的Matlab/Simulink模型&#xff0c;调频结束后转速回复&#xff0c;造成频率二次跌落SFD。 系统为三机九节点模型&#xff08;可更换为四机两区域&#xff0c;十机39节点&#xff0c;IEEE39节点&#xff0c;IEEE11…

WIN10 x86环境部署ARM虚拟机(银河麒麟)

我们经常使用的是x86架构的cpu&#xff0c;而对于不同cpu架构的arm架构的操作系统&#xff0c;我们可以通过QEMU模拟器来进行模拟一个arm环境 1、部署前的准备 arm的镜像&#xff1a; 以此镜像为例&#xff1a;Kylin-Server-10-SP2-aarch64-Release-Build09-20210524.iso QE…

Codeforces Round #911 (Div. 2)

A.Cover in Water 题意&#xff1a; 有一个 1 n 1 \times n 1n的水池&#xff0c;里面有些格子可以加水&#xff0c;有些格子是被堵上的&#xff0c;你可以进行以下两种操作&#xff1a; 1.往一个空的格子里加水 2.移除一个有水的格子中的水&#xff0c;并将这些水添加到另…