1、什么是依赖注入(DI)?

依赖注入(DI)是一个过程,对象之间的依赖关系,即他们的工作与其他对象,只能通过构造函数的参数,一个工厂方法参数或特性,设置在对象实例后,它的构造或从工厂方法返回。然后,容器在创建bean时注入这些依赖项。这个过程基本上是反向的,因此命名为控制反转(IOC),Bean本身通过使用直接构造类或者服务器模式来控制自身的依赖关系的实例化或位置

DI存在两种主要的形式:基于构造函数的依赖注入和基于setter的依赖注入。

2、基于构造函数的依赖注入

基于构造函数的DI是通过调用具有多个参数的构造函数的容器来完成的,每个参数表示依赖关系。

调用static具有特定参数的工厂方法来构造bean几乎是等价的,此讨论类似于对构造函数和静态工厂方法的参数处理。

3、基于构造函数的依赖注入类型

一、基于构造函数里面的参数类型

实体类如下:

package com.spring.mvc;

public class BeanType {
	private String name;
	private int age;
	public BeanType(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String toString() {
		return "BeanType [name=" + name + ", age=" + age +"]";
	}
	
}


xml文件配置如下:

<beans xmlns="http://www.springframework.org/schema/beans" 
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:context="http://www.springframework.org/schema/context" 
	   xmlns:mvc="http://www.springframework.org/schema/mvc"
	   xmlns:tx="http://www.springframework.org/schema/tx"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans 
	   					   http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
						   http://www.springframework.org/schema/context 
						   http://www.springframework.org/schema/context/spring-context-4.3.xsd
		              	   http://www.springframework.org/schema/tx 
						   http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
		              	   http://www.springframework.org/schema/mvc 
		              	   http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
        
    <bean id="beanType" class="com.spring.mvc.BeanType">
	    <constructor-arg type="int" value="21"/>
	    <constructor-arg type="java.lang.String" value="小明"/>
	</bean>

</beans>


测试函数

public static void main(String[] args) {
		//创建ApplicationContext实例,读取spring IOC内容
		ApplicationContext ctx = new ClassPathXmlApplicationContext("springmvc.xml");
		//读取IOC容器中BeanEntity的实例对象
		BeanType be = (BeanType) ctx.getBean(BeanType.class);
		//读取结果
		System.out.println(be.toString());
		
	}

测试结果:

java依赖注入与控制反转 springmvc依赖注入原理_xml

总结:基于构造函数参数类型的依赖注入,在装配的时候如果存在相同的参数类型是无法进行参数装配的

二、基于构造函数参数索引的依赖注入:使用index属性来明确指定构造函数参数的索引

实体类对象:

package com.spring.mvc;

public class BeanIndex {
	
	private String name;
	private int age;
	private String remark;
	public BeanIndex(String name, int age, String remark) {
		super();
		this.name = name;
		this.age = age;
		this.remark = remark;
	}
	public String toString() {
		return "BeanIndex [name=" + name + ", age=" + age + ", remark="
				+ remark + "]";
	}
	
}

xml文件配置如下:

<beans xmlns="http://www.springframework.org/schema/beans" 
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:context="http://www.springframework.org/schema/context" 
	   xmlns:mvc="http://www.springframework.org/schema/mvc"
	   xmlns:tx="http://www.springframework.org/schema/tx"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans 
	   					   http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
						   http://www.springframework.org/schema/context 
						   http://www.springframework.org/schema/context/spring-context-4.3.xsd
		              	   http://www.springframework.org/schema/tx 
						   http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
		              	   http://www.springframework.org/schema/mvc 
		              	   http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
        
    <bean id="beanType" class="com.spring.mvc.BeanType">
	    <constructor-arg type="int" value="21"/>
	    <constructor-arg type="java.lang.String" value="小明"/>
	</bean>
	
	<bean id="beanIndex" class="com.spring.mvc.BeanIndex">
	    <constructor-arg index="0" value="小明"/>
	    <constructor-arg index="1" value="21"/>
	    <constructor-arg index="2" value="小明今年21岁了"/>
	</bean>

</beans>

测试函数:

public static void main(String[] args) {
		//创建ApplicationContext实例,读取spring IOC内容
		ApplicationContext ctx = new ClassPathXmlApplicationContext("springmvc.xml");
		//读取IOC容器中BeanEntity的实例对象
		BeanType be = (BeanType) ctx.getBean(BeanType.class);
		//读取结果
		System.out.println(be.toString());
		System.out.println("=================================");
		//读取IOC容器中BeanEntity的实例对象
		BeanIndex beIndex = (BeanIndex) ctx.getBean(BeanIndex.class);
		//读取结果
		System.out.println(beIndex.toString());
	}



测试结果:

java依赖注入与控制反转 springmvc依赖注入原理_spring_02

总结:如果构造器里面的参数个数很多,得需要一个一个去记住索引,很麻烦!但是解决了多个参数类型相同的依赖注入

三、根据构造函数参数名称进行依赖注入(推荐)

实体类对象:

package com.spring.mvc;

public class BeanName {

	private String name;
	private int age;
	private String remark;
	private String interest;
	public BeanName(String name, int age, String remark, String interest) {
		super();
		this.name = name;
		this.age = age;
		this.remark = remark;
		this.interest = interest;
	}
	public String toString() {
		return "BeanName [name=" + name + ", age=" + age + ", remark=" + remark
				+ ", interest=" + interest + "]";
	}
	
}



xml文件配置:

<beans xmlns="http://www.springframework.org/schema/beans" 
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:context="http://www.springframework.org/schema/context" 
	   xmlns:mvc="http://www.springframework.org/schema/mvc"
	   xmlns:tx="http://www.springframework.org/schema/tx"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans 
	   					   http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
						   http://www.springframework.org/schema/context 
						   http://www.springframework.org/schema/context/spring-context-4.3.xsd
		              	   http://www.springframework.org/schema/tx 
						   http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
		              	   http://www.springframework.org/schema/mvc 
		              	   http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
        
    <bean id="beanType" class="com.spring.mvc.BeanType">
	    <constructor-arg type="int" value="21"/>
	    <constructor-arg type="java.lang.String" value="小明"/>
	</bean>
	
	<bean id="beanIndex" class="com.spring.mvc.BeanIndex">
	    <constructor-arg index="0" value="小明"/>
	    <constructor-arg index="1" value="21"/>
	    <constructor-arg index="2" value="小明今年21岁了"/>
	</bean>
	
	<bean id="beanName" class="com.spring.mvc.BeanName">
	    <constructor-arg name="name" value="小明"/>
	    <constructor-arg name="age" value="21"/>
	    <constructor-arg name="remark" value="小明今年21岁了"/>
	    <constructor-arg name="interest" value="小明喜欢JAVA语言编程"/>
	</bean>

</beans>



测试函数:

public static void main(String[] args) {
		//创建ApplicationContext实例,读取spring IOC内容
		ApplicationContext ctx = new ClassPathXmlApplicationContext("springmvc.xml");
		//读取IOC容器中BeanEntity的实例对象
		BeanType be = (BeanType) ctx.getBean(BeanType.class);
		//读取结果
		System.out.println(be.toString());
		System.out.println("=================================");
		//读取IOC容器中BeanEntity的实例对象
		BeanIndex beIndex = (BeanIndex) ctx.getBean(BeanIndex.class);
		//读取结果
		System.out.println(beIndex.toString());
		System.out.println("=================================");
		//读取IOC容器中BeanEntity的实例对象
		BeanName beName = (BeanName) ctx.getBean("beanName");
		//读取结果
		System.out.println(beName.toString());
	}



测试结果:

java依赖注入与控制反转 springmvc依赖注入原理_spring_03

总结:基于构造器参数名称注入很方便快捷,推荐使用!