1. mavne依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.Aop
2.1 Aspect
在spring中,在类上添加 @Aspect 注解,即表示这是一个切面类
@Aspect
@Component
public class HelloAspectj {
}
2.2 Pointcut
切点,定义在哪些地方进行功能增强
/**
* 通过 execution 表达式定义切点
*/
@Pointcut("execution(* com.example.demo.aop..*.*(..))")
public void helloPointcut(){}
/**
* 通过注解定义切点,对方法上添加该注解的方法进行增强
*/
@Pointcut("@annotation(com.example.demo.aop.func.service.LogAspect)")
public void helloPointcutAnnotation(){}
2.2.1 execution
execution表达式定义切点, * com.example.demo.aop..*.*(..)
- 第一个* 方法的返回值类型
- com.example.demo.aop 应用aop的package
- .. 当前包及子包
- * 类名,* 表示所有类
- * 方法名,*表示所有方法
- (..) 参数类型, ..表示所有参数类型
2.2.2 annotation
通过注解定义切点,对添加指定注解的方法进行功能增强
2.3 Advice
通知,定义功能增强的时机和内容
切面类
package com.example.demo.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class HelloAspectj {
// @Before("execution(* com.example.demo.aop.func.service.IHello.hello(..))")
@Pointcut("execution(* com.example.demo.aop..*.*(..))")
public void helloPointcut(){}
/**
* @param joinPoint 连接点信息,可获取到方法的元数据信息及参数信息
*/
@Before("helloPointcut()")
public void Before(JoinPoint joinPoint) {
System.out.println("Before");
}
/**
* @param joinPoint 连接点信息,可获取到方法的元数据信息及参数信息
*/
@After("helloPointcut()")
public void After(JoinPoint joinPoint) {
System.out.println("After");
}
/**
* 如果方法有返回值,则此方法必须定义返回值,否则
*/
@Around("helloPointcut()")
public Object Around(ProceedingJoinPoint joinPoint) {
System.out.println("Around");
Object proceed = null;
try {
// 调用目标方法并获得方法返回值
proceed = joinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return proceed;
}
/**
* @param joinPoint 连接点信息
* @param value 返回值
*/
@AfterReturning(pointcut = "helloPointcut()",returning = "value")
public void AfterReturning(JoinPoint joinPoint,Object value) {
System.out.println("AfterReturning value " + value);
}
/**
* @param joinPoint 连接点信息
* @param ex 异常信息
*/
@AfterThrowing(pointcut = "helloPointcut()",throwing = "ex")
public void AfterThrowing(JoinPoint joinPoint,Throwable ex) {
System.out.println("AfterThrowing");
}
}
2.3.1 时机
如果目标方法在所有时机都进行方法增强,则按照下面的顺序执行增强方法
AfterReturnning 和 AfterThrowing为互斥项,一次调用中只能有一个生效
- @Around 环绕通知:方法执行前添加逻辑处理,然后手动调用目标方法,(ProceedingJoinPoint.proceed()),然后在方法执行后进行逻辑处理
- @Before 前置通知:方法执行之前
- @AfterReturnning 返回通知:方法成功执行之后通知,
- @AfterThrowing 异常通知:抛出异常之后通知
- @After 后置通知:方法执行之后
2.3.2 内容
增强的内容即是该通知对应的具体方法
2.3.3 内部调用
切点对某个类中的所有方法进行增强,其中该类中的方法methodA调用的该类中的方法methodB,此时methodB不会被增强
这种情况若需要对methodB进行增强,则在methodA中按照下面方式调用methodB
CurrentClass proxy =(CurrentClass) AopContext.currentProxy();
proxy.menthodB();