本文介绍一下aop中最常用的前置增强、后置返回增强以及后置异常增强(用的不多)
首先引入maven依赖
引入maven依赖
<!-- 引入aop支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
具体实战
注释写的很清楚
@Aspect//这是一个切面
@Component//告诉Spring需要将其加入到IOC容器
public class WebLogAop {
//ThreadLocal保证不受其他线程影响,用于记录接口响应时间
private static ThreadLocal<Long> threadLocal = new ThreadLocal<Long>();
//切点, 每一个controller请求方法
@Pointcut("execution(public * com.zycz.myproject.controller..*.*(..))")
public void pointCut(){
}
/**
* before advice 前置增强处理
* @author 沉鱼
* @date 2017年12月28日 上午10:40:15
* @param joinPoint 连接点
*/
@Before(value = "pointCut()")
public void doBefore(JoinPoint joinPoint) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//请求的内容,记录url、method、ip
System.out.println("URL==>" + request.getRequestURL().toString() + "," +
"METHOD==>" + request.getMethod() + "," +
"IP==>" + request.getRemoteAddr());
//请求参数,将value数组转成字符串
Map<String, String[]> params = request.getParameterMap();
Map<String,String> args = new HashMap<>();
for (Entry<String,String[]> temp : params.entrySet()) {
args.put(temp.getKey(), Arrays.toString(temp.getValue()));
}
//连接点的签名可以跟踪到程序具体类、具体方法,记录一下方法和参数
System.out.println("CLASS_METHOD==>" + joinPoint.getSignature().getDeclaringTypeName() + "." +joinPoint.getSignature().getName() + "," +
"ARGS==>" + args);
//记录请求接口开始时间
threadLocal.set(System.currentTimeMillis());
}
/***
* after returning advice 后置返回增强处理
* @author 沉鱼
* @date 2017年12月28日 上午10:41:07
* @param joinPoint 连接点
* @param returnMsg return返回的信息(就是response)
*/
@AfterReturning(pointcut = "pointCut()",returning = "returnMsg")
public void doAfterReturn(JoinPoint joinPoint,Object returnMsg) {
//与前置增强一致记录下方法名
System.out.println("CLASS_METHOD==>" + joinPoint.getSignature().getDeclaringTypeName() + "." +
joinPoint.getSignature().getName());
//记录一下接口响应时间
Long reponseTime = System.currentTimeMillis() - threadLocal.get();
System.out.println("接口响应时间(毫秒)==>" + reponseTime);
//删除threadLocal变量副本
threadLocal.remove();
}
/***
* 后置异常增强处理
* @author 沉鱼
* @date 2017年12月28日 上午11:08:16
* @param joinPoint 连接点
* @param exception 目标方法抛出的异常与增强处理的异常一致才执行,否则不执行,
* 如果是throwing对应的是Throwable类型将匹配任何类型异常
*/
@AfterThrowing(pointcut="pointCut()",throwing = "exception")
public void doAfterThrow(JoinPoint joinPoint,Throwable exception) {
//记录空指针异常
if (exception instanceof NullPointerException) {
System.out.println("报NullPointerException了!请处理一下!");
}
}
}
验证
简单写个Controller请求,就是复用我之前的SpringBoot整合Swagger2的,想了解SpringBoot整合Swagger2的可以看我这篇SpringBoot集成Swagger2
@RestController
// @ApiIgnore
@Api(tags = { "myproject" }, description = "我的工程接口详情")
public class MyProjectc {
@ApiOperation(value = "展示你所输入的内容", notes = "根据客户端输入的内容返回同样的内容", response = String.class)
@ApiImplicitParams({ @ApiImplicitParam(name = "param", value = "输入要返回的内容", required = false, dataType = "String", paramType = "query") })
@RequestMapping(value = "/showWhatYouSay", method = RequestMethod.POST)
public String showWhatYouSay(String param) {
Map<String, Object> map = new HashMap<>();
map.put("result", param);
// throw new NullPointerException();
return JSONObject.toJSONString(map);
}
}
可以看到非常简单的,你输入什么就给你返回什么的接口。中间抛空指针的是为了验证后置异常增强的。这里先注释掉。
用postman请求一下接口,可以看到返回成功。
看一下控制台会有下面的内容
URL==>http://127.0.0.1:8080/myproject/showWhatYouSay,METHOD==>POST,IP==>127.0.0.1
CLASS_METHOD==>com.zycz.myproject.controller.MyProjectc.showWhatYouSay,ARGS==>{param=[well done]}
CLASS_METHOD==>com.zycz.myproject.controller.MyProjectc.showWhatYouSay
接口响应时间(毫秒)==>120
后置异常增强验证,让接口抛出空指针异常,然后去请求一下会看到控制台这样的
后置异常增强处理用的不多,一般都用全局异常捕获来做。