【问题标题】:AOP on plain java application普通Java应用程序上的AOP
【发布时间】:2015-12-04 06:41:55
【问题描述】:

我已经成功地将 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 建议,但在我运行应用程序时它被忽略。我确定有一个我无法检测到的小错误。 请帮忙!

【问题讨论】:

  • 您编写了这段代码并尝试运行它(向我们展示您是如何运行它的)。你为什么要这样写,并以任何方式运行它并期望它做你想做的事? (这些问题的答案将表明您对使用 AspectJ 进行了一些研究。)
  • 我可以使用aop.xml配置来写,但我认为它不是移动的。所以,我更喜欢使用注解来指向方法建议的方法。为什么我以这种方式实现它?因为类似的东西在 Spring-boot 项目下工作。我如何运行它?来自 main 方法。
  • 所以你只是做了java Tester?
  • 是的,只是一个 Java 测试人员。
  • 好的。那么,在使用java Tester 执行程序时,AspectJ 在哪里?您需要了解的是annotations 自己什么都不做。它们只是元数据。你需要一些东西来处理它们。 AspectJ 通常通过load time weaving 执行此操作。 Spring AOP 使用另一种方法:代理。正如您所展示的,您的程序两者都没有。

标签: java annotations aop aspectj


【解决方案1】:

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

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 运行它。

【讨论】:

  • 感谢 Kriegaex,它非常有帮助。我已经将我的 IntelliJ 配置为使用 Ajca 进行编译,它运行良好!
猜你喜欢
  • 2011-09-11
  • 1970-01-01
  • 2013-04-09
  • 2011-10-30
  • 2016-07-26
  • 2015-03-13
  • 1970-01-01
  • 1970-01-01
  • 2019-01-12
相关资源
最近更新 更多