1 spring简介
1.1 官网API:
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-p-namespace
1.2 控制反转:
将组件对象的控制权由代码本身转移到外部容器。发现传统方式,如果切换了实现类就必须在代码中更改实现类,这种方式就是耦合度很高,违反了spring的思想,组件化配置。
2 spring程序开发
2.1 添加依赖 spring-webmvc
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.6</version>
</dependency>`
2.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
2.3 在spring配置文件中配置userdaoimpl
<bean id="usreMapper" class="cn.hxzy.dao.impl.UserMapperImpl"></bean>
2.4 使用spring的API获得bean的实例
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
public boolean save() {
UserMapper userMapper = (UserMapper) context.getBean("userMapper");
Integer count = userMapper.save();
if (count > 0) {
return true;
}
return false;
}
3 依赖注入
3.1 构造方法注入
3.1.1 按照构造函数的参数索引值位置进行注入
<bean id="user" class="cn.hxzy.pojo.User">
<constructor-arg index="0" value="zhangsan"/>
<constructor-arg index="1" value="20"/>
</bean>
3.1.2 按照构造函数的参数进行注入
注意,如果按类型进行匹配注入,配置的是基本数据类型,则在class中定义的属性也必须为基本数据类型。如果为包装类,定义的时候也必须为包装类型
<bean id="user" class="cn.hxzy.pojo.User">
<constructor-arg type="java.lang.String" value="lisi"/>
<constructor-arg type="java.lang.Integer" value="24"/>
</bean>
bean标签的作用范围
singleton | 默认的,单例的 |
---|---|
prototype | 多例的 |
request | SpringWeb应用中,创建一个bean对象后,存入到request作用域 |
session | SpringWeb应用中,创建一个bean对象后,存入到sessiont作用域 |
3.1.3 引入注入
<bean id="user" class="cn.hxzy.pojo.User">
<constructor-arg index="0" value="zhangsan"/>
<constructor-arg index="1" value="20"/>
<constructor-arg ref="dog"/>
</bean>
<bean id="dog" class="cn.hxzy.pojo.Dog">
<constructor-arg index="0" value="旺财"/>
<constructor-arg index="1" value="3"/>
</bean>
3.2 设值注入
3.2.1 properties属性注入
setter器
public void setUserName(String userName) {
this.userName = userName;
}
xml配置
<bean id="stu" class="cn.hxzy.pojo.Student">
<property name="userName" value="qyy"/>
</bean>
3.2.2 p-namespace p命名空间注入
配置的头文件引用
xmlns:p="http://www.springframework.org/schema/p"
3.3 注入复杂数据类型
<bean id="data" class="cn.hxzy.news.test.DataCategroy">
<property name="strs">
<array>
<value>html</value>
<value>vue</value>
<value>spring</value>
</array>
</property>
<property name="list">
<list>
<value>java</value>
<value>jdbc</value>
<value>maven</value>
</list>
</property>
<property name="map">
<map>
<entry key="ch" value="中国"/>
<entry key="en" value="英国" />
<entry key="us" value="美国"/>
<entry key="ru" value="俄罗斯"/>
</map>
</property>
</bean>
4 bean的自动装配方式
<bean id="user" class="cn.hxzy.pojo.User" autowire="byName">
<property name="userName" value="zhangsan"/>
<property name="userAge" value="30"/>
<property name="userId" value="100"/>
</bean>
<bean id="dog" class="cn.hxzy.pojo.Dog">
<property name="dogColor" value="黄色"/>
<property name="dogName" value="旺财"/>
</bean>
byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid。
byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean,如果在容器存在相同类型的对象,则不能使用byType。
使用Java的注解也必须在spring配置文件中配置context约束
@Resource与@Autowired的区别:
@Resource是java的注解,默认是按照名称进行装配,相当于是@Autowired加@Qualifier(value = "user")的合体
@Autowired是spring的注解,默认是按照类型进行装配
相同点
都是用来自动装配的,都可以放在属性字段上
不同点
@Autowired通过byType的方式实现,必须要求这个对象存在
@Resource默认通过byName的方式实现,如果找不到名字,则通过byType实现。
5 使用注解自动装配
5.1 编写spring核心配置文件
<?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">
</beans>
5.2 配置注解支持
<context:annotation-config/>
5.3 自动扫描标注注解的包
<!--在容器启动的时候,对标注注解的包进行自动扫描,扫描到以后自动进行注册到容器-->
<context:component-scan base-package="cn.hxzy"/>
5.4 常用注解的说明
@Component //相当于在spring配置文件中定义的bean节点,当容器加载的时候,扫描包以后就会进行注册到IOC容器
根据@Component注解衍生出一些注解:
@Repository 代表数据访问层
@Service 代表业务逻辑层, 通常情况会给他加名称 @Service(value = “userService”)
@Controller 代表控制层
@Autowired 注解实现的bean的自动装配,默认是按照类型去装配的,如果容器中出现了两个类型相同的bean,则需要添加注解
@Qualifier(value = “jdbcMysqlDao”)//根据名称来自动装配
@Resource是java自己的注解,默认按照名称来自动装配,如果该bean没有名称,则按照类型进行装配
@Configration 相当于spring核心配置文件里面的beans
@Bean:用于@Configration配置类中,声明一个对象让spring容器管理,一般用于整合其他框架后,把它的类注册为bean实例对象后供spring来调度使用的。
@PropertySource(“classpath:application.properties”)读取静态资源目录下指定名称的properties文件
@Value(“${name}”)
@Bean与 @Component的区别:
两者都是Spring框架中用于定义bean的注解,但它们的用途和范围有所不同。以下是两者的区别:
作用对象不同:@Bean注解作用于方法,用于显式声明单个bean,而@Component注解作用于类,用于自动检测和使用类路径扫描自动配置bean。
配置方式不同:@Bean注解通常与@Configuration注解一起使用,允许开发者精确地创建和配置bean,提供更多关于bean的配置信息,如初始化方法、作用域、命名等;@Component注解则更多用于自动装配到Spring容器中,适用于简单的业务类。
使用场景不同:@Bean适用于需要更精细控制的bean配置,如第三方库中的类;@Component适用于简单的业务类或组件。
总结来说,如果需要简单地将一个类声明为bean,可以使用@Component;如果需要详细配置bean或从方法中产生bean,则应使用@Bean。
6 aop的简介
AOP是面向切面编程的意思,全称为Aspect Oriented Programing。
他是一种基于OOP之上的一种编程范式,弥补了OOP的不足,能更好的组织程序结构。
AOP可以把业务的功能步骤做成插拔式的组件,从而可以用这些组件定制新的功能,因此AOP可以提高业务的复用性,提高开发效率。把现有的代码做增强处理。
7 代理模式
7.1 代理模式的好处
可以使真实角色的操作更加存粹,不用去关注一些公共的业务。
公共业务就交给了代理角色,实现了业务的分工。
公共业务发生扩展的时候,方面集中管理。
8 spring使用aop
8.1 aop的的一些相关名词
- 切面(Aspect):横切关注点被模块化的特殊对象,是一个类,里面可以定义切入点和通知(切面 = 切点+通知)
- 通知(Advice):切面必须要完成的工作,是类中的一个方法
- 切入点(pointCut):切面通知执行的位置
- 连接点(JointPoint):程序执行过程中明确的点,一般是方法的调用
8.2 引入依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
8.3 在核心配置文件中导入aspectj约束
<?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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
8.4 定义一个日志类
8.4.1 前置通知
@Component("beforeLog")
public class LoggerProgram implements MethodBeforeAdvice {
/**
* 前置增强
* @param method 执行的目标方法
* @param objects 参数列表数组,如果目标方法无参,则为null
* @param o 目标对象
* @throws Throwable
*/
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("执行方法的当前时间为:"+ LocalDateTime.now());
System.out.println("目标对象的方法名称为:"+method.getName());
System.out.println("方法的参数为:");
for (Object object : objects) {
System.out.println(object);
}
System.out.println("目标对象的类型为:"+o.getClass().getName());
}
}
8.4.2 后置通知
@Component("afterLog")
public class LoggerAfter implements AfterReturningAdvice {
@Override
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println("执行方法完成的时间为:"+ LocalDateTime.now());
System.out.println("目标对象的方法名称为:"+method.getName());
System.out.println("方法的参数为:");
for (Object object : objects) {
System.out.println(object);
}
System.out.println("目标对象的类型为:"+o1.getClass().getName());
System.out.println("方法的返回值为:"+o);
}
}
8.4.3 环绕通知
@Component("around")
public class AroundTest implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("方法开始执行,时间为:" + LocalDateTime.now());
long start = System.currentTimeMillis(); //系统时间戳 1970.1.1
Object rs=methodInvocation.proceed(); //目标方法进行调用执行
System.out.println("方法执行完成,时间为:" + LocalDateTime.now());
long end = System.currentTimeMillis();
System.out.println("所用时间为:" + (end - start));
System.out.println("方法的返回值为:"+rs);
return rs; //方法的返回值
}
}
8.5 在核心配置文件中加入aop配置
<!--aop:xml的配置-->
<aop:config>
<!--定义切入点-->
<aop:pointcut id="point" expression="execution(* cn.hxzy.dao.impl.*.*(..))"/>
<!--定义通知-->
<!--<aop:advisor advice-ref="beforeLog" pointcut-ref="point"/>-->
<aop:advisor advice-ref="afterLog" pointcut-ref="point"/>
</aop:config>
通知类型:
前置通知:方法执行前进行的代码编织,xml配置实现接口:MethdBeforeAdvice。
后置通知:方法执行后进行的代码编织 xml配置实现接口:AfterReturningAdvice。
环绕通知:方法执行前后都进行代码编织,区别于前置+后置。把目标方法进行了围绕,无论是否发生异常都会被执行。xml配置实现接口:MethodInterceptor。
切入点表达式:
execution(* cn.hxzy.dao.impl.*.*(..))
第一个* 表示的是方法任意的返回值
第二个* 表示任意的类
最后一个*表示的是任意的方法
9 使用注解来定义切面
好处:1、增加了代码的灵活度 2、减少了配置代码量
使用@Aspect,首先要保证所用的JDK 是5.0或以上版本
@Aspect 标注这个类是一个切面
@Before("execution(* cn.hxzy.dao.Impl.UserDaoImpl.*(..))") 前置通知
@AfterReturning("execution(*cn.hxzy.dao.Impl.UserDaoImpl.*(..))") 后置通知
@AfterThrowing 异常通知, 在方法抛出异常之后
@Around 环绕通知, 围绕着方法执行
@After 最终增强
<!---开启aspectj框架的自动代理-->
<aop:aspectj-autoproxy expose-proxy="true" />
注解示例
@Aspect
@Component
public class AdviceLog {
@Pointcut("execution(* cn.hxzy.dao.impl.*.*(..))")
public void pt(){}
//前置通知
@Before("AdviceLog.pt()")
public void beforeLog(JoinPoint joinPoint) {
//得到代理对象的签名信息
Signature signature = joinPoint.getSignature();
Class c1 = signature.getDeclaringType();
System.out.println("方法名:" + signature.getName());
System.out.println("类名:" + c1.getName());
System.out.println("参数信息:");
Object[] args = joinPoint.getArgs();
for (Object arg : args) {
System.out.println(arg);
}
}
//后置通知
@AfterReturning(returning = "result", pointcut = "AdviceLog.pt()")
public void afterLog(JoinPoint joinPoint, Object result) {
System.out.println("方法执行完毕后的时间为:" + LocalDateTime.now());
System.out.println("方法的执行返回结果为:" + result);
}
//环绕通知
@Around("AdviceLog.pt()")
public Object around(ProceedingJoinPoint joinPoint) {
System.out.println("方法开始执行,时间为:" + LocalDateTime.now());
long start = System.currentTimeMillis(); //系统时间戳 1970.1.1
//调用方法本身去执行
Object result = 0;
try {
result = joinPoint.proceed(); //调用方法....
} catch (Throwable throwable) {
throwable.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("所用时间为:" + (end - start));
System.out.println("方法的返回值为:" + result);
return result;
}
}
10 spring集成Mybatis
1、IOC spring创建对象,给对象的属性赋值,完成对对象的管理。
2、AOP 在不影响核心业务代码的基础上,把公共的一部分基础业务,抽取到切面中,然后在程序的编译器(运行期)通过代理的方式,实现代码的织入。
导入依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
10.1 什么是 MyBatis-Spring
MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。它将允许 MyBatis 参与到 Spring 的事务管理之中,创建映射器 mapper 和 SqlSession
并注入到 bean 中,以及将 Mybatis 的异常转换为 Spring 的 DataAccessException
。 最终,可以做到应用代码不依赖于 MyBatis,Spring 或 MyBatis-Spring。
spring整合mybatis的步骤:
10.2 导入依赖
<dependencies>
<!-- junit测试包 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!-- mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.29</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>provided</scope>
</dependency>
<!-- Spring 相关-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.8</version>
</dependency>
<!-- spring 操作jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.8</version>
</dependency>
<!--AOP相关-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7.M3</version>
</dependency>
<!--mybatis整合spring的补丁包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<!--阿里巴巴的数据源连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.18</version>
</dependency>
</dependencies>
10.3 创建maven集成的mybatis项目
spring核心配置文件的头信息:
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
</beans>
mybatis的核心配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--mybatis的核心配置文件-->
<configuration>
<settings>
<!--全局开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
<setting name="logImpl" value="STDOUT_LOGGING"/>
<setting name="autoMappingBehavior" value="FULL"/>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<package name="cn.hxzy.pojo"/>
</typeAliases>
<!--注册 映射器-->
<mappers>
<mapper resource="mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
10.4 编写了数据源druid.properties
druid.driver=com.mysql.jdbc.Driver
druid.url=jdbc:mysql://localhost:3306/ticket?serverTimezone=UTC&useUnicode=true&useSSL=false&characterEncoding=utf8
druid.username=root
druid.password=root
druid.pool.init=5
druid.pool.minIdle=5
druid.pool.maxActive=100
druid.pool.maxWait=30000
10.5 编写了spring的核心配置文件
读取数据源
<!--spring读取properties文件-->
<context:property-placeholder location="classpath:druid.properties"/>
<!--数据源连接池-->
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${druid.driver}"/>
<property name="url" value="${druid.url}"/>
<property name="username" value="${druid.username}"/>
<property name="password" value="${druid.password}"/>
<property name="initialSize" value="${druid.pool.init}"/>
<property name="minIdle" value="${druid.pool.minIdle}"/>
<property name="maxActive" value="${druid.pool.maxActive}"/>
<property name="maxWait" value="${druid.pool.maxWait}"/>
</bean>
注册sqlSessionFactoryBean
<!--Spring注册SqlSessionFactory对象-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="druidDataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
实例对象
<!--newsMapper的bean实例对象-->
<bean id="newsMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
<property name="sqlSessionTemplate" ref="sqlSession"/>
<property name="mapperInterface" value="cn.hxzy.mapper.NewsMapper"/>
</bean>
此方法也可以简写为:
指定扫描基准包,把包下面面的接口注册成spring容器所管理的接口对象
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.hxzy.dao"/>
</bean>
<context:annotation-config />
<context:component-scan base-package="cn.hxzy"/>
<aop:aspectj-autoproxy expose-proxy="true"/>
11 声明式事务
事务的概念:把一组SQL指令打包一个独立的语句模块执行,如果里面有任意一条语句执行失败,则整个语句执行操作都将会回滚。
四个特性:1、原子性 2、持久性 3、隔离性 4、一致性
原子性:一组sql,一批sql是一个最小的执行单元,不可分割
持久性:执行命名令后,产生的结果是永久性的,不可逆转。
隔离性:两个及以上的并发事务执行的时候,互不影响
一致性:事务执行前后,对数据的操作产生的影响是一致的。
11.1 事务管理器的配置
<!-- 定义事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="druidDataSource"/>
</bean>
<!--配置切点,引用通知-->
<aop:config>
<aop:pointcut id="mypoint" expression="execution(* cn.hxzy.service.impl.*.*(..))"/>
<aop:advisor advice-ref="myAdvice" pointcut-ref="mypoint"/>
</aop:config>
<!--通知-->
<tx:advice transaction-manager="txManager" id="myAdive">
<!--事务规则-->
<tx:attributes>
<tx:method name="zhuanZhang" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="insert*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
11.2 事务的隔离级别
描述的是两个及以上的并发事务,执行的过程中,针对事务之间的互相影响的情况的一种应对策略。
并发事务可能出现的问题:
脏读:事务1执行的过程中,事务2读取到了事务1修改过但还未提交的数据,这种情况就叫做脏读。
不可重复度:事务1先后读取同一条记录,但两次读取的数据不同,原因是在这之间事务2进行数据的修改,并提交,导致事务1两次读取到的数据不同,称之为不可重复读
幻读:事务1按照条件查询数据时,没有对应的数据行,在这期间,事务2插入了对应的数据行,并且进行了提交,之后事务1在插入对应的数据时,又发现这行数据已经存在,好像出现了幻觉。
DEFAULT :采用的JDBC的隔离级别
4==SERIALIZABLE 串行化: T1在执行的过程中,T2既不能读与不能写
3=REPEATABLE_READ 可重复读(mysql):T1在执行的过程中,T2只读与不能修改数据,T2可以添加数据,可能会导致T1幻读 (幻读)
2=READ_COMMITTED 读已提交 (oracle):T1在执行的过程中,T2可以读也可以写,但是T1只能读取到T2提交后的数据(幻读)(不可重复读)
1=READ_UNCOMMITTED 读未提交:T1在执行的过程中,T2可以读也可以写,T1可以读取到T2未提交的数据(幻读)(不可重复读)(脏读)
11.3 事务的传播机制
REQUIRED: 如果上层方法没有事务,则创建一个新的事务,如果已经存在事务,则加入到事务中。
SUPPORTS: 如果上层方法没有事务,则以非事务方式执行。如果已经存在事务,则加入到事务中。
REQUIRES_NEW: 如果上层方法没有事务,则创建一个新的事务。如果已经存在事务,则将当前事务挂起,创建新事务执行。
NOT_SUPPORTED:如果上层方法没有事务,则以非事务方式执行。如果已经存在事务,则将当前事务挂起,以非事务方式执行。
NEVER: 如果上层方法没有事务,则以非事务方式执行。如果已经存在事务,则将当前事务挂起,并抛出异常。
MANDATORY: 如果上层方法没有事务,则抛出异常,如果已经存在事务,则加入到事务重执行。
NESTED:如果上层方法没有事务,则创建一个新的事务,如果已经存在事务,则嵌套到当前事务中。
11.4 事务的其他属性
timeout:事务超时时间,允许事务运行的最长时间,以秒为单位。默认值为-1,表示不超时
read-only:事务是否为只读,默认值为false
rollback-for:设定能够触发回滚的异常类型、Spring默认只在抛出runtime exception时才标识事务回滚、可以通过全限定类名指定需要回滚事务的异常,多个类名用逗号隔开
no-rollback-for:设定不触发回滚的异常类型、Spring默认checked Exception不会触发事务回滚、可以通过全限定类名指定不需回滚事务的异常,多个类名用英文逗号隔开
11.5 使用注解的形式实现声明式事务的配置
可以直接配置在类上或者方法上
@Service
@Transactional(isolation = Isolation.REPEATABLE_READ,propagation = Propagation.REQUIRES_NEW,noRollbackFor = ArithmeticException.class)
public class TransferAccountServiceImpl implements TransferAccountService {
}
也可以叫灵活的配置在所需要的方法上
@Transactional(isolation = Isolation.REPEATABLE_READ,propagation = Propagation.REQUIRES_NEW,noRollbackFor = ArithmeticException.class)
public boolean transferAccount(int fromUserId, int toUserId, double money) {
}
在配置文件中添加上,注解事务的支持
<!--启动注解方式的支持-->
<tx:annotation-driven transaction-manager="txManager"/>