Spring 知识点

Spring

官网:https://spring.io/

官网下载地址:https://repo.spring.io/release/org/springframework/spring/

GitHub:https://github.com/spring-projects/spring-framework

1.1 简介

  • 2002 年 首次推出Spring框架雏形:interface21.io
  • Spring 框架以 interface21.io 为基础,于 2004 年 3 月 24 号 发布 1.0 版本
  • Spring Framework 创建人:Rod Johnson 悉尼大学 音乐出身
  • Spring 理念:使现有的技术更加容易使用
  • Spring 是为了解决企业级应用开发的复杂性而创建的,简化开发。

SSH

  • Struct2 + Spring + Hibernate

SSM

  • SpringMVC + Spring + Mybatis

Maven Jar

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.7.RELEASE</version>
</dependency>

1.2 概念

  • Spring 是一个开源的免费的框架
  • Spring 是一个轻量级的,非入侵式的框架
  • 特性:控制反转(IOC)、面向切面编程(AOP)
  • 支持事务处理,对框架整合的支持

总结:Spring 是一个轻量级的 控制反转和面向切面编程的框架

1.3 组成

Spring 框架指的是 Spring Farmework,它是很多模块的组合,使用这些模块可以很方便协助开发。这些模块是:

核心容器、数据访问、Web、AOP、工具、消息、测试模块。

Core Container 中的 Core 组件是 Spring 所有组件的核心;Beans 组件和 Context 组件是实现 IOC 和 依赖注入的基础;AOP组件用于实现面向切面编程。

六个特性:

  • 核心技术:依赖注入(DI), AOP, 事件, 资源, i18n, 验证, 数据绑定, 类型转换, SpEL
  • 测试:
  • 数据访问:事务, DAO支持, JDBC, ORM, 编组XML
  • Web支持:Spring MVC, Spring WebFlux Web 框架
  • 集成:远程处理
  • 语言:Kotlin, Groovy, 动态语言

1

  • Spring Core:基础,可以说Spring 其他所有的功能都需要依赖于该类库。主要提供 IoC 依赖注入功能。
  • Spring Aspects:该模块为与 AspectJ 集成提供支持
  • Spring AOP:面向切面编程
  • Spring JDBC:Java 数据库连接
  • Spring JMS:Java 消息服务
  • Spring ORM:用于支持 Hibernate 等 ORM 工具
  • Spring Web:为创建 Web 应用程序提供支持

1.4 拓展

  • Spring Framkwork
  • Spring Boot
    • 快速开发的脚手架
    • 基于SpringBoot 可以快速的开发单个微服务
    • 约定大于配置
  • Spring Cloud
    • SpringCloud是基于 SpringBoot 实现的

2.IOC 理论

2.1 IOC 本质

IOC: 对象由Spring来创建、管理、装配!

IOC 是一种编程思想,由主动的编程变成被动的接收

1.对象由谁创建?

  • 对象由Spring 创建

2.对象的属性由谁设置?

  • 对象的属性由Spring容器设置

这个过程就叫控制反转:

控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的

反转:程序本身不创建对象,而是被动的接收对象

依赖注入:利用Set方法来进行注入

beans.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

</beans>

样例:

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id = "useDaoImpl" class="dao.UserDaoImpl" />
    <bean id = "useMysqlDaoImpl" class="dao.UserMysqlDaoImpl" />

    <!-- ref 引用Spring容器创建好的对象,value 具体的值 -->
    <bean id="useServiceImpl" class="service.UserServiceImpl">
        <property name="userDao" ref = "useMysqlDaoImpl" />
    </bean>
</beans>

使用样例:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pojo.User;
import service.UserServiceImpl;

public class BeanTest {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

        UserServiceImpl userService = (UserServiceImpl) context.getBean("useServiceImpl");
        userService.getUserById();

        User user = (User) context.getBean("user");
        System.out.println(user.getId());
    }

}

2.2 IOC 创建对象的方式

1.使用无参构造创建对象。默认

2.有参构造创建对象

  1. 下标赋值

    <bean id="exampleBean" class="examples.ExampleBean">
        <constructor-arg index="0" value="7500000"/>
        <constructor-arg index="1" value="42"/>
    </bean>
    
  2. 类型赋值(不建议使用)

    <bean id="exampleBean" class="examples.ExampleBean">
        <constructor-arg type="int" value="7500000"/>
        <constructor-arg type="java.lang.String" value="42"/>
    </bean>
    
  3. 参数名

    <bean id="exampleBean" class="examples.ExampleBean">
        <constructor-arg name="name" value="Vincent"/>
    </bean>
    

总结:在配置文件加载的时候,容器中的对象就已经初始化了!

3.Spring 配置

3.1别名

<!-- alias 别名,可以使用别名获取对象 -->
<alias name="user" alias="usershow" />

3.2 bean 的配置

<bean id="user" class="pojo.User">
    <property name="id" value="1" />
</bean>
  • id:bean 的唯一标识符,也就是对象名
  • class:bean 对象 对应的权限定名(包名+类名)
  • name:别名

3.3 import

import 一般用于团队开发,可以将多个配置文件导入合并为一个。

<import resource="classpath:****.xml" />

4.依赖注入 DI

4.1 构造器注入

转:2.2

4.2 Set 方式注入(重点)

依赖注入本质是 Set 注入

  • 依赖:Bean 对象的创建依赖于容器
  • 注入:Bean 对象中的所有属性由容器注入

Set 注入样例

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user" class="pojo.User">
        <property name="id" value="1" />
    </bean>

    <bean id="stu" class="pojo.Student">
        <!-- 普通属性注入 -->
        <property name="name" value="Vincent" />

        <!-- 对象注入 ref  -->
        <property name="user" ref="user" />

        <!-- 数组 -->
        <property name="books">
            <array>
                <value>遮天</value>
                <value>完美世界</value>
                <value>神墓</value>
            </array>
        </property>

        <!-- List -->
        <property name="hobbys">
            <list>
                <value>BALL</value>
                <value>GAMES</value>
            </list>
        </property>

        <!-- Map -->
        <property name="card">
            <map>
                <entry key="cardno" value="1231412214"/>
            </map>
        </property>

        <!-- Set -->
        <property name="games">
            <set>
                <value>lol</value>
                <value>cf</value>
            </set>
        </property>

        <!-- 空值注入 / null 注入 -->

        <property name="wife">
            <null/>
        </property>

        <!-- Properties -->
        <property name="info">
            <props>
                <prop key="1">1111</prop>
                <prop key="2">2222</prop>
            </props>
        </property>
    </bean>

</beans>

4.3 拓展方式注入

p 命名空间 和 c 命名空间

  • 不可直接使用,需要导入 xml 配置

p 命名配置:

xmlns:p="http://www.springframework.org/schema/p"
# 使用
<bean name="p-namespace" class="com.example.ExampleBean"
        p:email="someone@somewhere.com"/>

c 命名配置:

xmlns:c="http://www.springframework.org/schema/c"
<bean id="beanOne" class="x.y.ThingOne" 
      c:thingTwo-ref="beanTwo"
      c:thingThree-ref="beanThree" 
      c:email="something@somewhere.com"/>

4.4 Bean 的作用域

image-20200620152556816

  • singleton: 唯一 bean 实例,Spring 中的 bean 默认都是 单例的。
  • prototype: 每次请求都会创建一个新的 bean 实例
  • request: 每一次Http请求都会产生一个新的bean, 该bean 仅在当前 Http request 有效
  • session: 每一次Http请求都会产生一个新的bean, 该bean 仅在当前 Http session 有效
  • global-session: 全局session作用域,仅仅在基于portlet的web应用中才有意义,Spring5已经没有了。

5.Bean 的自动装配

  • 自动装配是 Spring 装配 Bean 依赖的一种方式
  • Spring 会在上下文中自动寻找,并自动给bean装配属性

Spring 中三种装配方式

  • 在 xml 中显示装配
  • 在 java 代码中装配
  • 隐式的装配

5.1 ByName 自动装配

  • 会自动在Spring容器上下文中,查询与set属性相对于的 bean id
<bean name="p-namespace" class="com.example.ExampleBean" autowire="buName"/>

5.2 ByType 自动装配

  • 会自动在Spring容器上下文中,查找与对象类型相对于的bean
<bean name="p-namespace" class="com.example.ExampleBean"autowire="buType"/>

小结:

  • byName 需要保证所有bean 的 id 唯一,并且这个bean需要和自动注入的属性的set方法的值一致
  • byType 需要保证所有 bean 唯一,并且这个bean需要和自动注入的属性的类型一致

5.3 使用注解自动装配

使用注解配置

  • 导入约束:context
  • 添加配置
<?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:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 开启自动注入配置 -->
    <context:annotation-config/>

</beans>

@Autowired

  • 在属性上使用即可, 也可以在SET上使用
  • 可不用编写 SET 方法,

@Resource

小结:

@Autowired@Resource 区别

  • 都是用来自动装配,都可以放在属性字段上
  • @Autowired 默认通过 byType 的方式实现,对象必须存在
  • @Resource 默认通过 byName 的方式实现,如果找不到 name, 则自动通过 byType 方式找,都找不到就报错
  • 执行顺序不同:

6. 使用注解开发

@Autowired

@Resource

@Component : 组件,说明bean 被Spring容器管理了

@Value : 属性注入

@Repository: dao

@Service:service

@Controller:controller

@Scope:作用域

小结:

@Component 、@Repository、@Service、@Controller、将类注册到Spring容器中,装配Bean

配置需要扫描的包:

<context:component-scan base-package="com.**.**"/>

7. Java 配置Spring

7.1 JavaConfig

@Configuration 代表这是一个配置类,相当于beans.xml,它本身是一个 @Component 组件

@ComponentScan 自动扫描包

@Import 导入类

@Bean

8.代理模式

为什么学习代理模式?

  • Spring AOP 的底层

代理模式分类

  • 静态代理
  • 动态代理

8.1 静态代理

角色分析:

  • 抽象角色:一般使用接口或者抽象类解决
  • 真实角色:被代理的角色
  • 代理角色:代理真是角色,代理真实角色后,
  • 客户:访问代理角色的人

代理模式实现步骤:

  • 接口

    public interface Rent {
    
        public void rent();
    
    }
    
  • 真实角色

    public class Host implements Rent{
    
        @Override
        public void rent() {
            System.out.println("我要出租房子");
        }
    }
    
  • 代理角色

    public class Proxy {
    
        private Host host;
    
        public Proxy() {
        }
    
        public Proxy(Host host) {
            this.host = host;
        }
    
        public void rent(){
            host.rent();
        }
    
        public void seeHouse(){
            System.out.println("看房子");
        }
    }
    
  • 客户端访问代理角色

    public class Client {
    
        public static void main(String[] args) {
            Host host = new Host();
    
            Proxy proxy = new Proxy(host);
    
            proxy.rent();
        }
    }
    

代理模式的好处

  • 可以使真实角色的操作更加纯粹,不用关注一些公共的业务
  • 公共也就交给代理角色,实现业务的分工
  • 公共业务发生拓展的时候,方便集中管理

缺点:

  • 一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率变低

8.2 动态代理

  • 动态代理和静态代理角色一样
  • 动态代理的代理类是动态生成的,非直接写的
  • 动态代理分为两大类:基于接口的动态代理、基于类的动态代理
    • 基于接口:JDK 动态代理
    • 基于类:cglib
    • java字节码:javasist

Proxy & InvocationHandler

proxy 生成动态代理实例

InvocationHandler 调用处理程序并返回结果

InvocationHandler

image-20200621111410915

动态代理的好处:

  • 静态代理的他都有
  • 一个动态代理类代理是一个接口,一般就是对应一个业务
  • 一个动态代理可以代理多个类,只要是实现了一个接口

9.AOP

9.1 什么是AOP

AOP (Aspect Oriented Programming) : 面向切面编程

通过预编译方式和运行期动态代理实现程序功能统一维护的技术。AOP是 OOP 的延续,是Spring 框架中的一个重要内容,是函数式编程 的一种衍生范型。

利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,并提供开发效率。

image-20200621152746897

9.2 AOP在Spring中的作用

提供声明式事务,允许用户自定义切面

image-20200621152839514

image-20200621152941351

9.3Spring 实现AOP

导入 Maven 包

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.5</version>
</dependency>

方式一:Spring API 接口

    <aop:config>
​        <!-- 切入点 expression:表达式 -->
​        <aop:pointcut id="pointcut" expression="execution(* pers.vincent.service.UserServiceImp.*(..))"/>

​        <aop:advisor advice-ref="log" pointcut-ref="pointcut" />
​        <aop:advisor advice-ref="afterlog" pointcut-ref="pointcut" />
​    </aop:config>

方式二:自定义类实现

10.整合Mybatis

步骤:

  1. 导入JAR包
    • junit
    • mybatis
    • mysql 数据库连接
    • spring 相关的
    • aop
    • spring-mybatis
  2. 编写配置文件
  3. 测试

spring-database.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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- DataSoure: 使用Spring 的数据源替换 Mybatis 的配置 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/smbms?useUnicode=true&amp;characterEncoding=UTF8"/>
        <property name="username" value="root" />
        <property name="password" value="root" />
    </bean>

    <!-- sqlsessionFactory -->
    <bean id="sqlsessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configuration" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:pers/vincent/mapper/*.xml" />
    </bean>

    <!-- SqlSessionTemplate 就是 SqlSession -->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <!-- 只能使用构造器注入sqlsessionFactory, 因为它没有set方法 -->
        <constructor-arg index="0" ref="sqlsessionFactory" />
    </bean>


</beans>
  • 编写数据源
  • sqlSessionFactory
  • sqlSessionTemplate
  • 需要添加实现类

11.事务

11.1 事务的 ACID 原则

  • 原子性:事务是最小执行单位
  • 持久性:事务一旦提交,无论系统发生什么,结果都不会被影响,被持久化到存储器中
  • 一致性
  • 隔离性:多个业务可能操作一个资源,防止数据损坏

11.2 Spring 中的事务管理

  • 声明式事务:AOP (推荐事务)
    • 在配置文件中配置
      1. 基于XML的声明式事务
      2. 基于注解的声明式事务
<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        https://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- DataSoure: 使用Spring 的数据源替换 Mybatis 的配置 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/smbms?useUnicode=true&amp;characterEncoding=UTF8"/>
        <property name="username" value="root" />
        <property name="password" value="root" />
    </bean>

    <!-- sqlsessionFactory -->
    <bean id="sqlsessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configuration" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:pers/vincent/mapper/*.xml" />
    </bean>

    <!-- SqlSessionTemplate 就是 SqlSession -->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <!-- 只能使用构造器注入sqlsessionFactory, 因为它没有set方法 -->
        <constructor-arg index="0" ref="sqlsessionFactory" />
    </bean>

    <!-- 配置声明式事务 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.">
                                         
    </bean>

    <!-- 结合 AOP 实现事务的织入 -->
    <!-- 配置事务的通知 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!-- 给哪些方法配置事务 -->
        <!-- 配置事务的传播特性: propagation-->
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

    <!-- 配置事务切入 -->
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* pers.vincent.mapper.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
    </aop:config>

</beans>
  • 编程式事务:(不推荐使用)

    • 在代码里硬编码

为什么需要事务?

  • 如果不配置事务,可能存在数据提交不一致的情况
  • 事务在开发过程中十分重要,涉及到数据的一致性和完整性

11.3 Spring 事务中的隔离级别

TransactionDefinition 接口定义了五个表示隔离级别的常量

  • TransactionDefinition.ISOLATION_DEFAULT: 使用后端数据库默认的隔离级别。

    MySQL 默认采用的REPEATABLE_READ;Oracle 默认采用 READ_COMMITTED

  • TransactionDefinition.ISOLATION_READ_UNCOMMITTED: 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读

  • TransactionDefinition.ISOLATION_READ_COMMITTED: 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍可能发生

  • TransactionDefinition.ISOLATION_REPEATABLE_READ: 对同一个字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以组织脏读和不可重复读,但幻读仍有可能发生。

  • TransactionDefinition.ISOLATION_SERIALIZABLE: 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读,不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

12. 相关问题

@RestController 和 @Controller

@RestController

  • 相当于:@Controller + @ResponseBody

  • RESTful Web 服务

  • 返回 JSON 和 XML 形式数据:对象数据直接以 JSON 和 XML 形式写入 HTTP 响应(Response)

  • 对应 前后端分离

@Controller

  • 单独使用不加 @ResponseBody 的话,一般使用再要返回一个视图的情况,传统的 SpringMVC 应用,前后端不分离

Spring IOC 和 Spring AOP

Spring IOC

  • 控制反转:是一种思想,将原本在程序中手动创建对象的控制权交由 Spring 管理。
  • IoC 容器是 Spring 用来实现 IoC 的载体,IoC 容器实际上就是 Map, Map 中存放的是各种对象。
  • 将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入。
  • 初始化过程:
    • 配置XML文件
    • 读取Resource
    • 解析 BeanDefinition
    • 注册 BeanFactory

Spring AOP

  • 面向切面编程:将业务模块需要共同调用的逻辑或责任(例如事务管理、日志管理、权限控制等)封装起来,便于减少系统的代码重复,降低模块间的耦合度,并有利于未来的可拓展性和可维护性
  • 基于动态代理

Spring AOP 和 AspectJ AOP

  • Spring AOP 是基于动态代理,属于运行时增强
    • 以集成 AspectJ, AspectJ 算的上是 Java 生态系统中最完整的 AOP 框架
  • AspectJ AOP 是基于字节码操作,属于编译时增强

Spring Bean

1.Spring 中的单例 bean 的线程安全问题了解吗?

主要是因为当多个线程操作同一个对象的时候,对这个对象的非静态成员变量的写操作会存在线程安全问题。

解决方法:

在类中定义一个 ThreadLocal 成员变量,将需要的可变成员变量保存在 ThreadLocal 中

@Component 和 @Bean 的区别是什么?

  • 作用对象不同:@Component 注解作用于类,而@Bean注解作用于方法
  • @Component 通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中;@Bean 注解通常是我们在标有该注解的方法中定义产生这个 bean, @Bean 告诉了Spring这是某个类的示例,当我们需要用他的时候还给我。

将一个类声明为 Spring 的 bean 的注解有哪些??

  • @Autowired: 自动装配bean
  • @Component: 可标注任意类为 Spring 组件
  • @Service: 用于服务层
  • @Resposity: 对应持久层即 Dao 层,主要用于数据库操作
  • @Controller: 对应控制层

Spring Bean 的生命周期

Spring 框架中用到了哪些设计模式?

  • 工厂设计模式:Spring 使用工厂模式通过 BeanFactory、ApplcationContext 创建 Bean 对象
  • 代理设计模式:Spring AOP 功能实现
  • 单例设计模式:Spring 中的Bean默认都是单例的
  • 包装器设计模式:项目需连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。
  • 观察者模式:Spring 事件驱动模型就是观察者模式很经典的应用
  • 适配器模式:Spring AOP 的增加或通知使用到了适配器模式;SpringMVC 中的也是用到适配器模式 Controller

@Transactional(rollbackFor = Exception.class) 注解

Exception 分为 RuntimeException 和 非运营时异常。事务管理至关重要,即使出现异常情况,它也可以保证数据的一致性。

@Transactional 注解作用于类上时,该类的所有 public 方法都将具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。如果类和方法上都加了这个注解,那么这个类里面的方法抛出异常,就会回滚,数据库里面的数据也会回滚。

@Transactional 不配置 rollbackFor 属性,那么只会遇到 RuntimeException 时才会回滚;配置 rollbackFor = Exception.class 时,那么在非运行时异常时也会进行回滚。

相关文章:https://developer.ibm.com/zh/articles/j-master-spring-transactional-use/

原文地址:https://www.cnblogs.com/blackBlog/p/13451738.html