SpringAOP+自定义注解使用
1、创建springboot工程,在pom.xml中引入aspectjweaver依赖
<!– AOP切面编程框架 –>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<!–<version>1.9.4</version>–>
</dependency>
2、编写自定义注解(使用@interface关键字定义注解)
package cn.baidou.dianping.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义方法注解
*/
// @Target(ElementType.METHOD) 用来约束这个自定义注解只能用在方法上
@Target(ElementType.METHOD)
// @Retention 用来控制注解的生命周期,RUNTIME表示这个注解一直存活 (作用在源码阶段,字节码文件阶段,运行阶段)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodExporter {
}
3、编写切面类
package cn.baidou.dianping.aop;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
/**
* 获取目标入参、执行时间、执行过程、返回结果等细节并打印到日志上
*
* @author 白豆五
* @version 2023/06/15
* @since JDK8
*/
@Aspect //设置当前类为切面类
@Component //配置成Spring管理的bean
@Slf4j
public class MethodExporterAspect {
/*
@Around:环绕通知,最强大的通知类型,可以控制方法入参、执行、返回结果等各方面细节
“@annotation(xxx.MethodExporter)”:表示任何添加@MethodExporter注解的目标方法都将在执行方法前先执行该切面方法
*/
@Around(“@annotation(cn.baidou.dianping.annotation.MethodExporter)”)
public Object methodExporter(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();//开始时间
Object proceed = joinPoint.proceed(); // 执行目标方法,获取方法返回值
long endTime = System.currentTimeMillis(); //结束时间
ObjectMapper mapper = new ObjectMapper();
// 将入参JSON序列化
String jsonParam = mapper.writeValueAsString(joinPoint.getArgs());//joinPoint.getArgs()获取目标方法的参数
// 将返回结果JSON序列化
String jsonResult = null;
if (jsonResult != null) {
jsonResult = mapper.writeValueAsString(proceed);//mapper.writeValueAsString()可用于将任何Java值序列化为字符串
} else {
jsonResult = “null”;
}
// 模拟上报过程
log.debug(“正在上报服务器调用过程:\ntarget:{}.{}()\nexecution:{}ms,\nparameter:{}\nresult:{}”,
joinPoint.getTarget().getClass().getSimpleName(),
joinPoint.getSignature().getName(),
(endTime – startTime),
jsonParam,
jsonResult);
return proceed;
}
}
4、编写测试代码
package cn.baidou.dianping.controller;
import cn.baidou.dianping.annotation.MethodExporter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
* @author 白豆五
* @version 2023/06/15
* @since JDK8
*/
@RestController
@RequestMapping(“/test”)
public class TestController {
@MethodExporter
@GetMapping(“/list”)
public Map test() {
Map resultMap = new LinkedHashMap();
resultMap.put(“code”, “200”);
resultMap.put(“message”, “ok”);
try {
TimeUnit.SECONDS.sleep(new Random().nextInt(10));
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return resultMap;
}
}
控制台输出:
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
7. 本站有不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别!
66源码网 » SpringAOP+自定义注解使用