五【Spring】控制反转(IOC)

本文介绍了Spring框架如何通过IoC(控制反转)和依赖注入(DI)解决传统项目中的依赖问题。详细讲解了Spring配置文件中的Bean属性、作用域以及基于XML的依赖注入方式,包括设置注入、构造注入和自动注入。通过示例展示了不同作用域的Bean实例化以及如何通过XML配置实现Bean的装配。
摘要由CSDN通过智能技术生成


在这里插入图片描述

✅作者简介: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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值