Spring5
- 框架概述
- IOC(Inversion Of Control)
-
- IOC基本过程:
- IOC接口(BeanFactory)
-
- IOC接口实现类
- IOC操作Bean管理
-
- 一、什么是Bean管理?
- 二、什么是DI?
- 三、Bean管理的两种实现方式
-
- 1.基于XML配置文件方式实现
-
- 基于XML方式创建对象
- 基于XML方式注入属性
-
- 常规属性注入
- 特殊属性值的注入
- 2.基于注解方式实现
-
- 什么是注解?
- 基于注解方式创建对象
-
- 有关创建对象提供的注解(默认都是单例)
- 基于注解方式注入属性
-
- 有关 对象属性注入 的注解
- 示例
- 实现完全注解开发(无XML配置文件)
- 四、Bean管理的作用域
-
- 如何设置Spring创建Bean是单实例还是多实例?
- 区别
- 五、Bean管理的生命周期
-
- Spring中Bean生命周期的基本流程(未添加后置处理器)
-
- 演示
- Spring中Bean生命周期的基本流程(添加后置处理器)
-
- 演示
- 六、Bean管理之XML自动装配
- 七、Bean管理之引入外部属性文件
- AOP(Aspect Oriented Programming)
-
- 概念
- AOP术语
-
- 连接点
- 切入点
- 通知(增强)
-
- 切面
- AOP底层原理
-
- 动态代理
-
- 有接口(JDK动态代理)
-
- 演示实现过程
- 无接口(CGLIB动态代理)
- AOP操作
-
- 基于AspectJ实现AOP操作
-
- 通过XML配置文件方式实现
-
- 基本步骤
- 通过AspectJ注解方式实现
-
- 基本步骤
- 示例
- 常用操作
- JDBCTemplate
-
- JDBCTemplate基本使用流程
- JDBCTemplate基本CRUD操作
-
- CREATE 增
- READ 查
- UPDATE 改
- DELETE 删
- Spring 事务操作
-
- 事务概念
-
- 事务使用基本流程
- Spring 事务管理
-
- Spring 事务管理 API
- 编程式事务管理
- 声明式事务管理(常用)
-
- 参数配置
- 基于注解方式(常用)
- 基于 xml 配置文件方式
- 示例:完全注解实现Spring声明式事务管理
- Spring 配置文件常见XML标签
-
- Bean标签
-
- Property标签
-
- Value标签
- list标签
-
- Value标签
- ref标签
- Array标签
-
- Value标签
- Map标签
-
- Entry标签
- Set标签
-
- Value标签
- Spring5 新功能
-
- Spring5 框架整合 Log4j2
- Spring5 框架整合 JUnit4
- Spring5 框架整合 JUnit5
Spring5代码学习仓库:Gitee
视频课程:尚硅谷2022 Spring5教程
Spring5新特性:
https://cntofu.com/book/95/33-what-new-in-the-spring-framework.md
https://zhuanlan.zhihu.com/p/645200006
框架概述
Spring 是轻量级的开源的 JavaEE 框架。Spring 可以解决企业应用开发的复杂性。
Spring 有两个核心部分:IOC 和 Aop
(1)IOC:控制反转,把创建对象过程交给 Spring 进行管理
(2)Aop:面向切面,不修改源代码进行功能增强
Spring 特点
(1)方便解耦,简化开发
(2)Aop 编程支持
(3)方便程序测试
(4)方便和其他框架进行整合
(5)方便进行事务操作
(6)降低 API 开发难度
IOC(Inversion Of Control)
把对象创建和对象之间的调用过程,交给 Spring 进行管理。
目的:为了降低开发中的耦合度。
基本实现原理:XML解析、工厂模式、反射。
附:工厂模式详解
IOC基本过程:
- xml配置文件,配置要创建的对象Bean。
- xml解析得到配置文件中的包路径。
- 创建XXFactory工厂类,通过反射创建对象返回。
IOC接口(BeanFactory)
IOC的思想就是基于IOC容器完成,IOC的底层就是对象工厂。
Spring提供了两个IOC容器实现的方式(两个接口)。
- BeanFactory:IOC容器的基本实现,一般是Spring内部使用,不建议开发人员使用。
- 在加载配置文件时不会创建容器中的对象,只有获取时才创建。
- ApplicationContext:BeanFactory的子接口,提供更多更强大的功能。一般由开发人员使用。
- 在加载配置文件时会同时创建容器中的对象。
注:推荐使用ApplicationContext
接口,因为项目使用中,一般把耗时的操作放在项目启动时。
IOC接口实现类
IOC操作Bean管理
Spring中有两种类型的Bean:普通Bean(开发者自己创建)、工厂Bean(FactoryBean)。
主要区别
- 普通Bean:在配置文件中定义的Bean类型(class中指定)就是获取bean得到的类型。
- 工厂Bean:在配置文件中定义的Bean类型(class中指定)可以和获取bean类型不一致。
怎么手动创建工厂Bean?
- 创建类,实现
FactoryBean
接口 - 实现接口中的方法,在实现的
getObject
方法中可以定义不同的返回Bean类型
public class MyBean implements FactoryBean<Department> {
@Override
public Department getObject() throws Exception {
// 自定义返回类型
Department department = new Department();
department.setDeptName("研发部");
return department;
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return FactoryBean.super.isSingleton();
}
}
一、什么是Bean管理?
Bean管理指两个操作:
- 由Spring创建对象
- 由Spring注入属性。
二、什么是DI?
DI(Dependency Injection)依赖注入,IOC的具体实现,简单来说就是注入属性,需要在创建对象完成的基础之前来进行。
三、Bean管理的两种实现方式
1.基于XML配置文件方式实现
基于XML方式创建对象
在配置文件的beans标间中新建bean标签,填写id、class等属性。
注:如果没有设置构造参数子标签(<constructor-arg></constructor-arg>
),则默认使用无参构造方法创建,因此需要注意无参构造是否存在。
基于XML方式注入属性
常规属性注入
- 使用set方法注入(默认使用无参构造创建bean)
- 在实体类中创建好对应属性的
set
方法 - 在Spring配置文件中的Bean标签中插入属性标签
<property name="property" value="value"></property>
- 在实体类中创建好对应属性的
- 使用有参构造方法注入(根据参数匹配构造方法创建bean)
- 在实体类中创建好对应属性的 有参构造方法
- 在Spring配置文件中的Bean标签中插入构造方法参数标签
<constructor-arg name="property" value="value"></constructor-arg>
或<constructor-arg index=“Number” value="value"></constructor-arg>
- name:构造方法中参数的属性名
- value:注入的实际值
- index: 索引,从0开始,代表构造方法从左至右的参数。
- 注:相较于标签的两种写法,使用name方式更准确。
- P名称空间注入(用于简化XML配置方式)
- 在XML配置文件中的
beans
标签上添加xmlns:p="http://www.springframework.org/schema/p"
命名空间 - 进行属性注入,在bean标签中操作。
- 无需再写子标签,直接在bean书写
p:注入属性名
即可完成操作。 - 注意 : 仅简化set方式注入
- 无需再写子标签,直接在bean书写
- 在XML配置文件中的
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"
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="my_user" class="icu.lking.spring5.User"></bean>
<!-- 方式一:使用set方法完成依赖注入 -->
<!-- 配置Book对象创建信息:默认使用无参构造方法 -->
<bean id="book_di_property" class="icu.lking.spring5.Book">
<property name="bookName" value="小红与小牛的故事"></property>
<property name="author" value="Jason"></property>
</bean>
<!-- 方式二:使用构造方法方法完成依赖注入 -->
<!-- 配置Book对象创建信息:这里使用有参构造方法 -->
<bean id="book_di_constructor_name" class="icu.lking.spring5.Book">
<!-- 使用name方式 -->
<constructor-arg name="author" value="Jason"></constructor-arg>
<constructor-arg name="bookName" value="放牛娃的夏天"></constructor-arg>
</bean>
<bean id="book_di_constructor_index" class="icu.lking.spring5.Book">
<!-- 使用Index方式 -->
<constructor-arg index="0" value="小白和小黑"></constructor-arg>
<constructor-arg index="1" value="Jason"></constructor-arg>
</bean>
<!-- 方式三:使用p命名空间注入属性 注意 : 仅简化set方式注入 -->
<bean id="order_di_p_label" class="icu.lking.spring5.Order" p:orderNumber="123456" p:createUserName="Jason"></bean>
</beans>
特殊属性值的注入
字面量:设置的固定值都是字面量。
- null值
主要是null
标签的使用。
<!-- 注入特殊值,null值 -->
<bean id="student_di_null" class="icu.lking.spring5.Student">
<property name="name" value="Jason"></property>
<property name="stuNumber">
<!-- null值标签 -->
<null/>
</property>
</bean>
- 属性值包含特殊符号
主要问题:使用特殊符号中要避免xml进行转义。
解决方式:
①.特殊符号使用转义字符,如>
用>
表示
②.使用<![CDATA[...]]>
标记,可以忽略xml的转义(在该标签中的语句和字符原本是什么样的,在拼接成SQL后还是什么样的)
<!-- 注入特殊值,包含特殊符号的属性值 -->
<!-- 主要是要避免xml进行转义 -->
<!-- 1.特殊符号使用转义字符,如>用>表示 -->
<!-- 2.使用<![CDATA[...]]>标记,可以忽略xml的转义(在该标签中的语句和字符原本是什么样的,在拼接成SQL后还是什么样的) -->
<bean id="student_di_split_label" class="icu.lking.spring5.Student">
<!-- 拆分属性标签写法 -->
<property name="name">
<value>Jason<CEO></value>
</property>
<property name="stuNumber">
<value><![CDATA[<<20210907>>]]></value>
</property>
</bean>
- 注入外部Bean属性
使用property
标签的ref
属性来注入外部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"
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">
<!-- 外部Bean注入 -->
<!-- UserService Bean,采用Set注入方式注入UserDao -->
<bean id="userService" class="icu.lking.spring5.service.UserService">
<!-- Set注入 ref:填写外部Bean ID-->
<property name="userDao" ref="userDao"></property>
</bean>
<!-- UserDao Bean :寻找其实现类创建Bean-->
<bean id="userDao" class="icu.lking.spring5.dao.impl.UserDaoImpl"></bean>
<!-- 测试User -->
<bean id="testUser" class="icu.lking.spring5.User" p:name="Jason" p:sex="male"></bean>
</beans>
- 注入内部Bean属性和级联赋值
- 注入内部Bean
注入内部Bean,即在Property
标签下嵌套Bean
标签实现。 - 级联赋值
级联赋值即 在不嵌套bean
标签的情况下,便可完成对内部bean的内部属性赋值。
实现方式:
采用外部bean的方式注入,即可不嵌套bean
标签。采用.
符号则可可同时对外部bean的属性赋值,无需嵌套bean
标签。(需要有get方法)
- 注入内部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">
<!-- 注入 内部Bean 属性 -->
<!-- 员工Bean -->
<bean id="testEmp" class="icu.lking.spring5.bean.Employee">
<!-- set注入 普通属性 : 两种写法,效果相同 -->
<property name="name" value="Jason"></property>
<property name="workNumber">
<value>20210907</value>
</property>
<!-- 注入属性 内部Bean -->
<property name="department">
<!-- 内部Bean 可以不写 id -->
<bean id="inner_bean_dept" class="icu.lking.spring5.bean.Department">
<property name="deptName" value="研发部"></property>
</bean>
</property>
</bean>
<bean id="testEmpAgain" class="icu.lking.spring5.bean.Employee">
<!-- set注入 普通属性 -->
<property name="name" value="Jack"></property>
<property name="workNumber" value="20210906"></property>
<!-- 注入属性 内部Bean -->
<!-- 级联赋值: 可以通过外部bean 方式 并搭配 级联符号 -->
<property name="department" ref="dept"></property>
<!-- 如果使用级联符号 必须 注意:需要在Employee类中提供该属性的get方法,才能使用 -->
<property name="department.deptName" value="安保部"></property>
</bean>
<bean id="dept" class="icu.lking.spring5.bean.Department"></bean>
</beans>
- 注入数组/List集合/Map集合/Set集合类型属性值
- 在使用基本数据类型与包装类和String类型作为元素情况下
在property
下写出对应属性的标签即可。 - 在使用对象作为元素的情况下
提前创建对应数目的元素bean,在property
下写出对应属性的标签,并在对应标签下添加对应元素bean数目的ref
标签,在ref
标签的bean属性中填写 元素bean的id。 - 数组/List集合/Map集合/Set集合类型属性值的 提取 (重复使用)
- 添加util命名空间
xmlns:util="http://www.springframework.org/schema/util"
- 同时在
xsi:schemaLocation="...”
中追加http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
- 创建公共引用部分集合,定义id
- 注入属性时,使用
property
标签的ref
属性引用公共集合部分
- 添加util命名空间
- 在使用基本数据类型与包装类和String类型作为元素情况下
package icu.lking.spring5.collectiontype;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 测试 注入
*/
public class CollectionTestBean {
// -------在使用基本数据类型与包装类和String类型作为 元素 情况下--------
// 1. 数组类型属性
private String[] arr;
// 2. List集合类型属性
private List<String> list;
// 3. Map集合类型属性
private Map<String, String> map;
// 4. Set集合类型属性
private Set<String> set;
// ----公共集合共用----
private List<String> list1;
private List<String> list2;
// -----在使用对象作为 元素 的情况下------
private List<Course> courseList;
public void setCourseList(List<Course> courseList) {
this.courseList = courseList;
}
public void setArr(String[] arr) {
this.arr = arr;
}
public void setList1(List<String> list1) {
this.list1 = list1;
}
public void setList2(List<String> list2) {
this.list2 = list2;
}
public void setList(List<String> list) {
this.list = list;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setSet(Set<String> set) {
this.set = set;
}
/**
* 重写 toString 展示数据
* @return
*/
@Override
public String toString() {
return "CollectionTestBean{" +
"arr=" + Arrays.toString(arr) +
", list=" + list +
", map=" + map +
", set=" + set +
", list1=" + list1 +
", list2=" + list2 +
", courseList=" + courseList +
'}';
}
}
<?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="global_list">
<value>123</value>
<value>456</value>
<value>789</value>
</util:list>
<bean id="testCollectionType" class="icu.lking.spring5.collectiontype.CollectionTestBean">
<!-- 在使用基本数据类型与包装类和String类型作为 元素 情况下 -->
<!-- 1. 注入 数组属性值 -->
<property name="arr">
<!-- 这里采用array标签或list标签都可 -->
<array>
<value>一</value>
<value>二</value>
<value>三</value>
</array>
</property>
<!-- 2. 注入 List集合属性值 -->
<property name="list">
<list>
<value>四</value>
<value>五</value>