第一章 Spring概述

Spring框架是什么

Spring是一个框架,核心是IOC(控制反转)和AOP(面向切面编程)。
主要作用是降低代码之间的耦合度。

Spring的优点

  1. 轻量
  2. 针对接口编程,解耦合
  3. AOP编程的支持
  4. 方便集成各种优秀框架

    怎样使用Spring

  5. Spring是一个容器,把项目中用的对象放入容器中。

  6. 让容器完成对象的创建,对象之间关系的管理(属性赋值)。
  7. 我们在程序中从容器中获取要使用的对象。

    应该放入容器中的对象

  8. dao类,service类,controller类,工具类。

  9. Spring中的对象默认都是单例的,在容器中叫这个名称的对象只有一个。

    不应该放入容器中的对象

  10. 实体类对象,实体类的数据来源于数据库。

  11. Servlet,listener,filter等。

    第二章 IOC 控制反转⭐

    什么是控制反转

    假如有 a 和 b 两个对象,在注入 IOC 之前,a 依赖于 b 那么对象 a 在初始化或者运行到某一点的时候,自己必须主动去创建对象 b 或者使用已经创建的对象 b ,无论是创建还是使用对象 b ,控制权都在自己手上 。
    而注入 IOC 之后就变了,对象 a 与对象 b 之间失去了直接联系,当对象 a 运行到需要对象 b 的时候,IOC 容器会主动创建一个对象 b 注入到对象 a 需要的地方。其实通过上边这个举例可以很明显的就看出来,对象 a 获得依赖对象 b 的过程,由主动行为变为了被动行为,控制权颠倒过来了,这就是“控制反转”这个名称的由来。

    依赖注入(DI)是什么

    开发人员在项目中只需要提供对象的名称。对象的创建,查找,赋值都由容器内部自己来实现。
    Spring框架使用di实现了ioc。
    Spring底层使用的是反射机制。

⭐第一个Spring项目-使用步骤

  1. 引入maven依赖

image.png

  1. 定义接口与实体类
  2. 创建Spring配置文件

在src/main/resources/目录下创建一个xml文件
image.png
推荐命名:applicationContext.xml

  1. Spring配置文件的编写

image.png

  1. 定义测试类

image.png
① 从类路径开始算。 类路径-target-classes
② ClassPathXmlApplicationContext-表示从类路径下加载Spring的配置文件
在创建Spring容器时,会创建配置文件中的所有的对象。
getBean()-获取容器中的对象
getBeanDefinitionCount()-获取容器中定义的对象的数量
getBeanDefinitionNames()-获取容器中每个定义的对象的名称
④ 无

基于XML的DI

在Spring的配置文件中,使用标签和属性完成。

注入分类

bean 实例在调用无参构造器创建对象后,就要对 bean 对象的属性进行初始化。初始化
是由容器自动完成的,称为注入。
分为:① set注入 ② 构造注入

set注入(常用)

set 注入也叫设值注入是指,通过 setter 方法传入被调用者的实例。

  1. 简单类型(基本数据类型+String)


image.png
②使用进行赋值
image.png
注:只要有set方法,就可以赋值。 就算没有定义该属性。
③测试类
image.png

  1. 引用类型

当指定 bean 的某属性值为另一 bean 的实例时,通过 ref 指定它们间的引用关系。
ref的值必须为某 bean 的 id 值 。

image.png
② 声明School对象
image.png
③ 使用property标签的ref属性,对其他bean对象进行引用。
image.png

image.png

构造注入(理解)

构造注入是指,在构造调用者实例的同时,完成被调用者的实例化。即,使用构造器设置依赖关系 。
①在实体类中添加有参构造方法。
image.png
②声明school对象
image.png
③使用进行赋值
image.png
标签中用于指定参数的属性 :
name:与实体类中有参构造的形参名一致。
index: 根据实体类中有参构造的形参顺序编号(从0开始)
value:与前面用法一致
ref:与前面用法一致
④测试类

引用类型属性自动注入

byName方式自动注入

当配置文件中的bean的id值与bean类的属性名相同时,可以使用byName的方式。

①实体类
image.png
②声明School对象
image.png
③通过为标签 设置 autowire 属性值,为引用类型属性进行隐式自动注入
image.png
④测试类
image.png

byType的方式自动注入

要求:

  1. 配置文件中被调用者 bean 的 class 属性指定的类,要与代码中调用者 bean 类的某引用类型属性类型同源。即要么相同,要么有 is-a 关系(子类,或是实现类)。
  2. 这样的同源的被调用 bean 只能有一个。多于一个,容器就不知该匹配哪一个了。

什么叫同源?

  1. java类中引用类型的数据类型和bean的calss值一样。
  2. java类中引用类型的数据类型和bean的calss值是父子类关系。
  3. java类中引用类型的数据类型和bean的calss值是接口和实现类的关系。

①实体类
image.png
②声明school对象
image.png
③通过为标签 设置 autowire 属性值,为引用类型属性进行隐式自动注入
image.png
④测试类
image.png

为应用指定多个Spring配置文件

优势:

  1. 每个文件的大小比一个文件小很多,效率高。
  2. 避免多人开发带来的冲突。

多文件的分配方式:

  1. 按功能模块,一个模块一个配置文件。
  2. 按类的功能,数据相关的一个配置文件,事务功能的一个配置文件,Service功能的一个配置文件。

①根据功能编写多个配置文件
image.png
image.png
image.png
image.png
②在总配置文件下通过引入多个子配置文件。
image.png
image.png
classpath:表示类路径下(target/classes)

引入时也可以使用通配符
image.png
*要求:

  1. 父配置文件名不能满足*所能匹配的格式,否则将出现循环递归包含。

就本例而言,父配置文件不能匹配 spring-*.xml 的格式,即不能起名为spring-total.xml

  1. 如果要使用通配符*,必须在resources目录下建一个文件夹统一管理。

不可以直接放在resources下!

基于注解的DI⭐

使用Spring中的注解,完成属性赋值。

7个注解

  1. @Component
  2. @Repository
  3. @Service
  4. @Controller
  5. @Value
  6. @Autowired
  7. @Resource

    步骤

  8. 加入maven依赖spring-context,间接加入了spring-aop依赖(使用注解必备)。

  9. 在类中加入spring的注解。
  10. 在spring的配置文件中,加入一个组件扫描器(component-scan)的标签,说明注解在你项目中的位置。

    配置组件扫描器

    在 Spring 配置文件中配置组件扫描器,用于在指定在基本包中扫描注解。
    快捷键:com
    image.png

    指定多个包的3种方式

  11. 使用多个 context:component-scan 指定不同的包路径

image.png

  1. 在指定 base-package 的值时使用分隔符写多个值

分隔符可以使用逗号(,)分号(;)还可以使用空格,不建议使用空格。
image.png

  1. base-package 指定到父包名

base-package 的值表是基本包,容器启动会扫描包及其子包中的注解,当然也会扫描到
子包下级的子包。所以 base-package 可以指定一个父包就可以 。
image.png
也可以指定最顶级的包
image.png
不建议:使用顶级的父包,扫描的路径比较多,导致容器启动时间变慢。
建议:指定到目标包和合适的。也就是注解所在包全路径。

@Component-创建对象的注解

需要在类上使用注解@Component,该注解的 value 属性(可省略)用于指定该 bean 的 id 值。

image.png

什么时候用@Component呢?
不是dao层的,不是Service层的,不是Controller层的,但需要创建对象时。

@Component 不指定 value 属性, bean 的 id 是类名的首字母小写。
image.png


另外3个创建对象的注解

语法与@Component相同。
image.png
这三个注解与@Component 都可以创建对象,但这三个注解还有其他的含义,可以给项目的对象分层。

@Value-简单类型的属性注入

需要在属性上使用注解@Value,该注解的 value 属性(String类型的,都要用” “)用于指定要注入的值。
位置:

  1. 使用该注解完成属性注入时,类中无需 setter。
  2. 若属性有 setter,则也可将其加到 setter 上。

eg:
image.png

引用类型属性自动注入

@Autowired-byType自动注入

在引用属性上使用注解@Autowired,该注解默认使用按类型自动装配 Bean 的方式。

image.png

@Autowired与@Qualifier-byName自动注入

在引用属性上联合使用注解@Autowired 与@Qualifier。 (无先后顺序)
@Qualifier 的 value 属性用于指定要匹配的 Bean 的 id 值。
image.png
属性required
@Autowired 还有一个属性 required,默认值为 true,表示当匹配失败后,会终止程序运行。
若将其值设置为 false,则匹配失败,将被忽略,未匹配的属性值为 null 。
image.png

@Resources-JDK注解自动注入⭐

  1. Spring提供了对 jdk中@Resource注解的支持。
  2. @Resource 注解既可以按名称匹配Bean,也可以按类型匹配 Bean。默认是按名称注入。
  3. 使用该注解,要求 JDK 必须是 6 及以上版本。
  4. @Resource 可在属性上,也可在 set 方法上。

(1)byType 注入引用类型属性
@Resource 注解若不带任何参数, 采用默认按名称(byName)的方式注入。
按名称不能注入 bean,则会按照类型(byType)进行 Bean 的匹配注入。
image.png
(2)byName注入引用类型属性
@Resource 注解指定其 name 属性,则 name 的值即为按照名称进行匹配的 Bean 的 id。
image.png

注解与xml的对比

注解为主,xml为辅。
注解的优缺点:
image.png
xml的优缺点:
image.png

第三章 AOP 面向切面编程⭐

概述

AOP就是动态代理的规范化,把动态代理的实现步骤、方式都定义好了。
让开发人员用一种统一的方式使用动态代理。

AOP简介

AOP(Aspect Orient Programming),面向切面编程。
面向切面编程:就是将交叉业务逻辑封装成切面,利用AOP容器的功能将切面织入到主业务逻辑中。
交叉业务逻辑:是指通用的,与主业务逻辑无关的代码。例如事务,日志等。
AOP的底层就是采用动态代理模式实现的:JDK的动态代理和CGLIB的动态代理。

AOP三要素:

  1. - 切面的功能代码,切面要干什么?(Aspect表示)
  2. - 切面的执行位置,哪个类?哪个方法?(Pointcut表示)
  3. - 切面的执行时间,在目标方法前执行还是目标方法后执行?(Advice表示)

AOP的作用

  • 在目标类源代码不改变的情况下,增加功能。
  • 减少代码的重复
  • 专注业务逻辑代码
  • 解耦合,让你的业务功能和日志,事务非业务功能分离。

注意:AOP只是面向对象编程的一种补充。

什么时候使用AOP⭐

  1. 当你要给一个系统中已经存在的类修改功能,但是你没有源代码时,使用aop增加功能。
  2. 当你要给项目中的多个类增加一个相同的功能时,使用aop。
  3. 给业务方法增加事务,日志输出等功能时,使用aop。

    AOP编程术语⭐

  4. 通知/增强(Advice)

通知表示切面的执行时间,Advice也叫增强。定义切入的时间。

  1. 连接点(JointPoint)

通常业务接口中的方法均为连接点。

  1. 切入点(Pointcut)

让切点来筛选连接点,选中那几个你想要的方法。定义切入的位置。

  1. 切面(Aspect)

切面是通知和切入点的结合。
Advice→切面的执行时间,在目标方法前执行还是目标方法后执行?
Pointcut→切面的执行位置,哪个类?哪个方法?

  1. 目标对象(Target)
    目标对象指将要被增强的对象。

    AspectJ对AOP的实现⭐

    AspectJ 是一个优秀面向切面的框架, 它扩展了 Java 语言,提供了强大的切面实现。

    AspectJ的通知(Advice)类型

    切面的执行时间
  • @Before-前置通知
  • @AfterReturning-后置通知
  • @Around-环绕通知
  • @AfterThrowing-异常通知
  • @After-最终通知

    ⭐AspectJ的切入点(Pointcut)表达式

    切面的执行位置
    AspectJ 定义了专门的表达式用于指定切入点。
    表达式的原型:
    execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
    ?:表示可有可无。
    modifiers-pattern:访问权限类型 [public之类的]
    ret-type-pattern:返回值类型 [void之类的] 必有!
    declaring-type-pattern:包名类名 [com.mu.player]
    name-pattern(param-pattern):方法名(参数类型参数个数) [ sellUsb(int amount) ] 必有!
    throws-pattern: 抛出异常类型
    以上表达式共4个部分:
    execution(访问权限 方法返回值 方法名(参数) 异常类型)
    注意:表达式中的黑色文字表示可省略部分,各部分使用空格隔开。
    在其中也可以使用以下符号:
符号 意义
* 0至多个任意字符
.. 在方法参数中→表示任意多个参数
在包名后,表示当前包及其子包路径
+ 在类名后,表示当前类及其子类
在接口后,表示当前接口及其实现类

eg:

  • execution(public (..))

指定切入点为:任意的公共方法。

  • execution( set(..))

指定切入点为:任意的以“set”开头的方法。

  • execution( com.mu.service..*(..))

指定切入点为:service包下的任意类的任意方法。

  • execution( com.mu.service...*(..))

指定切入点为:service和其子包下的任意类的任意方法。
注:”..”出现在类名中时,后面必须跟”*”,表示包和其子包下的所有类。

  • execution( ..service..(..))

指定切入点为:所有包下的service包下的任意类的任意方法。

⭐AspectJ基于注解的AOP实现

AspectJ 对于 AOP 的实现有注解和配置文件两种方式,常用是注解方式。
使用AOP的目的:在不改变原来的类的代码的前提下,给已经存在的一些类和方法,增加额外的功能。

基本实现步骤-@Before

后面的通知步骤只有第三步的区别!

  1. 添加maven依赖


<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>

  1. 定义业务接口与目标类
  2. 创建切面类

@AspectJ

  • 是aspectJ框架的注解
  • 作用是表示当前类是切面类
  • 切面类:用来给业务方法增加功能的类。
  • 位置:在类定义的上方

在切面类(@Before)中定义方法的要求:

  • 必须是public的
  • 必须是void的
  • 方法名称自定义。
  • 方法可以无参,可以有参

但如果有参,参数不可以自定义,有几个参数类型可以选择。
@Before

  • 属性:value,是切入点表达式,表示切面的功能的执行位置(execution)
  • 位置:用于方法之上
  • 作用:表示切面功能的执行时间

image.png

  1. 在spring的配置文件中声明对象,把对象交给容器统一管理。
    1. 声明对象可以选择使用注解或者xml配置文件方式。

此处由第二章知识书写。

  1. 在spring的配置文件中声明自动代理生成器。

用来完成代理对象的自动创建功能。
image.png

  1. 测试类

image.png

@Before-方法有JoinPoint参数

作用:可以在通知方法中获取方法执行时的信息,例如方法的定义,方法的参数等信息。
何时用:当你的切面功能中需要用到方法的信息时,就加入JoinPoint参数。
要求:如果用,必须作为第一个参数出现。
image.png
输出结果:
image.png

@AfterReturning-注解有returning属性

在@AfterReturning中定义方法的要求:

  • 必须是public的
  • 必须是void的
  • 方法名称自定义。
  • 方法是有参数的,推荐使用Object类型,参数名自定义。

@AfterReturning

  • 属性:value,是切入点表达式,表示切面的功能的执行位置(execution)

    returning:自定义的变量,表示目标方法的返回值的。
    自定义变量名必须和通知方法的形参名一样。

  • 位置:用于方法之上

  • 作用:表示切面功能的执行时间
  • 特点:

    • 在目标方法之后执行
    • 能够获取目标方法的返回值,可以根据这个返回值做不同的处理功能。
    • 可以修改这个返回值。(并不能真正改变,因为java是值传递。目标方法的返回值不会被改变。)
      image.png

      @Around-通知方法有ProceedingJoinPoint

      在@Around中定义方法的要求:
  • 必须是public的

  • 必须有返回值,推荐使用Object
  • 方法名称自定义。
  • 方法是有参数的,固定的参数→ProceedingJoinPoint

因为ProceedingJoinPoint继承了JoinPoint,所以JoinPoint有的功能它都有,比如获取参数等。
@Around

  • 属性:value,是切入点表达式,表示切面的功能的执行位置(execution)
  • 位置:用于方法之上
  • 作用:表示切面功能的执行时间
  • 特点:
    • 它是功能最强的通知。
    • 在目标方法的前和后都能增强功能。
    • 可以控制目标方法的执行。
    • 可以修改原来的目标方法的执行结果,影响最后的调用结果。
    • 环绕通知等同于jdk动态代理的InvocationHandler接口,

pjp.proceed() = method.invoke(target,args)
返回值: 就是目标方法的执行结果,可以被修改。

  • 经常用于事务, 在目标方法之前开启事务,执行目标方法, 在目标方法之后提交事务

    image.png

    了解-@AfterThrowing-注解中有throwing属性

    在@AfterThrowing中定义方法的要求:

  • 必须是public的

  • void
  • 方法名称自定义。
  • 方法有参数→Throwable

@AfterThrowing

  • 属性:value,是切入点表达式,表示切面的功能的执行位置(execution)

    throwinng 自定义的变量,表示目标方法抛出的异常对象。
    变量名必须和方法的参数名一样

  • 位置:用于方法之上

  • 作用:表示切面功能的执行时间
  • 特点:
    • 在目标方法抛出异常时执行的
    • 可以做异常的监控程序, 监控目标方法执行时是不是有异常。

如果有异常,可以发送邮件,短信进行通知。
image.png

了解-@After

无论目标方法是否抛出异常,该增强均会被执行。
在@After中定义方法的要求:

  • 必须是public的
  • void
  • 方法名称自定义。
  • 方法没有参数

@After

  • 属性:value,是切入点表达式,表示切面的功能的执行位置(execution)
  • 位置:用于方法之上
  • 作用:表示切面功能的执行时间
  • 特点:
    • 总是会执行
    • 在目标方法之后执行的
    • 一般做资源清除工作的。

image.png

@Pointcut定义切入点

当较多的通知增强方法使用相同的 execution 切入点表达式时,编写、维护均较为麻烦。
用法:

  • 将@Pointcut 注解在一个方法之上,以后所有的execution的 value 属性值均可使用该方法名作为切入点.
  • 这个使用@Pointcut 注解的方法一般使用 private 的标识方法,即没有实际作用的方法。

image.png

cglib代理

在没有接口时,AspectJ会自动使用cglib代理,步骤没啥区别。

在有接口时,默认使用jdk代理,若要强制使用cglib代理(效率高一些):
image.png

第四章 Spring集成MyBatis

概述

原理:使用ioc实现
Spring帮mybatis创建的3个对象:

  1. 阿里的druid连接池
  2. SqlSessionFactory对象
  3. dao对象

Spring整合mybatis,事务是自动提交的。

步骤

1.添加Maven依赖(8个)

  1. 测试依赖
  2. Spring依赖
  3. Spring事务相关依赖-2个
  4. mybatis依赖
  5. mybatis-spring集成依赖

用来在spring项目中创建mybatis的SqlsessionFactory,dao对象的。

  1. mysql驱动
  2. 阿里数据库连接池

image.png
image.png

2.创建数据库相关实体类

image.png

3.定义相关dao接口和mapper映射文件

image.png
image.png

4.创建mybatis主配置文件

image.png

5.定义Service接口和实现类

image.png
image.png

6.创建spring的配置文件:声明mybatis的对象交给spring创建

image.png
image.png
image.png

7.创建测试类,获取Service对象,通过service调用dao完成数据库的访问

image.png

第五章 Spring事务

概述

  1. 什么是事务?

事务是指一组sql语句的集合, 集合中有多条sql语句 可能是insert , update ,select ,delete,这些操作作为一个整体一起向系统提交,要么都执行,要么都不执行。
如果不使用事务,当报异常时,数据扔会被添加到表中。

  1. 什么时候使用事务?

当操作涉及到多个表或者多个sql语句的insert,delete,update。需要这些语句都成功或者都失败才能完成某项功能时,需要使用事务。 例如:转账

  1. 之前事务的处理方式,有什么不足?

多种数据库的访问技术,有不同的事务处理的机制,对象,方法。学习成本太高。

  1. 如何解决之前的不足?

    spring提供一种处理事务的统一模型,能使用统一步骤的方式,完成多种不同数据库访问技术的事务处理。

    Spring的事务管理

    事务原本是数据库中的概念,在 Dao 层。但一般情况下,需要将事务提升到业务层,即 Service 层。
    这样做是为了能够使用事务的特性来管理具体的业务。
    Spring中实现对事务管理的两种方式:

    1. 使用Spring的事务注解管理事务
    2. 使用AspectJ的AOP配置管理事务

      Spring事务管理的两个接口

      事务管理器接口-PlatformTransactionManager

      PlatformTransactionManager:事务管理器接口,主要用于事务的commit,rollback和获取事务的状态信息.

      常用的两个实现类

  2. DataSourceTransactionManager:使用JDBC或MyBatis进行数据库操作时使用。

  3. HibernateTransactionManager:使用Hibernate进行持久化操作。

    Spring的回滚方式

    Spring 事务的默认rollback方式是:

    1. 发生运行时异常和error时,rollback。
    2. 当你的业务方法,执行成功,没有异常抛出,当方法执行完毕时,commit。
    3. 发生编译时异常时,commit。 对于编译时异常,程序员也可以手工设置其回滚方式。

      回顾异常与错误

      运行时异常:RuntimeException和他的子类都是运行时异常,例如NullPointException,NumberFormatException.
      编译时异常:在你写代码中,必须处理的异常。例如IOException, SQLException.
      自定义异常:继承RuntimeException-运行时异常;继承Exception-编译时异常。

      事务定义接口-TransactionDefinition

      TransactionDefinition:事务定义接口,定义了描述事务的三类常量:
      ①事务隔离级别 ②事务传播行为 ③ 事务默认超时时限

      事务隔离级别常量(5个)

      这些常量均以-ISOLATION_ 开头,格式为→ISOLATION_XXX
  4. DEFAULT:采用 DB 默认的事务隔离级别。

    MySql 的默认为 REPEATABLE_READ;Oracle默认为 READ_COMMITTED。

  5. READ_UNCOMMITTED: 读未提交。未解决任何并发问题。

  6. READ_COMMITTED: 读已提交。解决脏读,存在不可重复读与幻读。
  7. REPEATABLE_READ: 可重复读。解决脏读、不可重复读,存在幻读。
  8. SERIALIZABLE: 串行化。不存在并发问题。

    事务传播行为常量(7个)

    事务传播行为:处于不同事务中的方法在相互调用时,执行期间事务的维护情况。
    这些常量均以-PROPAGATION_ 开头,格式为→PROPAGATION_XXX

  9. PROPAGATION_REQUIRED(默认)

    1. 若当前存在事务,就加入到当前事务中;若当前没有事务,则创建一个新事务。
    2. Spring默认的事务传播行为。

image.png

  1. PROPAGATION_REQUIRES_NEW
    1. 若当前存在事务,就加入到当前事务中;若当前没有事务,可以以非事务方式执行。

image.png

  1. PROPAGATION_SUPPORTS
    1. 总是新建一个事务。
    2. 若当前存在事务,就将当前事务挂起,直到新事务执行完毕。

image.png

  1. PROPAGATION_MANDATORY
  2. PROPAGATION_NESTED
  3. PROPAGATION_NEVER
  4. PROPAGATION_NOT_SUPPORTED

    事务默认超时时限

    常量 TIMEOUT_DEFAULT 定义了事务底层默认的超时时限, sql 语句的执行时长。
    注:事务的超时时限起作用的条件比较多,且超时的时间计算点较复杂。所以,该值一般就使用默认值即可.

    程序举例环境搭建

    实例:购买商品trans_sale项目
    本例要实现购买商品,模拟用户下订单,向订单表添加销售记录,从商品表减少库存。

  5. 创建数据库表-sale,goods

  6. 添加maven依赖
  7. 编写dao接口和其mapper文件
  8. 编写mybatis主配置文件
  9. 编写自定义异常类
  10. 定义service接口和实现类
  11. 编写Spring配置文件
  12. 测试

Spring的事务注解管理事务-@Transactional

概述

  1. 适用于中小型项目
  2. 通过@Transactional 注解方式, 可将事务织入到相应 public 方法中,实现事务管理。
  3. @Transactional 若用在方法上,只能用于 public 方法上。
  4. 若@Transaction 注解在类上,则表示该类上所有的方法均将在执行时织入事务。
  5. 底层使用的是AOP机制,AOP的环绕通知。

    @Transactional的可选属性

  6. propagation:用于设置事务传播属性。该属性类型为 Propagation 枚举,

    默认值为Propagation.REQUIRED。

  7. isolation:用于设置事务的隔离级别。该属性类型为 Isolation 枚举,默认值为Isolation.DEFAULT。

  8. timeout:用于设置事务的默认超时时限。单位为秒,类型为 int,默认值为-1,即没有时限。

  9. readOnly:用于设置该方法对数据库的操作是否是只读的。该属性为 boolean,默认值为 false。

  10. rollbackFor:指定需要回滚的异常类。类型为 Class[],默认值为空数组。

当然,若只有一个异常类时,可以不使用数组。
运行时异常不需要指定。一般是想要给编译时异常进行rollback,才写此类属性。

  1. rollbackForClassName:指定需要回滚的异常类类名。类型为 String[],默认值为空数组。

    当然,若只有一个异常类时,可以不使用数组。

  2. noRollbackFor:指定不需要回滚的异常类。

  3. noRollbackForClassName:指定不需要回滚的异常类类名。

    步骤

  4. 声明事务管理器image.png

  5. 开启注解驱动

image.png

  1. 在业务层的public方法上加入事务属性

image.png

  1. 测试类

    AspectJ的AOP配置管理事务

    概述

  2. 适用于大型项目

  3. 这种方式将业务方法和事务配置完全分离。

    步骤

  4. 在之前项目的基础上添加AspectJ依赖


org.springframework
spring-aspects
5.2.5.RELEASE
  1. 声明事务管理器

image.png

  1. 配置事务通知

如果使用默认的话,propagation之类的属性不用写。
image.png
添加:add 修改:modify 删除:remove 查询:query

  1. 配置aop,通知应用的切入点

image.png

  1. 测试类

    第六章 Spring与Web

    问题:Spring容器对象不唯一。
    需求:web项目中容器对象只需要创建一次, 把容器对象放入到全局作用域ServletContext中。
    实现:使用监听器 当全局作用域对象被创建时 创建容器 存入ServletContext。

    基本步骤

  2. 创建maven项目-web模板,添加java文件和resources文件。

  3. 配置Tomcat
  4. 在之前的依赖基础上,添加Servlet依赖和jsp依赖。



javax.servlet
javax.servlet-api
3.1.0
provided



javax.servlet.jsp
jsp-api
2.2.1-b03
provided

  1. 编写JSP页面
  2. 解决web.xml版本过低问题
    1. 先删除自带的web.xmlimage.png
    2. 新建web.xml

image.png

  1. 再将名称改为-web.xml

    使用Spring的监听器ContextLoaderListener(重点)

  1. 添加maven依赖-Spring-web依赖。


<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>

  1. 在web.xml中注册监听器

image.png

  1. 指定Spring配置文件的位置

ContextLoaderListener 在对 Spring 容器进行创建时,需要加载 Spring 配置文件。其默认的 Spring 配置文件位置与名称为: WEB-INF/applicationContext.xml。但是,一般会将该配置文件放置于项目的 classpath 下,即 src 下,所以需要在 web.xml 中对 Spring 配置文件的位置及名称进行指定。
image.png

  1. 编写Servlet代码-获取Spring容器对象
    1. 直接从ServletContext中获取Spring容器对象image.png
    2. 通过WebApplicationContextUtils获取Spring容器对象image.png
  2. 完整的Servlet代码 ```java package com.mu.controller;

import com.mu.pojo.Student; import com.mu.service.StudentService; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;

public class RegisterServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取请求参数 String id = request.getParameter(“id”); String name = request.getParameter(“name”); String email = request.getParameter(“email”); String age = request.getParameter(“age”);

/ //获取Spring容器对象-直接从ServletContext中获取 1️⃣ String attr = WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE; WebApplicationContext ac = (WebApplicationContext) this.getServletContext().getAttribute(attr);/

    //通过WebApplicationContextUtils获取Spring容器对象 2️⃣
    WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());

    //获取Service
    StudentService service = (StudentService) ctx.getBean("studentService");
    Student student  = new Student();
    student.setId(Integer.parseInt(id));
    student.setName(name);
    student.setEmail(email);
    student.setAge(Integer.valueOf(age));
    service.addStudent(student);

    //跳转注册成功页面
    request.getRequestDispatcher("/result.jsp").forward(request,response);

}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

}

}

```