当前位置: 首页 > 知识库问答 >
问题:

如何对带注释方法的每个方法调用执行某些操作?

国跃
2023-03-14

我想用Java编写一个注释,它在执行带注释的方法之前和之后执行一些东西,类似于Spring中的aspects。

我已经尝试过Spring方面,但它只适用于bean(正如这家伙在这里提到的),我想保持独立于Spring框架。

字符串写入控制台的简单类:

public class Main {
    public static void main(String[] args) {
        say("How are you?");
    }

    @Hello
    private static void say(String s) {
        System.out.println(s);
    }
}

相关注释:

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)
public @interface Hello {}

而我需要像这样的东西(由Spring相位推断)

public Object process(ProceedingJoinPoint proceedingJoinPoint) {
    System.out.println("Hello");
    Object proceed = null;
    try {
        proceed = proceedingJoinPoint.proceed();
    } catch (Throwable throwable) {
        throwable.printStackTrace();
    }
    System.out.println("world!");
    return proceed;
}

我想要以下输出:

你好

你好吗

世界

编辑:

我创建了以下方面(没有注释),但它不起作用

@lombok.extern.java.Log
public aspect Log {
    pointcut methodExecuted():execution(* **(..));

    void around(): methodExecuted() {
        log.info("Hello");
        proceed();
        log.info("world!");
    }
}

我的错在哪里?

共有1个答案

万阳嘉
2023-03-14

假设您使用AspectJ编译器成功编译了aspect,那么它应该与您使用的代码一起工作,只是它会记录所有方法的执行,也就是说,main(…) ,所以在“你好吗?”前后两次使用aspect的输出。如果你没有看到任何东西,那么你可能在设置构建系统时犯了一个错误。

您应该更改切入点,将日志记录实际限制为带注释的方法:execution(**(..)

我还强烈建议您不要盲目使用AspectJ这样的强大工具,还要在使用之前研究一些文档。很明显,你没有这样做,或者只是草率地做了。然后,你就得到了一种效果,那就是作为一个没有能力使用工具的用户。;-)

这是我的MCVE:

package de.scrum_master.app;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

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

@Retention(RUNTIME)
@Target(METHOD)
public @interface Hello {}
package de.scrum_master.app;

public class Application {
  public static void main(String[] args) {
    say("How are you?");
  }

  @Hello
  private static void say(String s) {
    System.out.println(s);
  }
}
package de.scrum_master.aspect;

import de.scrum_master.app.Hello;

public aspect LoggingAspect {
  pointcut methodExecuted() : execution(* *(..)) && @annotation(Hello);

  Object around(): methodExecuted() {
    System.out.println("Hello");
    Object result = proceed();
    System.out.println("world!");
    return result;
  }
}

控制台日志:

Hello
How are you?
world!

 类似资料:
  • 我想在调用非公共方法(bar)后执行一些特定操作。此方法在另一个方法(foo)中调用。请注意,“bar”和“foo”都是在第三方jar文件中定义的。 我试图在面向方面的编程中使用Spring使用注释来做到这一点。然而,我不能这样做。 在调用jar文件中的特定函数之后,有人能告诉我如何做特定的事情(调用特定函数)吗?

  • 问题内容: 我是Java的初学者,并且一直在研究各种解决方案来解决这个问题,并且使自己陷入困境。我尝试过使用Threads,然后发现了这个Timer类,到目前为止,它一直没有成功。如果您可以 使用main方法 发布 可执行代码, 这样我就可以看到它正常工作并从那里开始玩,那将很棒。 启动程序 呼叫 生成随机数并设置Timer相应的时间。 定时器关闭时,再次通话。 可能使用的是:http : //d

  • 问题内容: 我正在尝试定义一个切入点,该切入点将捕获用(ie)注释的每个方法。这是我自己的注释。 此外,我想访问该方法的第一个参数,该参数将是类型。也许还有其他争论,但我不在乎。 编辑 这就是我现在所拥有的。我不知道如何传递带有注释的方法的第一个参数。 问题答案: 这样的事情应该做:

  • 下面的@Retryable代码适用于直接调用方法的情况,但通过@Async annotated method调用Retryable方法会引发异常。有什么建议吗? 这是我的服务课 这是Junit测试类 这里是Spring Boot应用程序类 例外如下。请对此提出任何建议。 retryWithException-0

  • 我有一个由tomcat运行的前端,我的后端处理由Mule运行。 例如, 你好世界html 你好世界js公司 我的触发器。Java语言 招呼xml 我的结果一直以错误的形式返回,这意味着它在JavaScript级别失败。 不太确定出了什么问题。 Tomcat正在本地主机8080上运行。