IOC控制翻转(DI注入)浅谈

1 篇文章 0 订阅
1 篇文章 0 订阅

IOC控制翻转和依赖注入关系

  • IOC的全称为(Inversion of Control),即“控制反转”;DI注入全称(Dependency Injection)依赖注入,二者是同一个事物的不同叫法,两者不是什么技术,而是一种设计思想。在Java开发中,IOC(DI)意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
  • 换句话说是无需在方法内部去New一个新的对象,然后再利用New出来的对象去获取相应的值;而是利用ClassPathXmlApplicationContext(“applicationContext.xml”)属性去自己取得相应的值。
  • 思想转换:由原来的自产自用,变为直接获取使用(从IOC容器中)。

三种常用的依赖注入方式

  • 来用set方法注入(具体实例代码如下:)
    实体类:
public class Teacher {
	private String teacherName;
	private int teacherAge;
	
	public Teacher() {

	}
	public Teacher(String teacherName, int teacherAge) {
		this.teacherName = teacherName;
		this.teacherAge = teacherAge;
	}
	public String getTeacherName() {
		return teacherName;
	}
	public void setTeacherName(String teacherName) {
		System.out.println("调用set方法");
		this.teacherName = teacherName;
	}
	public int getTeacherAge() {
		return teacherAge;
	}
	public void setTeacherAge(int teacherAge) {
		this.teacherAge = teacherAge;
	}
	public void show() {
		System.out.println("name:"+this.teacherName+"--age:"+this.teacherAge);
	}
}

applicationContext.xml文件中的配置:

	<bean id="teacher" class="org.dsl.entity.Teacher"> 
	    <property name="teacherName" value="zhangsan"></property> 
		<property name="teacherAge" value="20"></property> 
	</bean> 

测试结果:
在这里插入图片描述
注:set注入的方式可以存在type类型用于定位给哪个属性赋值,但是必须写全限定类名,如下name="teacherName"属性的赋值:

	<bean id="teacher" class="org.dsl.entity.Teacher"> 
	    <property name="teacherName" value="zhangsan" type="java.lang.String"></property> 
		<property name="teacherAge" value="20"></property> 
	</bean> 
  • 利用构造器注入
    实体类:
//Teacher实体类
public class Teacher {
	private String teacherName;
	private int teacherAge;
	
	public Teacher() {

	}
	//此处为构造方法
	public Teacher(String teacherName, int teacherAge) {
		System.out.println("调用构造方法");
		this.teacherName = teacherName;
		this.teacherAge = teacherAge;
	}
	public String getTeacherName() {
		return teacherName;
	}
	public void setTeacherName(String teacherName) {
		System.out.println("调用set方法");
		this.teacherName = teacherName;
	}
	public int getTeacherAge() {
		return teacherAge;
	}
	public void setTeacherAge(int teacherAge) {
		this.teacherAge = teacherAge;
	}
	public void show() {
		System.out.println("name:"+this.teacherName+"--age:"+this.teacherAge);
	}	
}
---------------------------------------------------------

//Course实体类

public class Course {
	private String courseName;
	private int courseHour;
	private Teacher teacher;
	
	public Course() {
	}
	public Course(String courseName, int courseHour, Teacher teacher) {
		System.out.println("调用Course构造方法");
		this.courseName = courseName;
		this.courseHour = courseHour;
		this.teacher = teacher;
	}
	public String getCourseName() {
		return courseName;
	}
	public void setCourseName(String courseName) {
		this.courseName = courseName;
	}
	public int getCourseHour() {
		return courseHour;
	}
	public void setCourseHour(int courseHour) {
		this.courseHour = courseHour;
	}
	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
	public void show() {
		System.out.println("courseName:"+this.courseName+"--courseHour:"+this.getCourseHour()+
				"--TeacherName:"+this.getTeacher().getTeacherName()+"--TeacherAge:"+this.getTeacher().getTeacherAge());
	}
}

applicationContext.xml文件中的配置:

	<bean id="teacher" class="org.dsl.entity.Teacher">
		<constructor-arg value="20" type="int" index="1" name="teacherAge"></constructor-arg>
		<constructor-arg value="lisi" type="String" index="0" name="teacherName"></constructor-arg>
	</bean>
	
    <bean id="course" class="org.dsl.entity.Course">
      <constructor-arg value="shuxue"></constructor-arg>
      <constructor-arg value="200"></constructor-arg>
       <constructor-arg ref="teacher"></constructor-arg>
    </bean>

注:引用复杂类型使用ref,例如( ref=“teacher”),当构造器中的value不能够确定某个属性时,可以利用type(属性类型)、index(属性顺序)、name(属性名称)三者中的一种或多种,用来定位某个属性,具体如下图所示:
在这里插入图片描述

测试结果:
在这里插入图片描述

  • 利用P命名空间注入
    • 如果安装STS工具,可进行如下操作,将P命名空间引入,如下图所示:
      在这里插入图片描述如上操作完成后,applicationContext.xml中的约束新增如下语句:
      在这里插入图片描述
    • 如果没有安装STS工具,可以直接将下述语句copy上去即可。
      xmlns:p=“http://www.springframework.org/schema/p”
  • applicationContext.xml文件中的配置:
	<bean id="teacher" class="org.dsl.entity.Teacher">
		<constructor-arg value="20" type="int" index="1" name="teacherAge"></constructor-arg>
		<constructor-arg value="lisi" type="String" index="0" name="teacherName"></constructor-arg>
	</bean>
	
    <bean id="course" class="org.dsl.entity.Course" p:courseHour="200" p:courseName="Tianwen" p:teacher-ref="teacher">
    </bean>

如图所示:
在这里插入图片描述

  • 测试结果:
    在这里插入图片描述注:在进行属性赋值时可以有两种方式:
  • property内部赋值:具体的值必须使用双引号“”
	<bean id="teacher" class="org.dsl.entity.Teacher"> 
	    <property name="teacherName" value="zhangsan" type="java.lang.String"></property> 
		<property name="teacherAge" value="20"></property> 
	</bean> 
  • property外部赋值:不使用双引号“”
	<bean id="teacher" class="org.dsl.entity.Teacher"> 
	    <property name="teacherName"> <value>zhangsan</value> </property> 
		<property name="teacherAge" > <value>20</value> </property> 
	</bean> 
  • 当赋空值时参考如下:
<bean id="teacher" class="org.dsl.entity.Teacher"> 
	    <property name="teacherName"> <value></value> </property> 
		<property name="teacherAge" > <value></value> </property> 
	</bean> 
<bean id="teacher" class="org.dsl.entity.Teacher"> 
	    <property name="teacherName" value=""> </property> 
		<property name="teacherAge" value=""> </property> 
	</bean> 
  • 赋值为null时没有value
<bean id="teacher" class="org.dsl.entity.Teacher"> 
	    <property name="teacherName" > <null/> </property> 
		<property name="teacherAge" > <null/> </property> 
	</bean> 

复杂类型赋值

  • applicationContext.xml中的配置:
    <bean id="collection" class="org.dsl.entity.CollectionDemo">
       <property name="listElement">
          <list>
            <value>足球</value>
            <value>篮球</value>
           </list>
       </property>
       <property name="mapElement">
         <map>
            <entry>
               <key>
                  <value>foot</value>
               </key>
               <value>足球</value>
            </entry>
            <entry>
               <key>
                  <value>lanqiu</value>
               </key>
               <value>篮球</value>
            </entry>
         </map>
       </property>
      <property name="array">
        <array>
           <value>足球</value>
           <value>篮球</value>
        </array>
       </property>
      <property name="setElement">
        <set>
           <value>足球</value>
           <value>篮球</value>       
        </set>
       </property>
             <property name="popElement">
        <props>
           <prop key="foot">足球</prop>
           <prop key="basketboll">篮球</prop>
        </props>
       </property>
    </bean>

  • 实体类
package org.dsl.entity;

import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class CollectionDemo {
	private java.util.List<String> listElement;
	private Set<String> setElement;
	private Map<String, Object>  mapElement;
	private String [] array;
	private Properties popElement;
	public java.util.List<String> getListElement() {
		return listElement;
	}
	public void setListElement(java.util.List<String> listElement) {
		this.listElement = listElement;
	}
	public Set<String> getSetElement() {
		return setElement;
	}
	public void setSetElement(Set<String> setElement) {
		this.setElement = setElement;
	}
	public Map<String, Object> getMapElement() {
		return mapElement;
	}
	public void setMapElement(Map<String, Object> mapElement) {
		this.mapElement = mapElement;
	}
	public String[] getArray() {
		return array;
	}
	public void setArray(String[] array) {
		this.array = array;
	}
	public Properties getPopElement() {
		return popElement;
	}
	public void setPopElement(Properties popElement) {
		this.popElement = popElement;
	}
	
	public void show() {
		String strContext = "";
		for (String str : array) {
			strContext+=str+",";	
		}
		System.out.println("listElement:"+this.listElement+"\nsetElement:"
		+this.setElement+"\nmapElement:"+this.mapElement+"\narray:"+strContext+"\npopElement:"+this.popElement);
	}
}

  • 测试代码
package org.dsl.test;
import org.dsl.entity.CollectionDemo;
import org.dsl.entity.Course;
import org.dsl.entity.Teacher;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test {
	public static void main(String[] args) {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		Course course = (Course)context.getBean("course");
		course.show();

	}
}

  • 测试结果

在这里插入图片描述
注:集中复杂类型在applicationContext.xml中的赋值可以相互利用,也不会报错且运行正常,但是最好还是按照响应的类型去匹配使用。

  • 相互使用,即数组中使用List进行赋值,List中用Set赋值,皆不会报错。
  • 正常使用,即按照相应类型使用,数组用array,List使用List,map使用map等。

特殊类型的装配(只适用Bean中存在引用类型)

  • 利用autowire属性进行装配,该属性值包括byName(根据Id名称进行装配)、byType(根据类型进行装配)、constructor(根据构造器进行装配)、default(默认自动选择装配方式)、no(不进行自动装配)
  • applicationContext.xml文件样式:
	<bean id="teacher" class="org.dsl.entity.Teacher"> 
	    <property name="teacherName" value="zhangsan"></property> 
		<property name="teacherAge" value="20"  ></property> 
	</bean> 
	
	<bean id="course" class="org.dsl.entity.Course" autowire="byName">
	  <property name="courseName" value="shuxue"></property> 
	  <property name="courseHour" value="2"></property> 
	  <property name="teacher" ref="teacher"></property> 
	 </bean> 

默认全局自动装配

  • 在applicationContext.xml文件的约束处,进行全局的默认自动装配设置,其中byName属性可替换为byType(根据类型进行装配)、constructor(根据构造器进行装配)、default(默认自动选择装配方式)、no(不进行自动装配)

在这里插入图片描述

利用注解的方式进行装配

  • 进行如下扫描器配置,来查询相应包下的注解,利用相应注解,将属性装配到IOC容器中
    在这里插入图片描述
  • 在applicationContext.xml中配置扫描器,如有多个包要扫描,可以进行逗号分隔。
    在这里插入图片描述
  • 在相应代码层面利用注解进行注册
    在这里插入图片描述

其中@Component(“teacherDao”)等价于
如果存在引用类型例如图片中的StudentDao属性的注入,存在两种方式:
第一种:利用@Autowired(自动装配)来实现,实际工作原理是在springIOC容器中,按照类型为StudentDao的bean进行查找匹配的;
第二种:利用@Autowired+@Qualifier(“bean中的属性名:id”),来实现按照springIOC中的属性Id,进行查找匹配的。
注:Component是较为通用的注解,但是在代码可读性和明确性方面,通常使用@Repository–对应存储层;@Service–对应业务层;@Controller–对应控制层。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值