普通 java 应用程序上的 AOP

AOP on plain java application

我已经成功地将 AOP 与 Spring 应用程序一起使用,但令人惊讶的是我坚持使用一个简单的 java 项目。现在我正在尝试实现非常简单的 AOP java 应用程序,但它不起作用。这是基本的 类:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class MySimpleLoggerAspect {

    @Around("@annotation(TimeableMetric)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("myTrace:before call ");

        Object retVal = null;
        try {
            retVal = joinPoint.proceed();
        } finally {
            System.out.println("myTrace:after call ");
        }
        return retVal;
    }
}

public class SampleClass {

    @TimeableMetric
    public String doService(String in){
        System.out.println("inside Service");
        return in;
    }
}

public class Tester {
    public static void main(String[] args) {
        System.out.println(new SampleClass().doService("Hello World"));
    }
}


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface TimeableMetric {

}

如您所见,这是一个非常简单的应用程序,只有 4 个 类。 IntelliJ 正确检测到 AOP 建议,但当我 运行 应用程序时它被忽略了。我确定有一个我无法检测到的小错误。 请帮忙!

代码没问题,对我来说,控制台日志如下所示:

myTrace:before call 
myTrace:before call 
inside Service
myTrace:after call 
myTrace:after call 
Hello World

可能你从 Spring AOP 开始使用,只为切入点 @annotation(TimeableMetric) 获取一个拦截,但与 Spring AOP 只知道 execution() 切入点相反,AspectJ还支持 call() 切入点。因此,如果您将切入点更改为 @annotation(TimeableMetric) && execution(* *(..)),则日志将变为:

myTrace:before call 
inside Service
myTrace:after call 
Hello World

至于如何应用方面的问题,你需要

  • 使用 AspectJ 编译器编译应用程序 ajc 然后
  • 运行 它与类路径上的 AspectJ 运行时间 aspectjrt.jar