@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("******");
}
我在方法sendEmail()
上有一个带有自定义注释的pointCut。
此方法sendEmail()
在我们的应用程序中从不同位置调用。
就像我们在付款获得批准时从paymentApproved ()
paymentManager方法调用sendEmail一样。
当任务完成时,我们从taskManger的taskComplete()
方法调用sendEmail。
我必须找出触发sendEmail的事件。
我在paymentManager的@EVENT("PAYMENT")
上应用了自定义注释paymentApproved ()
,在{person}工具的@EVENT("TASK")
方法上应用了taskComplete()
。
如何在@EVENT
方面获得logEmail(JoinPoint joinPoint)
的价值。
答案 0 :(得分:1)
<强>脚手架:强>
抱歉,我不喜欢全帽类名,我也使用自己的包名作为例子,因为我的模板已经生成了它们。
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用户。试想一下,它是一个或多个@Component
。
另请注意,在一个案例中sendEmail()
未被@Event
注释的方法调用。这不应该触发方面,只有来自注释方法的两个调用。
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() {}
}
<强>方面:强>
你的切入点想要表达:在@Loggable
注释的方法的控制流程中,用@Event
注释的Catch方法。控制流可以用cflow()
或cflowbelow()
切入点表示。
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)
更新:如果您使用完整的AspectJ(例如通过加载时编织)而不是Spring AOP,您可以使用call()
切入点并从那里获得封闭的连接点静态信息。然后不需要@Event
注释。但Spring AOP只是“AOP lite”而不支持call()
。
答案 1 :(得分:0)
您可以访问接收它的注释作为参数。像这样:
@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("******");
}