首页 > 解决方案 > 私有方法的 AspectJ 编织

问题描述

我有一个适用于公共方法的 AspectJ 编织注释,但私有方法被忽略了。此方法的目的是简单地记录运行该函数所花费的时间。

@Aspect
@Slf4j
public class TimedLogAspect {

    @Pointcut("@annotation(timedLogVar)")
    public void annotationPointCutDefinition(TimedLog timedLogVar) {}

    @Pointcut("execution(* *(..))")
    public void atExecution() {}

    @Around(value = "annotationPointCutDefinition(timedLogVar) && atExecution()", argNames = "joinPoint,timedLogVar")
    public Object around(ProceedingJoinPoint joinPoint, TimedLog timedLogVar) throws Throwable {
        Stopwatch stopwatch = Stopwatch.createStarted();
        Object returnValue = joinPoint.proceed();
        stopwatch.stop();

        MessageBuilder messageBuilder = new MessageBuilder(joinPoint.toShortString(), stopwatch.elapsed(TimeUnit.MILLISECONDS))
                .attachMessage(timedLogVar.message())
                .attachMethodArgs(timedLogVar.shouldAttachMethodArgs(), Stream.of(joinPoint.getArgs()).collect(Collectors.toList()))
                .attachReturnValue(timedLogVar.shouldAttachReturnValue(), returnValue);

        log.info(messageBuilder.build(), messageBuilder.getArgs().toArray());

        return returnValue;
    }
}

这是实际的界面:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TimedLog {
    boolean shouldAttachMethodArgs() default false;
    boolean shouldAttachReturnValue() default false;
    String message() default "";
}

我已经看到了很多答案,在该部分private的第一个之前添加,我已经看到注释不支持哪个,并且我正在使用没有 SpringAOP 的 AspectJ。*executionprivileged

有任何想法吗?

标签: javaspringaspectj

解决方案


答案很简单:使用原生 AspectJ 语法。你自己提到的。您甚至说您使用完整的 AspectJ,而不是 Spring AOP。所以切换应该不是问题。

你有很多优点:

  • 更强大(如您所见,注释语法中的某些功能不可用),
  • IDE 中的语法高亮和代码完成,
  • 更具表现力的语法(更少冗长,更优雅,即无需绑定thisJoinPoint通知和更容易使用if(),无需完全限定的类名,因为您可以导入它们)。

基于注释的语法 IMO 非常难以阅读,所有内容都在注释参数内的单个字符串中。我只有在别无选择或在这里回答有关它的问题时才使用它。


推荐阅读