我們想使用AspectJ來增強某些方法時,有兩種手段跟压,一種是方法注解胰蝠,一種是類注解。日常開發(fā)中常用的是方法注解震蒋。而僅僅把方法注解放到類上茸塞,注解并不會生效,需要做一些額外的處理查剖。
例如最常見的例子钾虐,切面打印日志
注解類:
@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 {
//參數(shù)值
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;
}
}
}