Spring
网课链接 https://www.bilibili.com/video/BV1Vf4y127N5
代码地址 https://gitee.com/userwhz/spring-ssg
Spring概念
轻量级的JavaEE框架
解决企业应用开发的复杂性
Spring 核心部分
IOC AOP
IOC 控制反转:把创建对象过程交给Spring进行管理
AOP面向切面:不修改源代码进行功能的增强
特点
方便解耦,简化开发
AOP编程支持
方便程序测试
方便集成框架
方便进行事务操作
降低API开发难度
入门案例
spring5相关jar包
Beans Core Context Expression
IOC容器
spring基本搭建相关链接 https://www.cnblogs.com/chenyanbin/p/13302036.html
控制反转:把对象创建和对象之间的调用过程,交给Spring进行管理
目的:降低代码耦合度
常见方式依赖注入
IOC底层原理
xml解析 工厂模式 反射
IOC过程
1)xml配置文件
2)service dao 创建工厂类
String classValue = class 属性值 在工厂中用xml解析 得到类名
CLass clazz = Class.forName(classValue) 反射创建对象 得到class
return (UserDao) clazz.newInstance() 创建对象
IOC思想基于IOC容器完成,底层就是对象工厂
Spring提供IOC容器实现两种方式(两个接口)
1)BeanFactory(内部使用接口,一般不适用)
IOC容器基本实现
加载配置文件时不会创建对象,使用时才创建对象
2)ApplicationContext(一般使用这个)
BeanFactory的子接口
加载配置文件时会创建对象
主要实现类 (路径差别)
FileSystemXmlApplicationCOntext
ClassPathXmlApplicationContext
IOC操作Bean管理
两个操作
- pring创建对象
xml配置
- Spring注入属性
两种方式
1)基于xml配置文件
创建对象
<bean id="user" class="com.atguigu.spring5.User"></bean>
使用bean标签,标签里面添加对应属性,可以实现对象创建
id 唯一标识
class 类的全路径
name 和id类似 可以加特殊符合 一般用id
默认执行无参数构造方法
注入属性
DI 依赖注入 就是注入属性
- set方法注入
创建属性和属性的set方法
在spring配置文件中配置对象创建。配置属性注入
使用property完成属性注入
- 有参构造注入
创建属性和有参构造
在spring配置文件中配置对象创建。配置属性注入
使用constructor-arg完成属性注入
- p名称空间注入,简化基于xml配置方式(了解)
添加xmlns:p="http://www.springframework.org/schema/p"
在配置文件中
进行属性注入
```
<bean id="user" class="com.atguigu.spring5.User" p:userName="aaa">
</bean>
```
注入其他类型属性
字面量 value
- 空值
```
<property name="username">
<null/>
</property>
```
- 属性值包含特殊符号
转义符号
写到CDATA <[CDATA[内容]]>
注入属性之外部bean
用service调用dao里面的方法
在sping的配置文件中配置
注入属性之内部bean
一对多 一个部门 多个员工
配置文件
```
<!--内部bean-->
<bean id="emp" class="com.atguigu.spring5.bean.Emp">
<property name="ename" value=""></property>
<property name="gender" value=""></property>
<property name="dept">
<bean id="dept" class="com.atguigu.spring5.bean.Dept">
<property name="dname" value="保安部"></property>
</bean>
</property>
</bean>
```
注入属性之级联赋值
```
<!--级联赋值-->
<bean id="emp" class="com.atguigu.spring5.bean.Emp">
<property name="ename" value=""></property>
<property name="gender" value=""></property>
<property name="dept" ref="dept"></property>
</bean>
<bean id="dept" class="com.atguigu.spring5.bean.Dept">
<property name="dname" value="保安部"></property>
</bean>
```
注入属性之集合属性
注入数组类型属性
list
array
注入List集合类型属性
list
注入Map集合类型属性
map
entry
注入Set集合类型属性
set
在集合设置对象类型值
list中加bean
提取集合类型属性注入
添加
xmlns:util="http://www.springframework.org/schema/util
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-beans.xsd
util
后面bean property 写上 ref
FactoryBean
两种bean
普通bean
配置文件class是什么返回什么
工厂bean
可以返回不同的类型
创建类 作为工厂bean
实现接口FactoryBean
实现接口的方法,在实现的方法中定义返回的bean类型
Bean的作用域
设置bean实例是单实例还是多实例
默认单例
scope属性
默认 singleton 单实例 加载spring的配置文件时就会创建实例对象
prototype 多实例 在调用对象的时候才会创建对象
bean的生命周期
基本
1. 实例化 Instantiation
2. 属性赋值 Populate
3. 初始化 Initialization
4. 销毁 Destruction
1)通过构造器创建bean实例(执行无参数构造)
2)为bean的属性和引用设置值(调用set方法)
3)调用bean的初始化方法(需要配置,方法需要自己创建)bean标签属性 init-method 方法名
4)bean可以使用(对象获取到了)
5)当容器关闭时,调用bean的销毁方法(需要配置,方法需要自己创建)bean标签属性 destory-method 方法名
bean的后置处理器(创建方法 继承BeanPostProcessor) before after
1)通过构造器创建bean实例(执行无参数构造)
2)为bean的属性和引用设置值(调用set方法)
把bean的实例传递给后置处理器的方法
3)调用bean的初始化方法(需要配置,方法需要自己创建)bean标签属性 init-method 方法名
把bean的实例传递给后置处理器的方法
4)bean可以使用(对象获取到了)
5)当容器关闭时,调用bean的销毁方法(需要配置,方法需要自己创建)bean标签属性 destory-method 方法名
xml自动装配
手动装配 自己设置值
自动装配 bean autowire属性
byName 根据属性名称注入
byType 根据属性类型注入
引入外部属性文件
直接配置数据库信息
连接池
把外部properties属性文件引入spring配置文件中
引入context名称空间
和util一样
引入外部文件
context:property-placeholder location="地址"
${}
2)基于注解方式
@注解名称(属性名称=属性值,属性名称=属性值)
作用在类,方法,属性
目的简化开发
Bean管理-创建对象
@Component
@Service
@Controller
@Repository
组件扫描配置
引入依赖
开启组件扫描
名称空间context
context:component-scan base-package=""
自己配置扫描 filter
属性注入
@Autowired 根据属性类型自动装配
@Qualifier 根据属性名称进行注入 指定 (value)
@Resource 可以根据类型注入,也可以根据名称注入 (name)
@Value 注入普通类型属性 (value)
不需要加set方法
完全注解开发
组件扫描不在xml配置
创建配置类
@Configuration
@ComponentScan(basePackages = {""} )
AOP操作
基本概念
面向切面编程
对业务逻辑的各个部分进行隔离
使得业务逻辑各部分之间的耦合度降低,提高程序的可用性
不通过修改源代码的方式添加新的功能
底层原理
动态代理
1)有接口情况 使用JDK动态代理
创建实现类代理对象
2)没有接口情况 使用CGLIB动态代理
创建当前类子类的代理对象
Proxy.newProxyInstance方法 可以返回指定接口的代理对象
三个参数
类加载器 classLoader
增强方法所在的类,这个类实现的接口,支持多个接口
实现接口InvocationHandler,创建代理对象,写增强的方法
操作术语
1)连接点
可以被增强的方法
2)切入点
实际被真正增强的方法
3)通知(增强)实际增强的逻辑部分
前置通知 Before
后置通知 AfterReturning
环绕通知 Around
异常通知 AfterThrowing
最终通知 After
4)切面
动作
把通知应用到切入点过程
AOP操作
AspectJ 不是Spring组成部分
是独立的AOP框架
一般和Spring一起使用
实现
基于配置文件
基于注解 常用
引入依赖
切入点表达式
execution([权限修饰符] [返回类型] [类全路径] [方法名称] ([参数列表]))
举例
execution(* com.atguigu.dao.BookDao.add(..))
在增强类加@Aspect
方法上加@Before(value = “execution(表达式)”)
无异常顺序
环绕前
before
方法
环绕后
after
afterReturning 方法返回值后执行
有异常设置
环绕前
before
方法 不执行
环绕后 不执行
after
afterReturning 方法返回值后执行 不执行
配置文件
命名空间 context
开启注解扫描
开启Aspect
aop:asoect-autoproxy
公共切入点抽取
方法上@Poingtcut(value = “execution()”)
方法名
后面value = 方法名
设置增强优先级
@Order(数值) 越小优先值越高
事务操作
数据库操作基本单元,逻辑上一组操作,要么都成功,要么都失败。
四大特性 ACID
原子性 不可分割
一致性 操作前后总量不变
隔离性 多事务操作不影响
持久性
Java三层 Web Service业务操作 Dao数据库操作
开启事务
执行操作
出现异常,事务回滚
提交事务
事务管理
两种方式
1)编程式事务管理
2)声明式事务管理 一般使用这个
基于xml
底层使用AOP
基于注解 一般用这个
在spring配置文件中配置事务管理器
配置开启事务注解 tx名称空间
annotation-driven
注解
@Transactional
Spring事务管理API
PlatFormTransactionManager
声明式事务管理参数配置
propagation 事务传播行为
事务传播行为用来描述由某一个事务传播行为修饰的方法被嵌套进另一个方法的时事务如何传播
事务传播行为类型说明
PROPAGATION_REQUIRED
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
PROPAGATION_SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY
使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW
新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER
以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
isolation 事务的隔离级别
READ UNCOMMITTED 读未提交 脏读 不可重复读 幻读
READ COMMITTED 读已提交 不可重复读 幻读
REPEATABLE READ 可重复读 幻读
SERIALIZABLE 串行化
解决隔离性
三个读问题
脏读 一个未提交的事务读取到另一个未提交事务的数据
不可重复读 一个未提交的事务读取到已提交事务的数据
幻读 一个未提交的事务读取到已提交事务添加的数据
timeout 超时时间 事务在一定时间进行提交,如果不提交进行回滚 单位s
readOnly 是否只读 默认false
rollbackFor 回滚 设置哪些异常进行回滚
no RollbackFor 不回滚 设置哪些异常不进行回滚
完全注解声明式事务控制
配置类
@EnableTransactionManagement