AspectJ类注解&方法注解的实现(@within)

2023-09-15  本文已影响0人  小胖学编程

我们想使用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;
        }
    }
}

文章参考

自定义注解式切面不生效?看完这篇你就明白了!

上一篇 下一篇

猜你喜欢

热点阅读