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

Spring AOP-如何获得父(调用者)方法的注释

王季萌
2023-03-14
@Before(value="@annotation(com.aspect.Loggable)",argNames="taskId")

public void logEmail(JoinPoint joinPoint) {

    System.out.println("@Before is running!");
    System.out.println("hijacked : " + joinPoint.getSignature().getName());
    System.out.println("******");
}

我在带有自定义注释的方法sendmail()上有一个切入点。

此方法sendmail()是从应用程序中的不同位置调用的。

就像我们在付款被批准时从paymentManager的paymentApproved()方法调用sendEmail一样。当任务完成时,我们从taskmanager的taskComplete()方法调用sendmail。

我必须找出触发sendEmail的事件。

我在paymentManager的paymentApproved()上应用了自定义注释@EVENT(“PAYMENT”),在TaskManager的taskComplete()方法上应用了自定义注释@EVENT(“TASK”)

如何在logEmail(JoinPoint-JoinPoint)方面获取@EVENT的值。

共有2个答案

王俊楚
2023-03-14

您可以访问将其作为参数接收的注释。像这样的东西:

@Before(value="@annotation(EVENT)",argNames="taskId")

public void logEmail(JoinPoint joinPoint, Event event) {

    // do what you need with event. For example, if the field is called value you can do this:
    if ("PAYMENT".equals(event.value())) {
       // do sth
    }

    System.out.println("@Before is running!");
    System.out.println("hijacked : " + joinPoint.getSignature().getName());
    System.out.println("******");
}
宣冥夜
2023-03-14

脚手架:

很抱歉,我不喜欢所有的caps类名,我还使用了我自己的包名作为示例,因为我的模板已经生成了它们。

package de.scrum_master.app;

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

@Retention(RetentionPolicy.RUNTIME)
public @interface Loggable {}
package de.scrum_master.app;

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

@Retention(RetentionPolicy.RUNTIME)
public @interface Event {
  String value();
}

驱动程序应用程序

这是纯Java,因为我不是Spring用户。想象一下,它是一个或多个@组件。

还请注意,在一种情况下,sendEmail()是从未由@事件注释的方法调用的。这不应该触发方面,只有来自带注释方法的两个调用。

package de.scrum_master.app;

public class Application {
  public static void main(String[] args) {
    Application application = new Application();
    application.doSomething();
    application.paymentApproved();
    application.taskComplete();
  }

  public void doSomething() {
    sendEmail();
  }

  @Event("paymentApproved")
  public void paymentApproved() {
    sendEmail();
  }

  @Event("taskComplete")
  public void taskComplete() {
    sendEmail();
  }

  @Loggable
  public void sendEmail() {}
}

方面:

您的切入点想要表示:在由@Event注释的方法的控制流中,捕获由@Loggable注释的方法。控制流可以用cflow()cflowdown()切入点来表示。

package de.scrum_master.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

import de.scrum_master.app.Event;

@Aspect
public class LogAspect {
  @Before(
    "@annotation(de.scrum_master.app.Loggable) &&" +
    "execution(* *(..)) &&" +  // only needed for AspectJ, not for Spring AOP
    "cflow(@annotation(event))"
  )
  public void logEmail(JoinPoint thisJoinPoint, Event event) {
    System.out.println(thisJoinPoint + " -> " + event);
  }
}

控制台日志:

execution(void de.scrum_master.app.Application.sendEmail()) -> @de.scrum_master.app.Event(value=paymentApproved)
execution(void de.scrum_master.app.Application.sendEmail()) -> @de.scrum_master.app.Event(value=taskComplete)

更新:如果您使用的是完整的ASHOJ(例如通过加载时编织)而不是Spring AOP,您可以使用call()切入点,并从那里获得封闭连接点的静态信息。那么@事件注释就没有必要了。但是Spring AOP只是“AOP精简版”,不支持call()

 类似资料:
  • 问题内容: 我正在使用以下代码来获取JavaScript调用者函数的名称: 有没有办法发现调用该方法的行号? 另外,是否有办法获取调用该方法的JavaScript文件的名称?还是源URL? 问题答案: 这适用于我在chrome / QtWebView中

  • 问题内容: Python:如何在被调用方法中获取调用者的方法名称? 假设我有2种方法: 如果我不想对method1进行任何更改,如何在method2中获取调用者的名称(在本示例中,名称为method1)? 问题答案: inspect.getframeinfo和其他相关功能可以帮助: 该自省旨在帮助调试和开发;建议不要将其用于生产功能。

  • 问题内容: Python:如何在被调用方法中获取调用者的方法名称? 假设我有2种方法: 如果我不想对method1进行任何更改,如何在method2中获取调用方的名称(在本示例中,名称为method1)? 问题答案: 和其他相关功能可以帮助: 该自省旨在帮助调试和开发;建议不要出于生产功能目的而依赖它。

  • 一些日志记录需要在类的静态方法执行前后完成。我试图使用Spring AOP实现这一点,但它不起作用,对于普通方法来说,它是起作用的。请帮助我理解如何实现这一点,如果可以使用注释来完成,那就太好了。

  • 我正在开发小程序,我的类扩展了一个第三方api类,它有它的油漆(图形g)方法。这个类扩展了JComponent,并从它的油漆(图形g)调用super.paint(g)。现在我想直接从我的类调用JComponent油漆方法。有什么方法可以做到这一点。我在下面尝试,但给出错误 或者你可以通过跟随来理解这一点

  • 问题内容: 如何获得Python类的父类? 问题答案: 使用以下属性: 从文档: 类对象的基类的元组。 例: 另一个例子: