Spring控制反转

  • IoC(控制反转),即调用者创建被调用者的实例对象不是由调用者自己完成,而是由Spring容器完成。
  • 使用IoC后,一个对象(调用者)依赖其他对象(被调用者)会通过被动的方式传递进来,而不是等这个对象(调用者)自己创建或者查找其他依赖对象(被调用者)。Spring容器在对象初始化时不等对象请求就主动将依赖对象传递给它,具体实现方法是依赖注入。

1.依赖注入

Dao.java

public interface RegisterDao {
	public void regist();
}

public class RegisterDaoImpl implements RegisterDao{

	@Override
	public void regist() {
		// TODO Auto-generated method stub
		System.out.println("注册成功");
	}

}

RegisterService.java

import com.spring2.dao.RegisterDao;
import com.spring2.dao.RegisterDaoImpl;

public class RegisterService {
	public RegisterDao registerDao;
	public void regist() {
		registerDao = new RegisterDaoImpl();//传统方法实例化另一个类,存在直接依赖
		registerDao.regist();
		//省略get,set方法
	}
}

TestRegister.java

import com.spring2.service.RegisterService;

public class TestRegister {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		RegisterService registerService = new RegisterService();
		registerService.regist();
	}
}

RegisterService类在regist()方法中创建RegisterDaoImpl实例化对象,属于RegisterService直接依赖RegisterDaoImpl,如果类RegisterDaoImpl改变,RegisterService中的regist()方法也会改变。

applicationContext.xml添加约束

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<!-- 相当于在程序中创建一个RegisterDaoImpl类的实例化对象,对象名为registerDao -->
	<bean id="registerDao" class="com.spring2.dao.RegisterDaoImpl"></bean>
	<!-- 相当于在程序中创建一个RegisterService类的实例化对象,对象名为regService -->
	<bean id="regService" class="com.spring2.service.RegisterService">
		<!-- 为对象regService中得registerDao属性注入实例化对象registerDao -->
		<property name="registerDao" ref="registerDao" />
	</bean>
</beans>

注释掉RegisterService中得regist()方法

public class RegisterService {
	public RegisterDao registerDao;
	
	public RegisterDao getRegisterDao() {
		return registerDao;
	}
	
	public void setRegisterDao(RegisterDao registerDao) {
		this.registerDao = registerDao;
	}

	public void regist() {
		//registerDao = new RegisterDaoImpl();
		registerDao.regist();
		//省略get,set方法
	}
}

TestRegister.java

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.spring2.service.RegisterService;

public class TestRegister {

	public static void main(String[] args) {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		RegisterService registerService = (RegisterService)applicationContext.getBean("regService");
		registerService.regist();
	}
}
类RegisterService不再直接依赖类RegisterImpl,类RegisterService里面虽然要调用RegisterDaoImpl的实例,但是这个实例不需要RegisterService自己创建,是由配置文件中
<bean id="registerDao" class="com.spring2.dao.RegisterDaoImpl">
创建,然后再创建一个类RegisterService的实例化对象regservice,并为对象regService中的registerDao属性注入实例化对象registerDao

2.Bean属性

Spring控制反转_第1张图片

3.Bean作用域

在这里插入图片描述
Spring控制反转_第2张图片
在Spring配置文件中间添加两个Bean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	<!-- 相当于在程序中创建一个RegisterDaoImpl类的对象,对象名为registerDao -->
	<bean id="registerDao" class="com.spring3.dao.RegisterDaoImpl" />
	<!-- 相当于在程序中创建一个RegisterService类的对象,对象名为regService -->
	<bean id="regService1" class="com.spring3.service.RegisterService"
		scope="singleton">
		<!-- 相当于为对象regService1中的registerDao属性注入实例 化对象registerDao -->
		<property name="registerDao" ref="registerDao" />
	</bean>
	<bean id="regService2" class="com.spring3.service.RegisterService"
		scope="prototype">
		<!-- 相当于为对象regService2中的registerDao属性注入实例 化对象registerDao -->
		<property name="registerDao" ref="registerDao" />
	</bean>

</beans>

Test.java

public class TestRegister {

	public static void main(String[] args) {
		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));
	}

}

PS:当scope属性值为singleton时,每次getBean()获取到的对象都是同一个,属性值为prototype时,每次getBean()方法获取到的对象都是一个新的对象。

4.基于XML的依赖注入

  1. Bean类必须提供一个无参构造方法(如果定义了有参构造方法,则必须显式的提供无参构造方法)
  2. 属性需要提供setter方法
4.1设值注入

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	<!-- 设值注入第一种格式 -->
	<bean id="user1" class="com.spring4.entity.User">
		<property name="uid" value="1" />
		<property name="uname" value="张三" />
		<property name="gender" value="男" />
		<property name="age" value="18" />
	</bean>

	<!-- 设值注入第二种格式 -->
	<bean id="user2" class="com.spring4.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>

</beans>

TestUser1.java

public class TestUser1 {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		User user1 = (User) context.getBean("user1");
		user1.show();
		User user2 = (User) context.getBean("user2");
		user2.show();

	}

}

在这里插入图片描述

4.2构造注入

在构造调用者的同时,完成被调用者的实例化(即使用构造方法进行赋值)

  1. name:指定构造方法中的参数名称
  2. index:指明改参数对应构造器的第几个参数,从0开始,该属性也可以不要,但注意赋值顺序要与构造器中参数顺序一致
	<bean id="user3" class="com.spring4.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>

	<bean id="user4" class="com.spring4.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>

测试方法与TestUser1相同

4.3名称空间注入

在Spring配置文件头中引入p命名空间
在这里插入图片描述

<bean id="user5" class="com.spring4.entity.User" p:uid="4" p:uname="王五" p:gender="女" p:age="23" />

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

4.4各种数据类型注入

创建额外的Bean类

public class School {
	private int id;
	private String schoolname;
	private String address;

	public String toString() {
		return "学校名称:" + schoolname + " ,学校地址:" + address;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getSchoolname() {
		return schoolname;
	}

	public void setSchoolname(String schoolname) {
		this.schoolname = schoolname;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

}

User类中加入School属性和set、get方法

private School school;

	public School getSchool() {
		return school;
	}

	public void setSchool(School school) {
		this.school = school;
	}
<bean id="myschool" class="com.spring4.entity.School">
		<property name="id">
			<value>1</value>
		</property>
		<property name="schoolname">
			<value>LeShanNormalUniversity</value>
		</property>
		<property name="address">
			<value>乐山市市中区滨河路778</value>
		</property>
	</bean>
	
	<bean id="user6" class="com.spring4.entity.User">
		<property name="uid">
			<value>6</value>
		</property>
		<property name="uname">
			<value>李四</value>
		</property>
		<property name="gender">
			<value></value>
		</property>
		<property name="age">
			<value>19</value>
		</property>
		<property name="school">
			<ref bean="myschool" />
		</property>
	</bean>

TestSchool.java

public class TestSchool {

	public static void main(String[] args) {
		ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
		User user6=(User) context.getBean("user6");
		user6.show();
		System.out.println("所在学校:\n"+user6.getSchool());		
	}

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

你可能感兴趣的:(SSM)