所有分类
  • 所有分类
  • 未分类

Spring之AOP系列-将方法上的注解做为切点(用@Around)

简介

说明

本文介绍Spring(SpringBoot)的AOP的用法:自定义注解,在Controller的方法上使用此注解,然后在AOP中获得注解的相关信息。

本文使用@Around。

基础代码

项目结构、pom.xml公共代码等与此文一样:Spring之AOP-将方法上的注解做为切点(用@Before) – 自学精灵

写法1:入参只有ProceedingJoinPoint

@Around入参只写ProceedingJoinPoint,有返回值。这个返回值会作为Controller数据返回回去。

AOP代码

package com.example.demo.aspect;

import com.example.demo.annotation.OperationLog;
import com.example.demo.common.util.JsonUtil;
import com.example.demo.entity.User;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * Around结合方法注解获得操作日志
 */
@Aspect
@Component
public class OperationLogAspectByAround {
    // 切点表达式,表示加了OperationLog注解的都是切点,路径是自定义注解的全路径
    @Pointcut("@annotation(com.example.demo.annotation.OperationLog)")
    //多个切点时可指定优先级
    // @Order(1)
    public void pointcut() {

    }

    //有ProceedingJoinPoint无注解类,有返回值
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("################## around 进入 ##################");
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();

        System.out.println("--------------------- 方法信息 ---------------------");
        System.out.println("joinPoint.getTarget().toString()  : " + joinPoint.getTarget().toString());
        System.out.println("methodSignature.getName()         : " + methodSignature.getName());
        System.out.println("method.getName()                  : " + method.getName());
        System.out.println("method.getReturnType().getName()  : " + method.getReturnType().getName());

        System.out.println("--------------------- 入参数据 ---------------------");
        Object[] objects = joinPoint.getArgs();
        System.out.println(JsonUtil.toJson(objects));

        System.out.println("--------------------- 真正执行 ---------------------");
        Object object = joinPoint.proceed();
        System.out.println("--------------------- 执行结果 ---------------------");
        System.out.println(JsonUtil.toJson(object));

        System.out.println("--------------------- 注解数据 ---------------------");
        OperationLog operationLog = method.getAnnotation(OperationLog.class);
        System.out.print("type: " + operationLog.type());
        System.out.println("\tdesc: " + operationLog.desc());

        return object;
    }
}

测试

1.测试添加接口

 后端结果

################## around 进入 ##################
--------------------- 方法信息 ---------------------
joinPoint.getTarget().toString()  : com.example.demo.controller.UserController@3bfbf09e
methodSignature.getName()         : testAdd
method.getName()                  : testAdd
method.getReturnType().getName()  : com.example.demo.entity.User
--------------------- 入参数据 ---------------------
[{"id":12,"userName":"Tony","note":"abc"}]
--------------------- 真正执行 ---------------------
--------------------- 执行结果 ---------------------
{"id":12,"userName":"Tony","note":"abc"}
--------------------- 注解数据 ---------------------
type: 添加	desc: 添加数据

2.测试修改接口

后端结果

################## around 进入 ##################
--------------------- 方法信息 ---------------------
joinPoint.getTarget().toString()  : com.example.demo.controller.UserController@3bfbf09e
methodSignature.getName()         : testUpdate
method.getName()                  : testUpdate
method.getReturnType().getName()  : com.example.demo.entity.User
--------------------- 入参数据 ---------------------
[{"id":11,"userName":"Peter","note":"hello"}]
--------------------- 真正执行 ---------------------
id = 11	 userName = Peter	 note = hello
--------------------- 执行结果 ---------------------
{"id":11,"userName":"Peter","note":"hello"}
--------------------- 注解数据 ---------------------
type: 更新	desc: 更新数据

写法2:入参为ProceedingJoinPoint + 注解类

@Around入参为ProceedingJoinPoint + 注解类,有返回值。这样就不用写@PointCut了,返回值会作为Controller数据返回回去。

AOP代码

package com.example.demo.aspect;

import com.example.demo.annotation.OperationLog;
import com.example.demo.common.util.JsonUtil;
import com.example.demo.entity.User;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * Around结合方法注解获得操作日志
 */
@Aspect
@Component
public class OperationLogAspectByAround {
    // 有ProceedingJoinPoint和注解类,有返回值。这样就不用写@Pointcut了
    @Around("@annotation(operationLog)")
    public Object around(ProceedingJoinPoint joinPoint, OperationLog operationLog) throws Throwable {
        System.out.println("################## around 进入 ##################");
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();

        System.out.println("--------------------- 方法信息 ---------------------");
        System.out.println("joinPoint.getTarget().toString()  : " + joinPoint.getTarget().toString());
        System.out.println("methodSignature.getName()         : " + methodSignature.getName());
        System.out.println("method.getName()                  : " + method.getName());
        System.out.println("method.getReturnType().getName()  : " + method.getReturnType().getName());

        System.out.println("--------------------- 入参数据 ---------------------");
        Object[] objects = joinPoint.getArgs();
        System.out.println(JsonUtil.toJson(objects));

        System.out.println("--------------------- 真正执行 ---------------------");
        Object object = joinPoint.proceed();
        System.out.println("--------------------- 执行结果 ---------------------");
        System.out.println(JsonUtil.toJson(object));

        System.out.println("--------------------- 注解数据 ---------------------");
        System.out.print("type: " + operationLog.type());
        System.out.println("\tdesc: " + operationLog.desc());
        return object;
    }
}

测试

1. 测试添加接口

后端结果

################## around 进入 ##################
--------------------- 方法信息 ---------------------
joinPoint.getTarget().toString()  : com.example.demo.controller.UserController@19e107d7
methodSignature.getName()         : testAdd
method.getName()                  : testAdd
method.getReturnType().getName()  : com.example.demo.entity.User
--------------------- 入参数据 ---------------------
[{"id":11,"userName":"Tony","note":"cccc"}]
--------------------- 真正执行 ---------------------
--------------------- 执行结果 ---------------------
{"id":11,"userName":"Tony","note":"cccc"}
--------------------- 注解数据 ---------------------
type: 添加	desc: 添加数据

测试2测试修改接口

后端结果

################## around 进入 ##################
--------------------- 方法信息 ---------------------
joinPoint.getTarget().toString()  : com.example.demo.controller.UserController@19e107d7
methodSignature.getName()         : testUpdate
method.getName()                  : testUpdate
method.getReturnType().getName()  : com.example.demo.entity.User
--------------------- 入参数据 ---------------------
[{"id":32,"userName":"Peter","note":"hi"}]
--------------------- 真正执行 ---------------------
id = 32	 userName = Peter	 note = hi
--------------------- 执行结果 ---------------------
{"id":32,"userName":"Peter","note":"hi"}
--------------------- 注解数据 ---------------------
type: 更新	desc: 更新数据
0

评论0

请先

显示验证码
没有账号?注册  忘记密码?

社交账号快速登录