Spring中如何为某一类注解进行增强(AOP)呢?

戚薇 Spring 发布时间:2023-04-13 21:47:15 阅读数:146 1
下文笔者通过示例的方式,讲述对包含某一类注解的类进行AOP切入的方法分享

AOP切入点设置为注解类的实现思路

使用@Before或@Around,结合@within
   或
使用@Pointcut结合@within

注意事项:
   @within中加入注解类的信息,即可对within中的注解进行增强
例:对标注了controller注解的类进行增强
@Before("@within(controller)")
public void before(JoinPoint joinPoint, Controller controller)

或

@Pointcut("@within(org.springframework.stereotype.Controller)")
例:

示例1:无参数

package com.java265.demo.aspect;
 
import com.java265.demo.annotation.ApiLog;
import com.java265.demo.entity.User;
import com.java265.demo.util.JsonUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
 
import java.lang.reflect.Method;
 
/**
 * Before结合类上的注解获得操作日志
 */
@Aspect
@Component
public class ApiLogAspectByPointcutWithoutArg {
    @Pointcut("@within(com.java265.demo.annotation.ApiLog)")
    public void pointcut() {
    }
 
    @Before("pointcut()")
    public void before(JoinPoint joinPoint) {
        System.out.println("++++++++++++++++++++++++ before ++++++++++++++++++++++++++++++");
        System.out.println("------------------ joinPoint ------------------");
        System.out.println(joinPoint);
        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("------------------ 类的ApiLog注解数据 ------------------");
        Class<?> declaringClass = method.getDeclaringClass();
        ApiLog apiLog = declaringClass.getAnnotation(ApiLog.class);
        System.out.println("tag: " + apiLog.tag());
 
        System.out.println("------------------ 类的Api注解数据 ------------------");
        Class<?> aClass = method.getDeclaringClass();
        if (aClass.isAnnotationPresent(Api.class)) {
            String[] tags = aClass.getAnnotation(Api.class).tags();
            String value = aClass.getAnnotation(Api.class).value();
 
            String tagJoin = String.join("+", tags);
            System.out.println("tags:" + tagJoin + "; value:" + value);
        }
 
        System.out.println("------------------ 方法注解数据 ----------------");
        if (method.isAnnotationPresent(ApiOperation.class)) {
            System.out.println("操作为:" + method.getAnnotation(ApiOperation.class).value());
        }
 
        System.out.println("------------------ 入参数据 ------------------");
        Object[] objects = joinPoint.getArgs();
        for (Object o : objects) {
            System.out.println(o);
            if (o instanceof User) {
                System.out.println("id是:" + ((User) (o)).getId() +
                        "; 名字是:" + ((User) (o)).getUserName() +
                        "; 备注是:" + ((User) (o)).getNote());
            }
        }
        System.out.println("#################################################");
    }
 
    @After("pointcut()")
    public void after(JoinPoint joinPoint) {
        System.out.println("++++++++++++++++++++++++ after ++++++++++++++++++++++++++++++");
        System.out.println("------------------ joinPoint ------------------");
        System.out.println(joinPoint);
    }
 
    @AfterReturning(value = "pointcut()", returning = "returnValue")
    public void afterReturning(JoinPoint joinPoint, Object returnValue) {
        System.out.println("+++++++++++++++++++++ afterReturning +++++++++++++++++++++++++");
        System.out.println("------------------ joinPoint ------------------");
        System.out.println(joinPoint);
        System.out.println("------------------ 返回值 --------------------");
        System.out.println(JsonUtil.toJson(returnValue));
    }
 
    @AfterThrowing(pointcut = "pointcut()", throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, Throwable e) {
        System.out.println("+++++++++++++++++++++ afterThrowing +++++++++++++++++++++++++");
        System.out.println("------------------ joinPoint ------------------");
        System.out.println(joinPoint);
        System.out.println("------------------ 异常信息 --------------------");
        e.printStackTrace();
    }
}

示例2:带参数

package com.java265.demo.aspect;
 
import com.java265.demo.annotation.ApiLog;
import com.java265.demo.entity.User;
import com.java265.demo.util.JsonUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
 
import java.lang.reflect.Method;
 
/**
 * Before结合类上的注解获得操作日志
 */
@Aspect
@Component
public class ApiLogAspectByPointcutWithArg {
    @Pointcut("@within(apiLog)")
    public void pointcut(ApiLog apiLog) {
 
    }
 
    @Before("pointcut(apiLog)")
    // 会报警告:argNames attribute isn't defined。
    // 解决方法:@Before(value = "pointcut(apiLog)", argNames = "joinPoint,apiLog")
    public void before(JoinPoint joinPoint, ApiLog apiLog) {
        System.out.println("++++++++++++++++++++++++ before ++++++++++++++++++++++++++++++");
        System.out.println("------------------ joinPoint ------------------");
        System.out.println(joinPoint);
 
        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("------------------ 类的ApiLog注解数据 ------------------");
        System.out.println("tag: " + apiLog.tag());
 
        System.out.println("------------------ 类的Api注解数据 ------------------");
        Class<?> aClass = method.getDeclaringClass();
        if (aClass.isAnnotationPresent(Api.class)) {
            String[] tags = aClass.getAnnotation(Api.class).tags();
            String value = aClass.getAnnotation(Api.class).value();
 
            String tagJoin = String.join("+", tags);
            System.out.println("tags:" + tagJoin + "; value:" + value);
        }
 
        System.out.println("------------------ 方法注解数据 ----------------");
        if (method.isAnnotationPresent(ApiOperation.class)) {
            System.out.println("操作为:" + method.getAnnotation(ApiOperation.class).value());
        }
 
        System.out.println("------------------ 入参数据 ------------------");
        Object[] objects = joinPoint.getArgs();
        for (Object o : objects) {
            System.out.println(o);
            if (o instanceof User) {
                System.out.println("id是:" + ((User) (o)).getId() +
                        "; 名字是:" + ((User) (o)).getUserName() +
                        "; 备注是:" + ((User) (o)).getNote());
            }
        }
        System.out.println("#################################################");
    }
 
    @After("pointcut(apiLog)")
    // 会报警告:argNames attribute isn't defined。
    // 解决方法:@After(value = "pointcut(apiLog)", argNames = "joinPoint,apiLog")
    public void after(JoinPoint joinPoint, ApiLog apiLog) {
        System.out.println("++++++++++++++++++++++++ after ++++++++++++++++++++++++++++++");
        System.out.println("------------------ joinPoint ------------------");
        System.out.println(joinPoint);
    }
 
    @AfterReturning(value = "pointcut(apiLog)", returning = "returnValue")
    // 会报警告:argNames attribute isn't defined。
    // 解决方法@AfterReturning(value = "pointcut(apiLog)", returning = "returnValue")
    public void afterReturning(JoinPoint joinPoint, ApiLog apiLog, Object returnValue) {
        System.out.println("+++++++++++++++++++++ afterReturning +++++++++++++++++++++++++");
        System.out.println("------------------ joinPoint ------------------");
        System.out.println(joinPoint);
        System.out.println("-------------------- 返回值 -------------------");
        System.out.println(JsonUtil.toJson(returnValue));
    }
}

//测试代码

package com.java265.demo.controller;
 
import com.java265.demo.annotation.ApiLog;
import com.java265.demo.annotation.OperationLog;
import com.java265.demo.entity.User;
import com.java265.demo.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
 
@ApiLog(tag = "用户接口")
@Api(tags = "用户")
@RequestMapping("/user")
@RestController
public class UserController {
    @Autowired
    private UserService userService;
 
    @ApiOperation("打印数据")
    @GetMapping("print")
    public User testPrint(User user) {
        userService.printUser(user);
        return user;
    }
 
    @ApiOperation("添加数据")
    @PostMapping("add")
    @OperationLog(type = "添加", desc = "添加数据")
    public User testAdd(User user) {
        return user;
    }
 
    @ApiOperation("更新数据")
    @PostMapping("update")
    @OperationLog(type = "更新", desc = "更新数据")
    public User testUpdate(User user) {
        userService.printUser(user);
        return user;
    }
 
    @ApiOperation("删除数据")
    @PostMapping("delete")
    public void delete(User user) {
    }
}
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaFramework/Spring/202304/6235.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者