Spring
IOC
spring简介
* Spring是分层的Java SE/EE应用full-stack轻量级开源框架
以 IOC(Inverse Of Control:反转控制)和
AOP(Aspect Oriented Programming:面向切面编程)为内核
提供了展现层 Spring MVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术
还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的 Java EE 企业应用开源框架。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iMd9GgLq-1595148548262)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570762883181.png)]
控制反转(IOC)
* 控制反转是一种思想,他的目的是指导我们设计出一套更加松耦合的程序(解耦)
# 控制:
是指的是控制权,可以简单的理解为对象创建的控制权
# 反转:
是指的对象创建的控制权由程序员手中反转到spring的手中
需要对象的时候让spring来帮我们来创建
<!--
spring 会依赖配置文件来帮我们创建我们需要的对象
配置文件中的标签相当于之前写的beans.properties 中的每一个键值对
id 为这个标签的唯一标识
-->
<bean id="book" class="com.leyou.dao.UserDao"></bean>
核心配置文件 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"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="book" class="com.leyou.dao.UserDao"></bean>
</beans>
主要的api
ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = act.getBean(UserService.class);
思路分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hwsEvAot-1595148548272)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570764922453.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2xvvBQzD-1595148548302)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570765245065.png)]
# 两个接口
* BeanFactory
这是SpringIOC容器的顶级接口 它定义了SpringIOC的最基础的功能,但是其功能比较简单,一般面向Spring自身使用
BeanFactroy在第一次使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化,
* ApplicationContext
这是在BeanFactory基础上衍生出的接口,它扩展了BeanFactory的功能,一般面向程序员使用
ApplicationContext是在容器启动时,一次性创建并加载了所有的Bean
他们创建的对象都是单例的
# 三个实现类
* 这三个类的作用都是:读取配置文件,初始化Spring的IOC容器,不一样的是加载配置文件的位置
* ClassPathXmlApplicationContext
读取类路径下的xml作为配置文件
* FileSystemXmlApplicationContext
读取本地目录下的xml作为配置文件
* AnnotationConfigApplicationContext
读取一个Java类作为配置文件
# 一个方法
act.getBean();
通常获取对象的方法有三种
1.1 act.getBean(String name );
以bean标签的 id属性作为值 因为向map集合中存的时候存的是beanID的值
act.getBean("book");
1.2 getBean(Class<T> requiredType);
以接口的类对象作为参数
act.getBean(Book.class);
1.3 getBean(String name, Class<T> requiredType);
以 beanId和接口的类对象作为参数
act.getBean("book",Book.class);
bean的配置
1. bean的创建方式
1.1 直接调用无参构造函数创建
<bean id="book" class="com.itheima.ioc.Book" ></bean>
1.2 利用静态工厂创建
<bean id="book" class="com.itheima.ioc.BeanFactory" factory-method="getBook1"></bean>
1.3 利用实例化工厂创建
需要先把工厂创建出来
<bean id="beanFactory" class="com.itheima.ioc.BeanFactory"></bean>
<bean id="book" factory-bean="beanFactory" factory-method="getBook2"></bean>
2. bean的作用域
bean的作用域根据bean的类型的不同而不同
bean的类型分为单例和多例
2.1 单例对象的时候
创建:
bean对象的创建随着容器的初始化而创建
在IOC容器初始化的时候,会读取配置文件或者配置类
会把所有的指定的类型的类创建出对象,并根据各自的key放入map集合中
销毁:
单例对象随着容器的销毁而销毁
2.2 多例对象的时候(scope标签来改变 prototype 为多例对象 singleton为单例对象)
创建:
每次调用getBean的时候创建
销毁:
销毁的权限不归Spring管 是跟系统的垃圾回收机器相关的(gc垃圾回收机制)
3. 依赖注入
依赖注入(Dependency Injection,DI) 其实依赖注入就是给属性复制的过程
依赖注入有两种方式:
一种是通过构造函数
一种是通过set方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dHFcw7PE-1595148548312)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570861638219.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-InohyJfj-1595148548324)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570861659418.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ck5X6q4e-1595148548327)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570861946542.png)]
4. 注入集合的属性
单列集合的标签可以互换
双列之间的标签之间可以互换
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7xPOLIYM-1595148548335)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570862037374.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oBRC1zgB-1595148548339)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570862079674.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AIO5RDEx-1595148548343)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570862102960.png)]
配置文件模块化(也就是多个配置文件的处理方式)
# 当我们的配置文件都存在一个主配置文件的applicationContext.xml中的时候
会导致这个文件巨大,开发的维护起来非常不方便
# 针对这个问题 spring提供了两种的方法
1. 同时引入多个配置文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TnrRWEQ4-1595148548347)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570862466201.png)]
2. 主从配置(也就是主配置文件里面导入其他的配置文件)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R9sNu7Uq-1595148548353)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570862652709.png)]
# 注意:
1. 同一xml配置文件不能出现相同名称的bean标签,如果初夏会报错
2. 不同的xml配置文件如果出现相同的名称的bean标签,不会报错,只是后加载的配置文件里面的bean标签会覆盖掉前面加载的配置文件里面的bean标签
> 开发中尽量使用bean标签的id也就是名称是唯一的
AOP
AOP概念
* aop(面向切面编程)是一种思想,他的目的是在不修改源代码的情况下,对原有的功能进行增强
* SpirngAop 是对aop思想的一种实现,Spring底层同时支持JDK 和Cglib动态代理
* Spring 会根据被代理的类是否有实现的接口来自动选择代理方式
如果有接口的话,就会选择JDk动态代理(当然也可以选择cglib)
如果没有接口的话,就采用cglib,没有办法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CWkNMLMI-1595148548357)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570972664220.png)]
术语
目标对象
被代理的类
连接点
目标对象中所有的方法
切入点
目标对象中需要增强的方法
增强(通知)
指的具体的一个功能(也可以说是具体的增强的方法)
织入
将增强功能和切入点连接到一起的一个过程
代理对象
经过动态代理产生的一个对象
切面
切点+增强
通俗的讲:就是讲一个什么样的增强功能加入到一个切点的什么位置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LFT9Z3Gb-1595148548360)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570973592824.png)]
XML配置切面
1. 首先要引入一个解析切点表达式的依赖
<!--
解析切点的表达式 * 和 ..
-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
2. 在xml中添加对应的bean标签
添加相应的切面
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7KumOOS0-1595148548364)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570975574821.png)]
切点表达式
* 可以通过表达式的形式来定义一组切点(就是一些方法)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s2v3TD1h-1595148548370)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570976127395.png)]
四大通知
前置通知
后置通知
异常通知
最终通知
1. before: 前置通知
在切点方法执行之前执行的方法
2. after-returning: 后置通知
在切点方法正常运行结束之后执行的方法
3. after-throwing: 异常通知
在切点方法运行抛出异常以后运行的方法
4. after: 最终通知
在切点方法运行最后执行
理解:
try{
before 前置通知
//切点方法执行了
after-returning 后置通知
}catch(Exception e){
after-throwing 异常通知
}finally{
after 最终通知
}
xml配置文件中的配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ieCu4waA-1595148548372)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570977337320.png)]
环绕通知
* 环绕通知是一种允许我们以编码的形式实现的通知类型
我们可以用它来代替四大通知
# 当我们使用环绕通知的时候
xml 的配置文件的配置为
public void arround(ProceedingJoinPoint pjp) {
try {
System.out.println("方法之前");
//这个表示切点方法的执行
// 相当于 method.invoke(obj,args)
pjp.proceed();
System.out.println("方法执行后");
} catch (Throwable throwable) {
throwable.printStackTrace();
System.out.println("异常方法执行了");
} finally {
System.out.println("最终的方法执行了");
}
}
配置文件 xml
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XPIHW215-1595148548377)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570978147711.png)]
AOP的工作原理
开发阶段
运行阶段
# 开发阶段
* 开发目标对象(业务逻辑)
* 开发增强功能(增强业务)
* 使用Spring 配置 描述核心的业务逻辑和增强的业务逻辑的运行顺序(切面)
# 运行阶段
* Spring会时刻监控切点方法的执行, 一旦程序运行到切点方法,Spring会立即将增强方法放置到切点方法的前后左右的位置,以达到一个组装的效果
Spring注解版(四大通知)
1. 当使用配置文件来和注解的结合版来配置AOP切面的时候
也就说当使用注解来配置AOP的时候 必须要让AOP的注解生效
两种方式让AOP的注解生效
一种是在配置文件中开启自动代理
<aop:aspectj-autoproxy/>
一种是在配置类上添加一个注解
@EnableAspectJAutoProxy
# XML配置文件的两个重要的标签
1. 包扫描:
<context:component-scan base-package=""/>
只有添加了包扫描 在指定的包及其之包的注解才生效
2. 开启自动代理
<aop:aspectj-autoproxy/>
2. 把对应的类上添加注解,并且放入IOC容器中
@Component @Service @Repository @Contorllor
3. 在增强类上添加一个@Aspect
表示将增强类装换为切面
4. 配置切点
首先声明一个切点:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nYOED25L-1595148548383)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570979801366.png)]
# 如果同时使用了Spring 四大通知的注解版,执行的顺序有问题!!!!!!!!!!!
# 以后使用通知的话 并且使用注解版的话 就只能使用环绕通知!!!!!!!!!!!!!!!!!!!!!
这是Spring的bug
环绕通知注解版
* 只需要在环绕的方法上添加一个@Around就行了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nMKlqoy7-1595148548387)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570980045793.png)]
Spirng Aop的纯注解版本
//创建一个配置类
@ComponentScan("com.itheima") //包扫描
@EnableAspectJAutoProxy //开启自动代理 相当于xml中的<aop:aspectj-autoproxy/>
public class SpringConfig {
}
//测试中的读取配置类的信息的时候读取的是class文件的配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SZRB9RYD-1595148548390)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570980386376.png)]
Spirng中的事务
事务管理方式
# Spirng支持两种事务管理方式
* 编程式事务
将业务代码和事务代码放在一起书写,它的耦合性太高,开发中不使用
* 声明式事务
是将事务代码和业务代码隔离开发,然后通过一段配置让他们组装运行,最后达到事务控制的目的.
# 声明式事务是通过AOP原理实现的
事务管理器
PlatformTransactionManager
# 这是Spring进行事务管理的一个跟接口,我们要使用它的实现类做事务管理
# 它的实现类可以根据各种持久层进行事务管理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lAT0oHXI-1595148548395)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1571130274566.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xKFjK9yu-1595148548400)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1571130709238.png)]
TransactionDefinition
* 事务的定义:
我们用它类定义事务
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wIqSLkmD-1595148548403)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1571131535290.png)]
隔离状态
* 事务的隔离状态的相关(如果不设置事务的隔离级别,可能引发脏读,不可重复读,幻读)
1. 读未提交
ISOLATION_READ_UNCOMMITTED
2. 读已提交
ISOLATION_READ_COMMITTED
3. 可重复读
ISOLATION_REPEATABLE_READ
4. 串行化
ISOLATION_SERIALIZABLE
# mysql 支持四种隔离状态
默认的是 可重复读
# oracle 支持两种(读未提交和串行化)
默认的是读未提交
传播行为
# 传播行为指的是一个业务方法被另一个业务方法调用的时候,应该如何控制事务
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Obq7UV0i-1595148548408)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1571133877354.png)]
只读性
# 只读事务(只能进行查询的操作,不能进行增删改的操作)
超时时长
# 事务超时的时间,此属性需要底层的数据库的支持
他的默认值是-1 表示不限制时间
TransationStatus
事务的状态
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JhMOv8CB-1595148548411)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1571131657295.png)]
# 我们通过事务定义(TransactionDefinition) 这样的一个参数 传递个事务管理器(PlatformTransactionManager),事务管理器读取这些参数,然后进行事务管理,经过事务管理后产生一些列的事务状态(TransationStatus)
DataSourceTransactionManager
事务管理器的实现类
1. 这个实现类可以管理 mybatis 和 jdbcTemplate
2. 这个类是Spring给我们提供好的类 ,我是使用这个类需要给他传递参数
四类参数
传播行为
隔离级别
只读性
超时时长
Spring框架是一个分层的JavaSE/EE应用full-stack轻量级开源框架,以IOC和AOP为内核,提供了展现层SpringMVC和持久层SpringJDBC等技术,整合众多第三方框架,成为常用的JavaEE企业应用框架。
173万+

被折叠的 条评论
为什么被折叠?



