详解原生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@Testpublic 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.UserDaoImplSystem.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*/@Testpublic 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.mzph.cn/news/179177.shtml

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

相关文章

pandas教程:US Baby Names 1880–2010 1880年至2010年美国婴儿姓名

文章目录 14.3 US Baby Names 1880–2010&#xff08;1880年至2010年美国婴儿姓名&#xff09;1 Analyzing Naming Trends&#xff08;分析命名趋势&#xff09;评价命名多样性的增长“最后一个字母”的变革变成女孩名字的男孩名字&#xff08;以及相反的情况&#xff09; 14.3…

Drool 7 SpreadSheet Decision Template 笔记

1 Excel Decision table 1.1 很棒的示意图&#xff0c;来自https://blog.csdn.net/justlpf/article/details/128109731 1.2 参考URL 1.2.1 https://blog.csdn.net/justlpf/article/details/128109731 1.3 多sheet 模式 默认是用第一个sheet如果要支持多sheet&#xff0c;需…

docker限制容器内存的方法

在服务器中使用 docker 时&#xff0c;如果不对 docker 的可调用内存进行限制&#xff0c;当 docker 内的程序出现不可预测的问题时&#xff0c;就很有可能因为内存爆炸导致服务器主机的瘫痪。而对 docker 进行限制后&#xff0c;可以将瘫痪范围控制在 docker 内。 因此&#…

如何运行C/C++程序

一、在线运行C/C 码曰 - 让代码在云端多飞一会&#xff1a;这是一个支持C/C&#xff0c;Java&#xff0c;Python等多种语言的在线编程&#xff0c;编译运行&#xff0c;粘贴分享的平台。你可以在这里输入你的代码&#xff0c;点击运行按钮&#xff0c;就可以看到输出结果。你也…

BGP笔记全

自治系统---AS 定义&#xff1a;由一个单一的机构或者组织所管理的一系列IP网络及其设备所构成的集合。 AS划分的原因 如果整张网络很大&#xff0c;路由数量进一步增加&#xff0c;路由表规模变得太大&#xff0c;会导致路由收敛速度变慢&#xff0c;设备性能消耗加大&#…

智能优化算法应用:基于猫群算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于猫群算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于猫群算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.猫群算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

Kubernetes基础(九)-标签管理

1 概述 Label&#xff08;标签&#xff09;是Kubernetes系统中一个比较重要的概念&#xff0c;给某个资源对象&#xff08;Node、Pod、Service等&#xff09;定义一个Label&#xff0c;就相当于给它打了一个标签&#xff0c;然后可以通过Label Selector&#xff08;标签选择器…

Layui框架弹出框form表单中单选按钮状态不刷新

1、问题描述 如下图&#xff1a;当我们点击编辑按钮的时候&#xff0c;实现如果性别(stu_sex)的值为0男生被选中&#xff0c;如果性别的值为1&#xff0c;女生被选中。但是在使用Layui框架的过程中&#xff0c;发现性别的单选按钮无法实现刷新&#xff0c;使用不正常。 1.1、…

记录:Unity脚本的编写7.0

目录 连接数据库编写脚本查看效果查增删 有段时间没有更新了&#xff0c;现在有点空&#xff0c;就继续写一下unity的脚本&#xff0c;这次就来写一下关于unity连接数据库的内容 连接数据库 无论是什么语言与应用场景&#xff0c;总有一项东西是绕不开的&#xff0c;那就是数据…

使用 ZFPlayer 播放视频的注意点

一 静音功能 通过调用系统的AVPlayer.muted来实现的 - (void)setMuted:(BOOL)muted {_muted muted;self.player.muted muted;if (self.audioMuteChange) {self.audioMuteChange(self, muted);}... }播放进度条 /// 滑杆 property (nonatomic, strong, readonly) ZFSliderV…

Django大回顾-2 之 Django的基本操作、路由层,MTV和MVC模型

【1】MTV和MVC模型 MVC与MTV模型 --->所有web框架其实都遵循mvc架构 MVC模型 MVC 本来坨在一起的代码&#xff0c;拆到不同的位置 模型(M&#xff1a;数据层)&#xff0c;控制器(C&#xff1a;逻辑判断)和视图(V&#xff1a;用户看到的)三层 他们之间以一种插件式…

Gee教程3.实现前缀树路由

需要完成的目标 使用 Trie 树实现动态路由(dynamic route)解析。支持两种模式:name和*filepath&#xff0c;(开头带有:或者*) 这里前缀树的实现修复了Go语言动手写Web框架 - Gee第三天 前缀树路由Router | 极客兔兔​​​​​​ 中路由冲突的bug。 Trie树简介 之前&#xff0…

selenium工作原理详解

一、什么是WebDriver WebDriver提供了另外一种方式与浏览器进行交互。那就是利用浏览器原生的API&#xff0c;封装成一套更加面向对象的Selenium WebDriver API&#xff0c;直接操作浏览器页面里的元素&#xff0c;甚至操作浏览器本身&#xff08;截屏&#xff0c;窗口大小&am…

如何在Ubuntu系统上安装YApi

简单介绍 YApi是高效、易用、功能强大的api管理平台&#xff0c;旨在为开发、产品、测试人员提供更优雅的接口管理服务。可以帮助开发者轻松创建、发布、维护API&#xff0c;YApi还为用户提供了优秀的交互体验&#xff0c;开发人员只需利用平台提供的接口数据写入工具以及简单的…

【从浅识到熟知Linux】基本指令之mkdir

&#x1f388;归属专栏&#xff1a;从浅学到熟知Linux &#x1f697;个人主页&#xff1a;Jammingpro &#x1f41f;每日一句&#xff1a;加油努力&#xff0c;这次写完真的要去干饭了&#xff01; 文章前言&#xff1a;本文介绍mkdir指令用法并给出示例和截图。 文章目录 基本…

ABAP算法 模拟退火

模拟退火算法 算法原理及概念本文仅结合实现过程做简述 模拟退火算法是一种解决优化问题的算法。通过模拟固体退火过程中的原子热运动来寻找全局最优解。在求解复杂问题时&#xff0c;模拟退火算法可以跳出局部最优解获取全局最优解。 模拟退火算法包含退火过程和Metropolis算法…

舞蹈店管理系统服务预约会员小程序效果如何

舞蹈的作用很广&#xff0c;也有大量求学者&#xff0c;每个城市也有大小各异的舞蹈品牌店&#xff0c;他们承接商演、也会教学员、宣传拓展生意等&#xff0c;因此近些年来&#xff0c;随着互联网深入及短视频&#xff0c;舞蹈业市场规模也在增加。 而在门店经营中&#xff0…

Java中关于ArrayList集合的练习题

目录 题目内容​编辑 完整源码 题目内容 根据下图所示数据&#xff0c;定义学生类Student&#xff0c;设置对应的字段并进行封装在Test中&#xff0c;定义ArrayList集合 ,将上述学生对象实例化&#xff0c;并放入集合&#xff0c;定义方法t1&#xff0c;参数为学生类集合&am…

js数组map()的用法

JavaScript Array map() 方法 先说说这个方法浏览器的支持&#xff1a; 支持五大主流的浏览器&#xff0c; 特别注意&#xff1a;IE 9 以下的浏览器不支持&#xff0c;只支持IE 9以上的版本的浏览器 特别注意&#xff1a;IE 9 以下的浏览器不支持&#xff0c;只支持IE 9以上的…

从零开始的c语言日记day37——数组指针练习

一、 取地址数组储存在了*p里&#xff0c;里面储存的是整个数组的地址但本质也是第一个元素的地址解引用后1为4个字节所以就可以打印数组了。但一般不用这种方法 这样更方便一些 打印多维数组 如果不用这样传参&#xff0c;用指针传参怎么做呢&#xff1f; Main里函数的arr表示…