最近在跟着小傅哥学springboot开发中间件,里面使用到了很多的aop代理,特意去补了一下
先说一下几个概念:
这是一个切面类,JoinPoint类可以获取切入点的对象、方法和参数、属性,ProceedingJoinPoint继承了JoinPoint,它暴露了一个proceed方法,这个方法是aop代理链执行的方法
@Aspect
@Component
public class DemoAspect {
@Pointcut("execution(public * com.example.demo.service.*.save*(..))")
public void save(){ }
@AfterReturning("save()")
public void afterReturn(JoinPoint joinPoint){
//1.获取切入点所在目标对象
Object target = joinPoint.getTarget();
System.out.println(target.getClass().getName());
//2.获取切入点方法的名字
String name = joinPoint.getSignature().getName();
System.out.println("切入方法名字:"+name);
//3.获取方法上的注解
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if(method != null){
ApiLog annotation = method.getAnnotation(ApiLog.class);
System.out.println("切入方法注解的title:"+annotation.title());
}
//4.获取方法的参数
Object[] args = joinPoint.getArgs();
for (Object arg : args) {
System.out.println("切入方法的参数:"+arg);
}
}
}
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ApiLog {
public String title() default "";
public String logService() default "operLogServiceImpl";
public boolean isSaveRequestDate() default true;
public boolean isTrack() default true;
}
@Service
public class TestService {
@ApiLog(title = "注解的标题", isSaveRequestDate = false)
public void save(String parm1,int parm2){
System.out.println("执行目标对象的方法"+parm1+parm2);
}
public void update(){
System.out.println("没有注解方法,不会被拦截");
}
}
大致的执行流程是这样的,如果一个类被定义为切入点,Spring会为它创建一个代理对象,IOC容器中存储的是这个代理对象,执行的也是这个代理对象,执行完原本的方法后,会去执行这个切点的通知策略,也就是afterReturn方法