五【Spring】控制反转(IOC)

news2024/12/29 16:23:03

目录

    • 一 Ioc控制反转
        • 1.1 概述
        • 1.2 依赖注入
    • 二 传统依赖的问题
        • 2.1 在传统的项目中
    • 三 引入Spring解决
        • 3.1 Spring配置文件中Bean属性
        • 3.2 Bean的作用域
        • 3.3 项目案例
    • 四 基于xml的依赖注入(注意有参 无参的构建)
        • 4.1 设置注入
        • 4.2 构造注入(依赖有参构造)
        • 4.2 p命名空间注入
        • 4.3 各种数据类型的注入
        • 4.4 自动注入

在这里插入图片描述

✅作者简介:Java-小白后端开发者 🥭公认外号:球场上的黑曼巴

🍎个人主页:不会飞的小飞侠24

🍊个人信条:谨 · 信

💞当前专栏:高级内容

🥭本文内容:JAVA -----mybatis框架【Spring】控制反转(IOC 】

更多内容点击👇
小飞侠的博客>>>>欢迎大家!!!

一 Ioc控制反转

1.1 概述

  • IoC是英文Inversion of Control的缩写,是控制反转的意思,即调用者创建被调用者的实例对象不是由调用者自已完成,而是由Spring容器完成,并注入给调用者。
  • 使用了IoC后,一个对象(调用者)依赖的其它对象(被调用者)会通过被动的方式传递进来,而不是这个对象(调用者)自己创建或者查找依赖对象(被调用者)。spring容器在对象初始化时不等对象请求就主动将依赖对象传递给它。IoC只是一种编程思想,具体的实现方法是依赖注入。

1.2 依赖注入

  • 依赖注入(Dependency Injection,DI)是指程序运行过程中,若需要调用另一个对象协助时,无须在代码中用硬编码(如用new构造方法)创建被调用者,而是依赖于外部容器(如spring),由外部容器创建后传递给程序。依赖注入解决了传统的编程方法中类与类之间严重直接依赖的问题,是目前最优秀的解耦方式。依赖注入让Spring的Bean之间以配置文件的方式组织在一起,而不是以硬编码的方式耦合在一起的。

二 传统依赖的问题

2.1 在传统的项目中

  • 会创建Dao service 结构,通过一个类依赖另外一个,修改时,牵一发 动全身。

引入一个依赖不利的因素

三 引入Spring解决

  • 在项目spring2中导入Spring jar包
    在pom.xml中引入依赖。
  • 创建Spring配置文件apllicationContext.xml,添加约束,实现创建实例化对象的功能。
  • 修改RegisterService类,注释或删除掉regist()方法中创建RegisterDaompl实例的代码。
  • 修改测试类
    <bean id="user" class="cn.syb.spring01.entity.User" >
        <property name="id" value="1"></property>
<!--       property 通过赋值操作,调用set方法-->
        <property name="username" value="tom"></property>
        <property name="password" value="122"></property>
    </bean>

在这里插入图片描述

3.1 Spring配置文件中Bean属性

在这里插入图片描述

3.2 Bean的作用域

  • 当通过Spring容器创建一个Bean 实例时,不仅可以完成Bean的实例化,还可以通过scope属性,为Bean 指定特定的作用域。Spring支持5种作用域。
  • singleton:单例模式。在整个Spring容器中,使用singleton定义的Bean将是单例的,即只有一个实例,第二次以后调用的bean跟第一次调用的是同一个对象,默认为单例的,该Bean是在容器被创建时即被装配好了。
  • prototype:原型模式。即每次使用getBean方法获取的同一个的实例都是一个新的实例。对于 scope为 * * prototype的原型模式,Bean实例是在代码中使用该Bean实例时才进行装配的。
  • request:对于每次HTTP请求,都将会产生一个不同的Bean实例。
  • session:对于每个不同的HTTP session,都将产生一个不同的Bean实例

3.3 项目案例

  • 创建RegisterService类的两个bean,第一个bean的id是regService1,scope属性值是singleton,第二个bean的id是regService2,scope属性值是prototype。测试类中各getBean两次,观察每次获取到的对象是不是同一个对象
 <!-- 相当于在程序中创建一个RegisterDaoImpl类的对象,对象名为registerDao -->
    <bean id="registerDao" class="com.lifeng.dao.RegisterDaoImpl"/>    
    <!-- 相当于在程序中创建一个RegisterService类的对象,对象名为regService1 -->
    <bean id="regService1" class="com.lifeng.service.RegisterService" scope="singleton"> 
    <!-- 相当于为对象regService1中的registerDao属性注入实例 化对象registerDao -->      	
    	<property name="registerDao" ref="registerDao"/>
    </bean> 
     <bean id="regService2" class="com.lifeng.service.RegisterService" scope="prototype"> 
    <!-- 相当于为对象regService2中的registerDao属性注入实例 化对象registerDao -->      	
    	<property name="registerDao" ref="registerDao"/>
    </bean>

Test

	ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
		RegisterService regService11=(RegisterService) context.getBean("regService1");
		RegisterService regService12=(RegisterService) context.getBean("regService1");
		System.out.println("regService11与regService12是否同一个对象:"+(regService11==regService12));	
 
		RegisterService regService21=(RegisterService) context.getBean("regService2");
		RegisterService regService22=(RegisterService) context.getBean("regService2");
		System.out.println("regService21与regService22是否同一个对象:"+(regService21==regService22));

四 基于xml的依赖注入(注意有参 无参的构建)

  • Bean的依赖注入又称为bean的装配,即利用spring实现bean的实例化过程,在这个过程中需完成实例化对象的创建,并给对象的各个属性赋值等任务。Spring有多种bean的装配方式,包括基于xml文件的装配,基于注解的装配,自动装配。
  • 其中基于xml文件的配置又分为两种装配方式:设值注入和构造注入。
  • Spring实例化bean的时候,首先会调用bean的默认的无参构造方法来实例化一个空值的bean对象,接着对Bean对象的属性进行初始化,初始化是由spring容器自动完成的,称为注入

4.1 设置注入

  • 是指Spring通过反射机制调用setter方法来注入属性值,bean必须满足以下两点要求才能被实例化:
  • (1)Bean类必须提供一个无参的构造方法,注意如果程序员定义了有参的构造方法,则必须要显式的提供无参的构造方法。
  • (2)属性需要提供setter方法
<bean id="user2" class="com.lifeng.entity.User">  		
    	<property name="uid">
    		<value>2</value>
    	</property> 
    	<property name="uname">
    		<value>李四</value>
    	</property> 
    	<property name="gender">
    		<value></value>
    	</property>
    	<property name="age">
    		<value>19</value>
    	</property>    	
</bean>	

4.2 构造注入(依赖有参构造)

在constructor-arg 中,利用有参赋值时,注意与实体类属性顺序

<bean id="user3" class="com.lifeng.entity.User">    	
    	<constructor-arg name="uid" value="3"/>
    	<constructor-arg name="uname" value="张无忌"/>
    	<constructor-arg name="gender" value="男"/>
    	<constructor-arg name="age" value="22"/>
</bean>
  • name:指定构造方法中的参数名称。
  • index:指明该参数对应着构造器的第几个参数,从0开始,该属性不要也可,但要注意赋值顺序要与构造器中的参数顺序一致。
  • 如果使用index属性,则用以下代码所示进行注入。
<bean id="user4" class="com.lifeng.entity.User">    	
    	<constructor-arg index="0" value="4"/>
    	<constructor-arg index="1" value="张无忌"/>
    	<constructor-arg index="2" value="男"/>
    	<constructor-arg index="3" value="22"/>
</bean>

4.2 p命名空间注入

  • 使用p命名空间将可以简化属性值的注入。
    (1)首先需要在项目spring4的spring配置文件头中引入p命名空间。
    xmlns:p=“http://www.springframework.org/schema/p”
    (2)在spring配置文件中再添加一个bean,使用p命名空间注入属性值。
 <bean id="user5" class="com.lifeng.entity.User" 
 p:uid="5" p:uname="王五" p:gender="女" p:age="23"/>
  • p 命名空间注入:也是采用设值注入方式,故需要有相应属性的 setter方法,通过上面代码可知,对照普通的设值注入,p命名空间注入简化很多。其基本语法参见表

在这里插入图片描述

4.3 各种数据类型的注入

1.注入常量
使用子节点,将常量(字符串及基本数据类型)值于中间,如5.4.1的设值注入第二种格式所示。也可以不用子节点,而是直接在节点中嵌入value属性,如5.4.1的设值注入第一种格式所示。
注入字符串常量值如果用到以下特殊字符,则需要替换为表5.2对应的表达式。
在这里插入图片描述

2.引用其他Bean组件
Spring中定义的各个bean之间可以互相引用(注入),借于建立依赖关系,可以使用ref属性实现,也可于用子节点实现。
项目案例:新建一个Company类,定义公司的编号,名称,地址属性,修改用户User类,添加一个Company类型的属性,用于设置用户所在的公司。(项目源码见本书配套源码: 第5章/基于xml的依赖注入/spring4)

  • (1)创建两个类   user    +Company  
    
  •  (2)  引入bean 组件
    
  • (3)在user类中引入Company 的bean
    
<bean id="myCompany" class="cn.entity.Company">
	< property name=id>
		<value>1</value>
	</property >
	< property name=company>
		<value>合肥</value>
	</property >
</bean>
<bean id="user" class="cn.entity.user">
	< property name=id>
		<value>1</value>
	</property >
	< property name=user>
		<value>广州</value>
	</property >
	
< property name="company">
		<ref bean="mycompany">
	</property >
</bean>

4.4 自动注入

对于属性的注入,可不在配置文件中注入,通过标签 设置属性autowire属性值,从而为域属性进行隐式自动注入《自动装配》,可分为两种。

byname 名称自动注入
byType 类型自动注入

  1. 当配置文件中被调用者Bean的id值与代码中调用者Bean类的属性名相同时,可使用byName方式,让容器自动将被调用者Bean注入给调用者Bean。容器通过调用者的Bean类的属性名与配置文件的被调用者Bean的id进行比较而实现自动注入。
    项目案例:先创建一个Company类的bean,其id为company,再创建一个User类型的bean,其id为user7, user7这个bean中company属性的注入不再直接引用company,而是改为自动装配。

(1)在项目spring4的spring配置文件中创建Company类的bean,其id为company。

<bean id="company" class="com.lifeng.entity.Company">  		
    	<property name="id">
    		<value>2</value>
    	</property> 
    	<property name="companyname">
    		<value>砺锋软件公司</value>
    	</property> 
    	<property name="address">
    		<value>广州天河建中路</value>
    	</property>    	 	
</bean>

(2)创建一个User类型的bean,采用自动装配。

<bean id="user7" class="com.lifeng.entity.User" autowire="byName">  		
    	<property name="uid">
    		<value>7</value>
	</property>     	<property name="uname">
    		<value>李四</value>
    	</property> 
    	<property name="gender">
    		<value></value>
	</property>     	<property name="age">
    		<value>19</value>
    	</property>  	  	
    </bean>

2 .byType注入是指按类型进行匹配注入,即只要spring容器中有跟域属性类型相同的bean就自动注入,而跟名称无关。使用byType方式自动注入,要满足下面这个条件:配置文件中被调用者bean的class 属性指定的类,要与代码中调用者Bean类的某域属性类型同源,要么相同,要么有 is-a 关系(子类,或是实现类)。但这样的同源的被调用 bean 只能有一个。多于一个,容器就不知该匹配哪一个,从而导致报错。

(1)项目spring4中新建一个bean,id为user8,把装配方式改为byType,其他基本跟user7一样。
<bean id="user8" class="com.lifeng.entity.User" autowire="byType">  		
  <--  省略其他  -->
</bean>

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

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

相关文章

【Java面试总结】MySQL篇·优化篇

【Java面试总结】MySQL篇SQL优化篇1.该如何优化MySQL的查询&#xff1f;2.怎样插入数据才能更高效&#xff1f;3.表中包含几千万条数据该怎么办&#xff1f;4.MySQL的慢查询优化有了解吗&#xff1f;5.说一说你对explain的了解6.explain你一般关注什么&#xff1f;1.该如何优化…

【Linux】网络编程 - Socket套接字/基于UDP的网络通信

目录 一.套接字 1.什么是套接字/Socket套接字 2.套接字的分类 3.Socket套接字的常见API 二.网络字节序 1.什么是网络字节序 2.网络字节序和主机字节序的转换接口 三.IP地址形式上的转换 四.客户端的套接字不由程序员bind 1.为什么客户端套接字不能由程序员bind 2.OS…

【题外话】如何拯救小米11Pro这款工业垃圾

1 背景媳妇用小米11Pro手机&#xff0c;某日不慎摔落&#xff0c;幸好屏幕未碎&#xff0c;然而WiFi却怎样都无法打开&#xff0c;初以为是系统死机&#xff0c;几天依旧故障无法使用。现在的手机没有WiFi功能&#xff0c;就无法刷抖音、看视频&#xff0c;就是鸡肋了。后抽空去…

全栈之路-前端篇 | 第三讲.基础前置知识【前端标准与研发工具】学习笔记

欢迎关注「全栈工程师修炼指南」公众号点击 &#x1f447; 下方卡片 即可关注我哟!设为「星标⭐」每天带你 基础入门 到 进阶实践 再到 放弃学习&#xff01;涉及 企业运维、网络安全、应用开发、物联网、人工智能、大数据 学习知识“ 花开堪折直须折&#xff0c;莫待无花空折…

【2.19】算法题2:贪心算法、动态规划、分治

题目&#xff1a;给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。子数组 是数组中的一个连续部分。方法一&#xff1a;贪心算法原理&#xff1a;若当前指针所指元素之前的和小…

学生和老师-课后程序(JAVA基础案例教程-黑马程序员编著-第四章-课后作业)

【案例4-4】学生和老师 【案例介绍】 1.案例描述 在班级中上课时&#xff0c;老师在讲台上讲课&#xff0c;偶有提问&#xff0c;会点名学生回答问题。虽然老师和学生都在讲话&#xff0c;但讲话的具体内容却不相同。本案例要求使用抽象类的知识编写一个程序实现老师上课的情…

Allegro如何快速清除多余的规则设置操作指导

Allegro如何快速清除多余的规则设置操作指导 在用Allegro做PCB设计的时候,会给PCB设置一些规则,在PCB设计完成之后,可能会有一些没有使用到的规则,如下图 Physical规则中的45OHM的规则是多余的 单独某个规则可以直接在规则管理器中删除,如果比较多可以用下面方法批量删除…

真实景观渲染技巧【Three.js】

受到一些很棒的 three.js 演示、与 covid 相关的旅行禁令以及可能在 pinterest 上花太多时间看美丽的旅行照片的启发——我开始看看我是否可以使用 three.js 和r3f在浏览器中渲染一个令人信服的风景场景。 推荐&#xff1a;将 NSDT场景编辑器 加入你的3D开发工具链。 在过去一个…

AnLogicFPGA设计的时序约束及时序收敛

本篇博文讲了三个内容&#xff1a;时序约束基本概念、时序约束命令、时序收敛技巧 时序约束基本概念 时序设计的实质就是满足每一个触发器的建立&#xff08;setup&#xff09;时间和保持&#xff08;hold&#xff09;时间。 建立时间(Tsu) 触发器的时钟信号沿到来以前&…

零信任-新华三H3C零信任介绍(12)

​目录 ​新华三零信任是什么&#xff1f; 新华三零信任架构特点 新华三零信任架构 新华三零信任架构适用场景 新华三零信任的未来发展展望 新华三零信任是什么&#xff1f; 建立新边界 全面身份化。新华三贯彻“永不信任&#xff0c;始终验证”的原则&#xff0c;通过对…

JavaWeb7-线程状态(生命周期)及转换过程

目录 1.所有线程状态&#xff08;共6种&#xff09; ①NEW-新建状态 ②RUNNABLE-运行状态 RUNNABLE&#xff08;得到时间片运行中状态&#xff09; READY&#xff08;已经保存了上下文&#xff0c;但还未得到时间片的就绪状态&#xff09;。 ③BLOCKED-阻塞状态 ④WAITI…

使用NutUI创建小程序和H5界面

做开发的时间长了&#xff0c;技术都是通用的&#xff0c;创建小程序和H5界面有很多的UI&#xff0c;本章节演示使用NutUI来创建&#xff0c;官网&#xff0c;NutUI - 移动端 Vue3 小程序组件库 1.使用HBuilder X创建一个uni-app的程序&#xff0c;如图所示 2. 安装UniNutUI …

nvm的使用与坑

1、nvm 介绍 Node Version Manager - 符合 POSIX 标准的 bash 脚本&#xff0c;用于管理多个活动的 node.js 版本 官网为 nvm-windows&#xff0c;点击这里进行下载 2、使用场景 比如有几个项目&#xff0c;这些项目的需求都不太一样&#xff0c;导致了这些个项目需要依赖的…

论文投稿指南——中文核心期刊推荐(管理学)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

多彩的声音-课后程序(JAVA基础案例教程-黑马程序员编著-第四章-课后作业)

【案例4-3】多彩的声音 记得 关注&#xff0c;收藏&#xff0c;评论哦&#xff0c;作者将持续更新。。。。 【案例介绍】 案例描述 设计和实现一个Soundable发声接口&#xff0c;该接口具有发声功能&#xff0c;同时还能调节声音大小。 Soundable接口的这些功能将由有3种声音…

【C++的OpenCV】第一课-opencv的介绍和安装(Linux环境下)

第一课-目录一、基本介绍1.1 官网1.2 git源码1.3 介绍二、OpenCV的相关部署工作2.1 Linux平台下部署OpenCV一、基本介绍 1.1 官网 opencv官网 注意&#xff1a;官网为英文版本&#xff0c;可以使用浏览器自带的翻译插件进行翻译&#xff0c;真心不推荐大家去看别人翻译的&am…

vue实现xml在线编辑功能

先看效果 避免误会 这是一个在线编辑器 我们可以在这上面随意的编写xml代码格式 我们修改上面的内容之后 就可以在控制台输出内容 如果这正是您想要的东西 那就可以先创建一个vue项目 我们先引入依赖 npm install brace -S npm install element-ui -S npm install vue-cli…

原型链污染

目录 前置知识 原型对象 prototype和__proto__的区别 原型链概念 原型链的继承 原型 链污染 原型链污染原理 javascript中可能会存在原型链污染的危险函数 原型链污染的实际应用 JavaScript中可以触发弹窗的函数 前置知识 原型对象 在JavaScript中&#xff0c;每个函…

9-静态链表及其有关操作

链表可以用malloc/new和结构体加指针的方式来实现&#xff0c;那种实现方式实现的链表又被称为动态链表。但是我们还可以利用数组的方式来实现一个链表&#xff0c;这种实现方式称为静态链表。 静态单链表 我们知道&#xff0c;一个链表节点主要由两大部分组成&#xff1a;数…

黑马Spring学习笔记(一)——IOC/DI核心概念、入门案例

目录 一、Spring系统架构和学习路线 二、Spring核心概念 2.1 IOC、IOC容器、Bean、DI 2.1.1 IOC&#xff08;Inversion of Control&#xff09;控制反转 2.1.2 DI&#xff08;Dependency Injection&#xff09;依赖注入 2.2 核心概念小结 三、入门案例 3.1 IOC入门…