Spring5学习笔记——概述、IOC操作之Bean管理(XML实现之一)

概述

  1. Spring 是轻量级的开源的 JavaEE 框架
  2. Spring 可以解决企业应用开发的复杂性
  3. Spring 有两个核心部分:IOC 和 Aop
    (1)IOC:控制反转,把创建对象的过程交给 Spring 进行管理
    (2)Aop:面向切面,不修改源代码进行功能增强
  4. Spring 特点:
    (1)方便解耦,简化开发
    (2)Aop 编程支持
    (3)方便程序测试
    (4)方便和其他框架进行整合
    (5)方便进行事务操作
    (6)降低 API 开发难度

入门代码

编写一个 Spring 程序:

  1. 下载 Spring 相关的 jar 包。

  2. 导入 Spring 核心 jar 包。
    在这里插入图片描述
    在这里插入图片描述
    Spring 需要依赖 logging 日志包。

  3. 使用 eclipse 编程时,需要安装 Spring 插件。
    在 Help => Eclipse Marketplace => 搜索 sts => 安装下图插件
    在这里插入图片描述

  4. 编写 User.java 类。
    在 com.mcc.spring5 包下

    package com.mcc.spring5;
    
    public class User {
    	public void add() {
    		System.out.println("method add");
    	}
    }
    
  5. 配置 Spring 配置文件,使用 xml 格式。
    注意:Spring 配置文件默认位置在/WEB-INF/下,默认名称为:applicationContext.xml
    新建 Spring Bean Configuration File 文件,名称为:bean1.xml
    在这里插入图片描述
    配置文件内容如下:

    bean1.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">
    
    	<!-- 配置 User 对象 -->
    	<bean id="user" class="com.mcc.spring5.User"></bean>
    	
    </beans>
    

    其中,id 表示所配置对象的别名,class 表示该对象的全类名。

  6. 编写测试代码。
    在 com.mcc.test 包下

    package com.mcc.test;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.mcc.spring5.User;
    
    public class TestSping5 {
    	@Test
    	public void testUser() {
    		//1. 加载 Spring 配置文件
    		ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    		//2. 获取配置文件中创建的对象
    		/*
    		 * getBean(String name, Class clazz)
    		 * 将配置文件中 id = name 
    		 */
    		User user = context.getBean("user", User.class);
    		System.out.println(user);
    		//3. 调用方法
    		user.add();
    	}
    }
    

IOC 容器

原理

  1. 什么是 IOC( Inversion of Control )?
    (1)控制反转,把对象创建和对象之间的调用过程,交给 Spring 进行管理。
    (2)使用 IOC 的目的:为了降低代码间的耦合度。
    (3)入门案例就是 IOC 的实现过程。
  2. IOC 底层原理:
    xml 解析、工厂模式、反射
  3. 图示:
    第一步:spring 配置文件,使用 xml 配置要创建的对象
    在这里插入图片描述
    第二步:假设有 UserService 类和 UserDao 类,UserService 类调用 UserDao 类的方法实现某些功能,因此在UserService 类内要创建 UserDao 类的对象,通过创建工厂类实现。
    在这里插入图片描述

BeanFactory 接口

  1. IOC 思想基于 IOC 容器完成,IOC 容器底层是对象工厂。
  2. Spring 提供两种方式实现 IOC 容器:(两个接口)
    (1)BeanFactory 接口:IOC 容器的最基本实现方式,是 Spring 内部使用的接口,不提供开发人员进行使用
             特点:加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象
    (2)ApplicationContext 接口:BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人员进行使用
             特点:加载配置文件时候就会把在配置文件对象进行创建
  3. ApplicationContext 接口的常用实现类:
    FileSystemXmlApplicationContext 类:加载磁盘上的配置文件
    ClassPathXmlApplicationContext 类:加载 src 文件夹下的配置文件
    AnnotationConfigApplicationContext 类:加载配置类

IOC 操作—Bean 管理

  1. 什么是 Bean 管理?
    Bean 管理指的是两个操作:
    (1)Spring 创建对象
    (2)Spirng 注入属性

  2. Bean 管理的两种方式:
    (1)基于 xml 配置文件方式实现
    (2)基于注解方式实现

基于 xml 配置文件实现

创建对象

创建 Bean 对象,可以在 xml 配置文件中通过 bean 标签实现,bean 标签的属性:

  • id 属性:对象的唯一标识
  • class 属性:对象的全类名
<!-- 配置 User 对象 -->
<bean id="user" class="com.mcc.spring5.User"></bean>

创建对象时,默认执行无参构造器完成对象的创建。

注入属性

DI:依赖注入,就是注入属性。

第一种注入方式:使用 set() 方法进行注入必须要有无参构造器

步骤:
(1)创建类,定义属性和对应的 set() 方法

package com.mcc.spring5;

public class User {
	private int id;
	private String name;
	
	public void setId(int id) {
		this.id = id;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + "]";
	}

	public void show() {
		System.out.println("method show");
	}
}

(2)在 spring 配置文件中注入属性

<!-- 配置 User 对象 -->
<bean id="user" class="com.mcc.spring5.User">
	<!--
		使用 property 标签完成属性注入
		name:类里面属性的名称
		value:向属性注入的值
 	-->
	<property name="id" value="001"></property>
	<property name="name" value="佐助"></property>
</bean>

测试:

@Test
public void testUser() {
	//1. 加载 Spring 配置文件
	ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
	//2. 获取配置文件中创建的对象
	/*
	 * getBean(String name, Class clazz)
	 * 将配置文件中 id = name 
	 */
	User user = context.getBean("user", User.class);
	System.out.println(user);//User [id=1, name=佐助]
	//3. 调用方法
	user.show();//method show
}

第二种注入方式:使用有参构造器进行注入

步骤:
(1)创建类,定义属性和有参构造器

package com.mcc.spring5;

public class Book {
	private String bname;
	private String bauthor;
	
	public Book(String bname, String bauthor) {
		super();
		this.bname = bname;
		this.bauthor = bauthor;
	}

	@Override
	public String toString() {
		return "Book [bname=" + bname + ", bauthor=" + bauthor + "]";
	}
	
	public void show() {
		System.out.println("method show");
	}
}

(2)在 spring 配置文件中注入属性

<!-- 配置 Book 对象 -->
<bean id="book" class="com.mcc.spring5.Book">
	<!--
		使用 有参构造器 进行属性注入时:
		使用 constructor-arg 标签完成属性注入
		name:类里面属性的名称
		value:向属性注入的值
 	-->
	<constructor-arg name="bname" value="西游记"></constructor-arg>
	<constructor-arg name="bauthor" value="施耐庵"></constructor-arg>
</bean>

测试:

@Test
public void testBook() {
	ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
	Book book = context.getBean("book", Book.class);
	System.out.println(book);
	book.show();
}

p 名称空间注入(了解)

简化了 set() 方法注入时的操作,不需要使用 property 标签。

步骤:
(1)在 beans 标签中加入:xmlns:p="http://www.springframework.org/schema/p"
(2)在 bean 标签中使用p:属性="值"完成属性注入

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

	<!-- 配置 User 对象 -->
	<bean id="user1" class="com.mcc.spring5.User" p:id="002" p:name="鸣人"></bean>

</beans>
null 值以及特殊字符的注入
  1. null 值的注入:
    使用<null/>标签实现

    property 标签下:

    <bean id="user2" class="com.mcc.spring5.User">
    	<property name="id" value="003"></property>
    	<property name="name">
    		<null/>
    	</property>
    </bean>
    

    constructor-arg 标签下:

    <bean id="book1" class="com.mcc.spring5.Book">
    	<constructor-arg name="bname" value="Java从入门到精通"></constructor-arg>
    	<constructor-arg name="bauthor">
    		<null/>
    	</constructor-arg>
    </bean>
    
  2. 特殊字符的注入:
    使用转义字符或<![CDATA[]]>实现

    <bean id="book2" class="com.mcc.spring5.Book">
    	<constructor-arg name="bname" value="&lt;数据结构与算法&gt;"></constructor-arg>
    	<constructor-arg name="bauthor">
    		<value><![CDATA[<???>]]></value>
    	</constructor-arg>
    </bean>
    
外部 Bean 的注入

接口:UserDao,UserService
类:UserDaoImpl,UserServiceImpl
UserServiceImpl 类中要使用 UserDaoImpl 对象完成功能的实现,
此时,在 UserServiceImpl 类中引用 UserDaoImpl 对象,就是外部Bean 的注入。

UserDao.java

package com.mcc.spring5.dao;

public interface UserDao {
	public void update();
}

UserService.java

package com.mcc.spring5.service;

public interface UserService {
	public void add();
}

UserDaoImpl.java

package com.mcc.spring5.dao;

public class UserDaoImpl implements UserDao{

	@Override
	public void update() {
		System.out.println("dao update");
	}

}

UserServiceImpl.java

package com.mcc.spring5.service;

import com.mcc.spring5.dao.UserDao;

public class UserServiceImpl implements UserService{
	
	private UserDao userDao;
	
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	@Override
	public void add() {
		System.out.println("service add");
		userDao.update();
	}
	
}

Spring 配置文件 bean2.xml

使用 property 标签 或 constructor-arg 标签的 ref 属性完成

  • name 属性:对象的属性名
  • ref 属性:需要注入的 Bean 对象的 id 值
<?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">
	
	<!-- 配置 UserDaoImpl 对象 -->
	<bean id="userDaoImpl" class="com.mcc.spring5.dao.UserDaoImpl"></bean>
	
	<!-- 配置 UserServiceImpl 对象 -->
	<bean id="userServiceImpl" class="com.mcc.spring5.service.UserServiceImpl">
		<!-- 
			注入外部Bean
			name 属性:对象的属性名
			ref 属性:需要注入的 Bean 对象的 id 值
		-->
		<!-- 注入 UserDaoImpl 对象 -->
		<property name="userDao" ref="userDaoImpl"></property>
	</bean>

</beans>

测试

public class TestRefBean {
	
	@Test
	public void testUserService() {
		ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
		UserService userService = context.getBean("userServiceImpl", UserService.class);
		userService.add();
		//service add
		//dao update
	}
}
内部 Bean 的注入

类:Department、Employee
一个部门有多个员工,一个员工只属于一个部门

Department.java

package com.mcc.spring5.bean;

public class Department {
	private String dname;

	public void setDname(String dname) {
		this.dname = dname;
	}

	@Override
	public String toString() {
		return "Department [dname=" + dname + "]";
	}
	
}

Employee.java

package com.mcc.spring5.bean;

public class Employee {
	private String ename;
	private String gender;
	private Department dept;
	
	public void setEname(String ename) {
		this.ename = ename;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	public void setDept(Department dept) {
		this.dept = dept;
	}
	
	public Department getDept() {
		return dept;
	}
	
	public void show() {
		System.out.println(ename + "::" + gender + "::" + dept.toString());
	}
	
}

Spring 配置文件 bean3.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">
	
	<!-- 创建 Employee 对象 -->
	<bean id="employee" class="com.mcc.spring5.bean.Employee">
		<property name="ename" value="张三"></property>
		<property name="gender" value=""></property>
		<property name="dept">
			<!-- 内部Bean实现 -->
			<bean id="department" class="com.mcc.spring5.bean.Department">
				<property name="dname" value="技术部"></property>
			</bean>
		</property>
	</bean>

</beans>

测试

public class TestInnerBean {
	
	@Test
	public void testEmployee {
		ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
		Employee employee = context.getBean("employee", Employee.class);
		employee.show();//张三::男::Department [dname=技术部]
	}
}
级联赋值

第一种方式:

<!-- 级联赋值 方式1 -->
<!-- 创建 Employee 对象 -->
<bean id="employee01" class="com.mcc.spring5.bean.Employee">
	<property name="ename" value="张三"></property>
	<property name="gender" value=""></property>
	<property name="dept" ref="department01"></property>
</bean>
<!-- 创建 Department 对象 -->
<bean id="department01" class="com.mcc.spring5.bean.Department">
	<property name="dname" value="财务部"></property>
</bean>

第二种方式:
这种方式要获取到 dept.dname 的前提是能获取到 Department dept 对象,因此,这种方式依赖于 Employee 类内的 getDept() 方法。

<!-- 级联赋值 方式2 -->
<!-- 创建 Employee 对象 -->
<bean id="employee02" class="com.mcc.spring5.bean.Employee">
	<property name="ename" value="李四"></property>
	<property name="gender" value=""></property>
	<property name="dept" ref="department02"></property>
	<property name="dept.dname" value="人事部"></property>
</bean>
<!-- 创建 Department 对象 -->
<bean id="department02" class="com.mcc.spring5.bean.Department"></bean>

测试

@Test
public void testEmployee01() {
	ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
	Employee employee = context.getBean("employee01", Employee.class);
	employee.show();//张三::男::Department [dname=财务部]
}

@Test
public void testEmployee02() {
	ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
	Employee employee = context.getBean("employee02", Employee.class);
	employee.show();//李四::男::Department [dname=人事部]
}
集合属性的注入

1. 集合中存放的是普通类型的数据

Student.java

package com.mcc.spring5.collection;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Student {
	private String[] courses;
	private Set<String> set;
	private List<String> list;
	private Map<String,String> map;
	
	public String[] getCourses() {
		return courses;
	}
	public void setCourses(String[] courses) {
		this.courses = courses;
	}
	public List<String> getList() {
		return list;
	}
	public void setList(List<String> list) {
		this.list = list;
	}
	public Map<String, String> getMap() {
		return map;
	}
	public void setMap(Map<String, String> map) {
		this.map = map;
	}
	public Set<String> getSet() {
		return set;
	}
	public void setSet(Set<String> set) {
		this.set = set;
	}
	
	@Override
	public String toString() {
		return "Student [courses=" + Arrays.toString(courses) + ", set=" + set + ", list=" + list + ", map=" + map
				+ "]";
	}

}

Spring 配置文件 collection.xml

集合使用的标签
数组<array>
Set<set>
List<list>
Map<map> <entry>
<?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="student" class="com.mcc.spring5.collection.Student">
		<property name="courses">
			<array>
				<value>语文</value>
				<value>数学</value>
				<value>英语</value>
			</array>
		</property>
		<!-- 为 Set 集合赋值 -->
		<property name="set">
			<set>
				<value>长春</value>
				<value>沈阳</value>
				<value>北京</value>
			</set>
		</property>
		<!-- 为 List 集合赋值 -->
		<property name="list">
			<list>
				<value>火车</value>
				<value>飞机</value>
				<value>轮船</value>
			</list>
		</property>
		<!-- 为 Map 集合赋值 -->
		<property name="map">
			<map>
				<entry key="1" value="本科"></entry>
				<entry key="2" value="硕士"></entry>
				<entry key="3" value="博士"></entry>
			</map>
		</property>
	</bean>

</beans>

测试

public class TestCollection {	
	@Test
	public void testCollection() {
		ApplicationContext context = new ClassPathXmlApplicationContext("collection.xml");
		Student stu = context.getBean("student", Student.class);
		System.out.println(stu.toString());
		//Student [courses=[语文, 数学, 英语], set=[长春, 沈阳, 北京], list=[火车, 飞机, 轮船], map={1=本科, 2=硕士, 3=博士}]
	}
}

2. 集合中存放的是对象类型的数据

Student.java

package com.mcc.spring5.collection;

import java.util.List;

public class Student {
	private String name;
	private List<Course> courseList;//学生所学的多门课程
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public List<Course> getCourseList() {
		return courseList;
	}
	public void setCourseList(List<Course> courseList) {
		this.courseList = courseList;
	}
	
	@Override
	public String toString() {
		return "Student [name=" + name + ", courseList=" + courseList + "]";
	}	

}

Course.java

package com.mcc.spring5.collection;

public class Course {
	private String cname;

	public String getCname() {
		return cname;
	}
	public void setCname(String cname) {
		this.cname = cname;
	}
	
	@Override
	public String toString() {
		return "Course [cname=" + cname + "]";
	}

}

Spring 配置文件 collection.xml

通过在集合标签中使用 <ref/>标签,完成向集合中传入对象类型的数据。

  • ref 标签中的 bean 属性:要传入到集合中的对象的 id 值。
<?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="student" class="com.mcc.spring5.collection.Student">
		<!-- 为 name 属性赋值 -->
		<property name="name" value="张三"></property>
		<!-- 为 courseList 赋值 -->
		<property name="courseList">
			<list>
				<ref bean="course01"/>
				<ref bean="course02"/>
			</list>
		</property>
	</bean>
	
	<!-- 创建 Course 对象 -->
	<bean id="course01" class="com.mcc.spring5.collection.Course">
		<property name="cname" value="Spring5框架"></property>
	</bean>
	<bean id="course02" class="com.mcc.spring5.collection.Course">
		<property name="cname" value="MyBatis"></property>
	</bean>

</beans>

测试

public class TestCollection {
	@Test
	public void testCollection() {
		ApplicationContext context = new ClassPathXmlApplicationContext("collection.xml");
		Student stu = context.getBean("student", Student.class);
		System.out.println(stu.toString());
		//Student [name=张三, courseList=[Course [cname=Spring5框架], Course [cname=MyBatis]]]
	}
}

3. 提取集合部分,以供多个对象注入

Book.java

package com.mcc.spring5.collection;

import java.util.List;

public class Book {
	private List<String> bookList;

	public List<String> getBookList() {
		return bookList;
	}
	public void setBookList(List<String> bookList) {
		this.bookList = bookList;
	}
	
	@Override
	public String toString() {
		return "Book [bookList=" + bookList + "]";
	}
}

Spring 配置文件 bookCollection.xml

要提取集合部分,供其他对象进行属性注入,首先要引入 util名称空间xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
						http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
	
	<!-- List 集合属性,抽取出来,以供其他对象进行注入 -->
	<util:list id="bookList">
		<value>仲夏夜之梦</value>
		<value>威尼斯商人</value>
		<value>皆大欢喜</value>
		<value>第十二夜</value>
	</util:list>
	
	<!-- 创建 Book 对象,并注入 List 属性 -->
	<bean id="book" class="com.mcc.spring5.collection.Book">
		<property name="bookList" ref="bookList"></property>
	</bean>
	
</beans>

测试

@Test
public void testBookCollection() {
	ApplicationContext context = new ClassPathXmlApplicationContext("bookCollection.xml");
	Book book = context.getBean("book", Book.class);
	System.out.println(book);//Book [bookList=[仲夏夜之梦, 威尼斯商人, 皆大欢喜, 第十二夜]]
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值