腳手架:
對不起,我不喜歡全部大寫的類名,我也用我自己的包名作爲例子,因爲我的模板已經生成它們。
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
s。
另請注意,在一種情況下,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() {}
}
看點:
你的切入點要表達的:由@Event
註釋的方法控制流內的@Loggable
註釋捕捉方法。控制流程可以用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()
。
這不是OP問題的答案。他希望從執行'sendEmail'的另一個連接點獲取事件註釋。 – kriegaex
如果我不明白它的錯誤,他在調用'sendEmail'的方法中使用相同的批註,並且切入點用於此批註 – mlg
我想你確實明白它是錯誤的。他希望在'sendEmail'上仍然有一個切入點,並從那裏訪問調用者的註釋。我知道將切入點改爲調用方法也可以以間接方式解決問題,但是如果使用不調用電子郵件方法但執行其他操作的事件註釋來註釋方法,該怎麼辦?看我即將到來的解決方 – kriegaex