Spring中如何为某一类注解进行增强(AOP)呢?
下文笔者通过示例的方式,讲述对包含某一类注解的类进行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) {
}
}
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


