一.AOP知识点
1.切入点表达式(表明需要增强的方法)
execution(权限修饰符 返回值类型 包名.类名.方法名(参数类型))
-- 完整写法
execution(public void com.atguigu.service.impl.UserServiceImpl.updateUser(Integer,String))
-- 省略权限修饰符
execution( void com.atguigu.service.impl.UserServiceImpl.updateUser(Integer,String))
-- 不限定返回值类型
execution( * com.atguigu.service.impl.UserServiceImpl.updateUser(Integer,String))
-- 不限定包名
execution( * *..UserServiceImpl.updateUser(Integer,String))
-- 不限定类名
execution( * *..*ServiceImpl.updateUser(Integer,String))
-- 不限定方法名
execution( * *..*ServiceImpl.*(Integer,String))
-- 不限定参数
execution( * *..*ServiceImpl.*(..))
-- 不推荐
execution( * *..*.*(..))
2.通知类别(掌握)
通知类名 | 标签 | 说明 |
---|---|---|
前置通知 | aop:before | 在切入点之前执行 |
正常后置通知 | aop:after-returning | 在切入点之后执行,切入点没有异常才执行 |
异常后置通知 | aop:after-throwing | 在切入点之后执行,切入点有异常才执行 |
后置通知 | aop:after | 在切入点之后执行,不管切入点是否有异常都执行 |
环绕通知 | aop:around | 在切入点之前执行,在切入点之后执行 |
/**
* 通知类
*/
@Aspect
@Component
public class MyAdvice1 {
/**
* 前置通知
*/
@Before("execution(* *..*Service.*(..))")
public void before(){
System.out.println("MyAdvice1 .. before");
}
/**
* 正常后置通知
*/
@AfterReturning("execution(* *..*Service.*(..))")
public void afterReturing(){
System.out.println("MyAdvice1 .. afterReturing");
}
/**
* 异常后置通知
*/
@AfterThrowing("execution(* *..*Service.*(..))")
public void afterThrowing(){
System.out.println("MyAdvice1 .. afterThrowing");
}
/**
* 后置通知
*/
@After("execution(* *..*Service.*(..))")
public void after(){
System.out.println("MyAdvice1 .. after");
}
@Around("execution(* *..*Service.*(..))")
public void around(ProceedingJoinPoint pjp){
System.out.println("around之前");
try {
pjp.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.out.println("around之后");
}
}
- AOP注解获取切入点输入参数(掌握)
@Aspect
@Component
public class MyAdvice2 {
/**
* 前置通知
*/
@Before("execution(* *..*Service.*(..))")
public void before(JoinPoint jp){
System.out.println("MyAdvice1 .. before 输入参数 = " + Arrays.toString(jp.getArgs()));
}
@Around("execution(* *..*Service.*(..))")
public void around(ProceedingJoinPoint pjp){
System.out.println("MyAdvice2 around 输入参数 = " + Arrays.toString(pjp.getArgs()));
try {
pjp.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
}
- AOP注解获取切入点异常(掌握)
@Aspect
@Component
public class MyAdvice4 {
/**
* 异常后置通知
*/
@AfterThrowing( value = "execution(* *..*Service.*(..))" ,throwing = "e")
public void afterThrowing(Exception e){
System.out.println("MyAdvice4 .. afterThrowing 异常 = " + e);
}
@Around("execution(* *..*Service.*(..))")
public void around(ProceedingJoinPoint pjp){
try {
pjp.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
System.out.println("MyAdvice4 .. around 异常 = " + throwable);
}
}
}
- AOP注解获取切入点返回值(掌握)
@Aspect
@Component
public class MyAdvice3 {
/**
* 正常后置通知
*/
@AfterReturning(value = "execution(* *..*Service.*(..))",returning = "result")
public void afterReturing(Object result){
System.out.println("MyAdvice1 .. afterReturing 返回值 = " + result);
}
@Around("execution(* *..*Service.*(..))")
public void around(ProceedingJoinPoint pjp){
try {
Object result = pjp.proceed();
System.out.println("MyAdvice3 .. around 返回值 = " + result);
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
}
二,操作流程
1.导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.编写Aop配置类
在类上加注解@Aspect标志为切面类,@Component将类放入spring容器,@Before表明为前置通知
@Component
@Aspect
public class AopAdvice {
@Before("execution(* *..HospitalSetController.lockHospSet(..))")//切入点表达式
public void before(){
System.out.println("切入成功!!!!!!!!!!!!!");
}
}