网站制作费可以做业务宣传费,免费软件开发app,求推荐公司网站建设,苏州展厅设计公司排名目录
1 事务管理
1.1 事务
1.2 Transactional注解
1.2.1 rollbackFor
1.2.2 propagation
2 AOP 基础
2.1 AOP入门
2.2 AOP核心概念
3. AOP进阶
3.1 通知类型
3.2 通知顺序
3.3 切入点表达式
execution切入点表达式
annotion注解
3.4 连接点 1 事务管理
1.1 事务…目录
1 事务管理
1.1 事务
1.2 Transactional注解
1.2.1 rollbackFor
1.2.2 propagation
2 AOP 基础
2.1 AOP入门
2.2 AOP核心概念
3. AOP进阶
3.1 通知类型
3.2 通知顺序
3.3 切入点表达式
execution切入点表达式
annotion注解
3.4 连接点 1 事务管理
1.1 事务
事务是一组操作的集合它是一个不可分割的工作单位。事务会把所有的操作作为一个整体一起向数据库提交或者是撤销操作请求。所以这组操作要么同时成功要么同时失败。
事务的目标保证操作前后数据的一致性。
事务的操作主要有三步 开启事务一组操作开始前开启事务start transaction / begin ; 提交事务这组操作全部成功后提交事务commit ; 回滚事务中间任何一个操作出现异常回滚事务rollback ;
1.2 Transactional注解
在当前方法执行之前来开启事务方法执行完毕后提交事务。如果在方法执行过程中出现异常就会进行事务的回滚操作。
我们一般会在service层控制事务因为一个业务功能可能会包含多个数据访问操作。在sevice层控制事务我们就可以将多个数据访问操作控制在一个事务范围内。
Transactional注解书写位置 方法 当前方法交给spring进行事务管理 类 当前类中所有的方法都交由spring进行事务管理 接口 接口下所有的实现类当中所有的方法都交给spring 进行事务管理
说明在application.yml配置文件中开启事务管理日志可以在console看到和事务相关的日志信息 Transactional注解的两个常见属性 异常回滚的属性rollbackFor 事务传播行为propagation
1.2.1 rollbackFor
默认情况下只有出现RuntimeException(运行时异常)才会回滚事务。
如果需要指定出现某种异常时回滚事务需要配置Transactional注解中的rollbackFor属性。
Transactional(rollbackForException.class)
1.2.2 propagation
propagation作用配置事务的传播行为
在A方法运行的时候首先会开启一个事务在A方法当中又调用了B方法 B方法自身也是事务那么B方法在运行的时候到底是加入到A方法的事务当中来还是B方法在运行的时候新建一个事务
解决方案给B方法加上注解
Transactional(propagation Propagation.REQUIRES_NEW)//不论A是否有事务都新建事务
属性值含义REQUIRED【默认值】B方法加入到A的事务中。REQUIRES_NEW为B创建新事务。即使A运行异常需要回滚也不影响B的事务提交。
2 AOP 基础
2.1 AOP入门
AOPAspect Oriented Programming面向切面编程就是面向特定方法编程是一种编程思想。
AOP的作用在程序运行期间在不修改源代码的基础上对已有方法进行功能增强无侵入性: 解耦 AOP的优势 减少重复代码 提高开发效率 维护方便
实现步骤 导入依赖在pom.xml中导入AOP的依赖 编写AOP程序给特定方法增强功能
pom.xml
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId
/dependencyComponent//标注一个类为Spring容器的Bean
Aspect //当前类为切面类
Slf4j//日志框架
public class TimeAspect {Around(execution(* com.itheima.service.*.*(..))) public Object recordTime(ProceedingJoinPoint pjp) throws Throwable {//记录方法执行开始时间long begin System.currentTimeMillis();//执行原始方法Object result pjp.proceed();//记录方法执行结束时间long end System.currentTimeMillis();//计算方法执行耗时log.info(pjp.getSignature()执行耗时: {}毫秒,end-begin);return result;}
}
AOP常见的应用场景 统计各个业务层方法的执行耗时 记录系统的操作日志 权限控制 事务管理我们前面所讲解的Spring事务管理底层其实也是通过AOP来实现的只要添加Transactional注解之后AOP程序自动会在原始方法运行前先来开启事务在原始方法运行完毕之后提交或回滚事务
2.2 AOP核心概念
1. 连接点JoinPoint所有可以被AOP控制的方法
2. 通知Advice控制连接点的方法比如上面的recordTime()方法
3. 切入点PointCutexecution里的方法通知仅会在切入点方法执行时被应用
假如切入点表达式改为DeptServiceImpl.list()就代表只有list()方法运行时才会应用通知。
4. 切面Aspect通知切入点
通过切面能够描述当前AOP程序针对哪个原始方法(连接点)在什么条件下切入点表达式执行什么样的操作通知。
切面所在的类我们一般称为切面类被Aspect注解标识的类比如上面的TimeAspect类。 5. 目标对象Target连接点方法所属的类 Spring的AOP底层是基于动态代理实现的即在程序运行时会自动为目标对象生成对应的代理对象。在代理对象中按照通知对目标对象中的原始方法进行功能增强。然后将代理对象注入到Controller层。
3. AOP进阶
3.1 通知类型 Around环绕通知通知方法在目标方法前、后都被执行。 Before前置通知通知方法在目标方法前被执行 After 后置通知通知方法在目标方法后被执行无论是否有异常都会执行 AfterReturning 返回后通知通知方法在目标方法正常执行后被执行 AfterThrowing 异常后通知此注解标注的通知方法发生异常后执行
在使用Around环绕通知时的注意事项 原始方法如果执行时有异常环绕通知中的后置代码不会在执行了 Around环绕通知需要自己调用 ProceedingJoinPoint.proceed() 来让原始方法执行其他通知不需要考虑目标方法执行 Around环绕通知方法的返回值必须指定为Object。来接收原始方法的返回值否则原始方法执行完毕是获取不到返回值的。
PointCut注解作用是将公共的切入点表达式抽取出来需要用到时引用该切入点表达式即可。
Slf4j
Component
Aspect
public class MyAspect1 {//切入点方法公共的切入点表达式Pointcut(execution(* com.itheima.service.*.*(..)))private void pt(){}//前置通知引用切入点Before(pt())public void before(JoinPoint joinPoint){log.info(before ...);}//环绕通知Around(pt())public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {log.info(around before ...);//调用目标对象的原始方法执行Object result proceedingJoinPoint.proceed();//如果原始方法在执行时发生异常则后续代码不在执行log.info(around after ...);return result;}
}
注意当切入点方法使用private修饰时仅能在当前切面类中引用该表达式 当外部其他切面类也要引用当前类中的切入点表达式时需要把private改为public而在引用的时候具体的语法为全类名.方法名()。
3.2 通知顺序
定义了多个切面类而多个切面类中多个切入点都匹配到了同一个目标方法。此时当目标方法在运行的时候这多个切面类当中的这些通知方法都会运行。哪个先运行哪个后运行
在不同切面类中默认按照切面类的类名字母排序 目标方法Before方法字母排名靠前的先执行 目标方法After方法字母排名靠前的后执行
Order注解:控制通知的执行顺序
Slf4j
Component
Aspect
Order(2) //切面类的执行顺序前置通知数字越小先执行; 后置通知数字越小越后执行
public class MyAspect2 {//通知
}
3.3 切入点表达式
作用主要用来决定项目中的哪些方法需要加入通知
execution切入点表达式
示例
execution(void com.itheima.service.impl.DeptServiceImpl.delete(java.lang.Integer))
execution(* com..DeptServiceImpl.delete(java.lang.Integer))
execution(* com..*.*(..))
//匹配DeptServiceImpl类中以find开头的方法
execution(* com.itheima.service.impl.DeptServiceImpl.find*(..)) 描述切入点方法通常基于接口描述而不是直接描述实现类增强拓展性
annotion注解 新建一个注解跟新建类的方式一样
Target(ElementType.METHOD)
Retention(RetentionPolicy.RUNTIME)
public interface MyLog {
} 然后在目标方法上添加注解MyLog表示该方法被通知方法控制
最后在切面类中的通知方法添加annotation注解括号里的参数为MyLog的全名。
Slf4j
Component
Aspect
public class MyAspect6 {//前置通知Before(annotation(com.itheima.anno.MyLog))public void before(){log.info(MyAspect6 - before ...);}
}
当一个新的方法需要被该通知方法控制时在新方法上添加注解MyLog即可。
3.4 连接点
在Spring中用JoinPoint抽象了连接点用它可以获得方法执行时的相关信息如目标类名、方法名、方法参数等。 对于Around通知获取连接点信息只能使用ProceedingJoinPoint类型 对于其他四种通知获取连接点信息只能使用JoinPoint它是ProceedingJoinPoint的父类型
Slf4j
Component
Aspect
public class MyAspect7 {Pointcut(annotation(com.itheima.anno.MyLog))private void pt(){}//前置通知Before(pt())public void before(JoinPoint joinPoint){log.info(joinPoint.getSignature().getName() MyAspect7 - before ...);}//后置通知Before(pt())public void after(JoinPoint joinPoint){log.info(joinPoint.getSignature().getName() MyAspect7 - after ...);}//环绕通知Around(pt())public Object around(ProceedingJoinPoint pjp) throws Throwable {//获取目标类名String name pjp.getTarget().getClass().getName();log.info(目标类名{},name);//目标方法名String methodName pjp.getSignature().getName();log.info(目标方法名{},methodName);//获取方法执行时需要的参数Object[] args pjp.getArgs();log.info(目标方法参数{}, Arrays.toString(args));//执行原始方法Object returnValue pjp.proceed();return returnValue;}
}