我们想使用AspectJ来增强某些方法时,有两种手段,一种是方法注解,一种是类注解。日常开发中常用的是方法注解。而仅仅把方法注解放到类上,注解并不会生效,需要做一些额外的处理。
例如最常见的例子,切面打印日志
注解类:
@Target({ElementType.TYPE, ElementType.METHOD}) //表示该注解可以加在类、方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnno {
}
切面类:
@Component
@Slf4j
@Aspect
public class PerLogAspect {
//方法注解生效
@Pointcut("@annotation(com.tellme.anno.PerLogAnno)")
public void methodPointCut() {
}
//类注解生效
@Pointcut("@within(com.tellme.anno.PerLogAnno)")
public void classPointCut() {
}
@Around("methodPointCut() || classPointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
//参数值
Object[] args = joinPoint.getArgs();
Signature signature = joinPoint.getSignature();
Object target = joinPoint.getTarget();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = target.getClass().getDeclaredMethod(methodSignature.getName(), methodSignature.getParameterTypes());
log.info("before method:{},args:{}", method.getName(), ObjectMapperUtils.toJSON(args));
Object proceed;
try {
proceed = joinPoint.proceed();
log.info("after method:{},result:{}", method.getName(), ObjectMapperUtils.toJSON(proceed));
} catch (Exception e) {
log.error("", e);
throw e;
}
return proceed;
}
//获取类或者方法上的注解
private static PerLogAnno getAnno(ProceedingJoinPoint joinPoint, Method method) {
PerLogAnno methodAnnotation = method.getAnnotation(PerLogAnno.class);
if (methodAnnotation == null) {
Class<?> targetCls = joinPoint.getTarget().getClass();
return targetCls.getAnnotation(PerLogAnno.class);
} else {
return methodAnnotation;
}
}
}
网友评论