案例 : 通过注解打印日志
1.自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Timer {
}
2.创建切面对注解进行处理
package com.itutorgroup.gowin.finance.listener;
import com.alibaba.fastjson.JSON;
import com.itutorgroup.gowin.finance.constants.ActionResult;
import com.xxl.job.core.biz.model.ReturnT;
import org.apache.commons.lang.ArrayUtils;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.lang.annotation.Annotation;
@Aspect
@Component
public class TimeAspect {
@Pointcut("@annotation(com.itutorgroup.gowin.finance.annotation.Timer)")
private void timer() {
}
@Around("timer()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取目标Logger
Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
// 获取目标类名称
String clazzName = joinPoint.getTarget().getClass().getName();
// 获取类名
String simpleClsName = joinPoint.getTarget().getClass().getSimpleName();
// 获取目标类方法名称
String methodName = joinPoint.getSignature().getName();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Annotation[][] parameterAnnotations = signature.getMethod().getParameterAnnotations();
if (parameterAnnotations != null && parameterAnnotations.length > 0) {
for (Annotation[] parameterAnnotation : parameterAnnotations) {
int paramIndex = ArrayUtils.indexOf(parameterAnnotations, parameterAnnotation);
for (Annotation annotation : parameterAnnotation) {
if (annotation instanceof RequestBody) {
Object paramValue = joinPoint.getArgs()[paramIndex];
logger.info("{}.{}:入参:{}", simpleClsName, methodName, JSON.toJSONString(paramValue));
}
if (annotation instanceof RequestParam) {
Object paramValue = joinPoint.getArgs()[paramIndex];
logger.info("{}.{}:入参:{}", simpleClsName, methodName, paramValue);
}
}
}
} else {
logger.info("{}.{}:无入参", simpleClsName, methodName);
}
long start = System.currentTimeMillis();
logger.info("{}: {}: start...", clazzName, methodName);
// 调用目标方法
Object result = joinPoint.proceed();
try {
if (result instanceof ActionResult) {
ActionResult<Object> response = (ActionResult<Object>) result;
logger.info("{}.{}:出参:{}", simpleClsName, methodName, JSON.toJSONString(response));
}
if (result instanceof ReturnT) {
ReturnT<Object> response = (ReturnT<Object>) result;
logger.info("{}.{}:出参:{}", simpleClsName, methodName, JSON.toJSONString(response));
}
} catch (Exception e) {
logger.error("系统异常", e);
}
long time = System.currentTimeMillis() - start;
logger.info("{}: {}: : end... cost time: {} ms", clazzName, methodName, time);
return result;
}
}
3.使用
@ApiOperation(value = "信息", notes = "信息")
@PostMapping("/queryInfo")
@Timer
public ActionResult<> queryInfo(@RequestBody RequestDto param){
return actionResult.pageOk(taxService.queryTaxBaseInfo(param));
}
@Pointcut注解
@Pointcut:标注在方法上,用来定义切入点,有11种用法
-
execution:用于匹配方法执行的连接点
@Pointcut("execution(public * com.admin.*.web.rest..*.*(..)) || execution(public * com.controller..*.*(..))")
- within:用于匹配指定类型内的方法执行
@Pointcut("within(@org.web.RestController *)")
- this:用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也* 类型匹配
@Pointcut("this(Service3)")
- target:用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配
@Pointcut("target(com.javacode2018.aop.demo9.test3.Service3)")
- args:用于匹配当前执行的方法传入的参数为指定类型的执行方法
//@1:匹配只有1个参数其类型是String类型的
@Pointcut("args(String)")
- @within:用于匹配所以持有指定注解类型内的方法
@Pointcut("@within(com.itutorgroup.gowin.finance.annotation.Timer)")
- @target:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解
-
//@1:目标类上有@Ann1注解 @Pointcut("@target(Ann1)")
- @args:用于匹配当前执行的方法传入的参数持有指定注解的执行
@Pointcut("@args(..,com.javacode2018.aop.demo9.test8.Ann8)"):匹配参数数量大于等于1,且最后一个参数所属的类型上有Ann8注解
- @annotation:用于匹配当前执行方法持有指定注解的方法
- bean:Spring AOP扩展的,AspectJ没有对于指示符,用于匹配特定名称的Bean对象的执行方法