我有一個CachingAspect
它使用around
建議對正確註釋的方法執行一些簡單的緩存。現在,我想要做的是特別跟蹤緩存和around
建議。AspectJ - 是否有可能執行建議?
到目前爲止,我可以攔截around
建議中的方法調用,但不能建議本身。最終,我想獲得around
意見建議的方法簽名。可能嗎?
在此先感謝!
我有一個CachingAspect
它使用around
建議對正確註釋的方法執行一些簡單的緩存。現在,我想要做的是特別跟蹤緩存和around
建議。AspectJ - 是否有可能執行建議?
到目前爲止,我可以攔截around
建議中的方法調用,但不能建議本身。最終,我想獲得around
意見建議的方法簽名。可能嗎?
在此先感謝!
你是什麼意思
[adviceexecution切入點]的意思是不工作我
對於我來說,工作得很好,像這樣:
public aspect MetaAspect {
before() : within(DummyAspect) && adviceexecution() {
System.out.println("MetaAspect: " + thisJoinPointStaticPart.getSignature());
for (Object arg : thisJoinPoint.getArgs())
System.out.println(" " + arg);
}
}
從這一點來說,看印刷簽名,你應該能夠進一步細化從DummyAspect挑選哪些意見,如果有不止一個,他們有不同的簽名。
更新:
好吧,你編輯了自己的問題,並指出,你需要確定什麼是不只是adviceexecution()
也是截獲方法的簽名。沒有100%的解決方案,但是如果你確定你的攔截建議以某種方式引用thisJoinPointStaticPart
的方法,JoinPoint.StaticPart
的一個實例將被添加到建議自己的簽名中,並且可以從你的meta方面訪問。下面是一個完整的代碼示例:
驅動程序:
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
Application application = new Application();
application.writeProperty("fullName", "John Doe");
application.readProperty("firstName");
application.doSomething(11);
}
public void writeProperty(String name, String value) {}
public String readProperty(String name) { return "foo"; }
public void doSomething(int number) {}
}
緩存方面:
package de.scrum_master.aspect;
public aspect CachingAspect {
pointcut readMethods(String propertyName) :
execution(* *.read*(String)) && args(propertyName);
before(String propertyName) : readMethods(propertyName) {
System.out.println(
"[CachingAspect] Read method called for property '" + propertyName + "'"
);
}
Object around(String propertyName) : readMethods(propertyName) {
System.out.println(
"[CachingAspect] Caching property '" + propertyName +
"' in method " + thisJoinPointStaticPart.getSignature()
);
return proceed(propertyName);
}
}
正如你所看到的,有這方面的一點建議。第一個沒有訪問任何連接點成員,第二個沒有。即我們將只能在我們的meta方面找到第二個目標籤名。
元方面:
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint.StaticPart;
public aspect AdviceInterceptor {
before() : within(CachingAspect) && adviceexecution() {
System.out.println("[AdviceInterceptor] Intercepting " + thisJoinPointStaticPart);
boolean foundSignature = false;
for (Object arg : thisJoinPoint.getArgs()) {
if (arg instanceof StaticPart) {
foundSignature = true;
StaticPart jpStaticPart = (StaticPart) arg;
System.out.println("[AdviceInterceptor] Target method = " + jpStaticPart.getSignature());
break;
}
}
if (!foundSignature)
System.out.println("[AdviceInterceptor] Target method cannot be determined from advice signature");
}
}
元建議遍歷它的參數,以便找到一個JoinPoint.StaticPart
類型參數。如果它找到一個,它會打印它的目標籤名,否則會在循環後打印一個失敗註釋。
輸出示例:
[AdviceInterceptor] Intercepting adviceexecution(void de.scrum_master.aspect.CachingAspect.before(String))
[AdviceInterceptor] Target method cannot be determined from advice signature
[CachingAspect] Read method called for property 'firstName'
[AdviceInterceptor] Intercepting adviceexecution(Object de.scrum_master.aspect.CachingAspect.around(String, AroundClosure, JoinPoint.StaticPart))
[AdviceInterceptor] Target method = String de.scrum_master.app.Application.readProperty(String)
[CachingAspect] Caching property 'firstName' in method String de.scrum_master.app.Application.readProperty(String)
可以使用thisJoinPoint.getSignature()的建議中得到這樣的方法簽名:
pointcut tolog1() : execution(* Activity+.*(..)) ;
before() : tolog1() {
String method = thisJoinPoint.getSignature().toShortString();
Log.d(ATAG, "=========== entering " + method+", parms="+Arrays.toString(thisJoinPoint.getArgs()));
}
是的,這是我在'around'的建議。但是現在我想創建另一個建議來追蹤「around」建議本身。我怎麼做? – janhink 2011-05-19 15:31:13
我的回答包含'adviceexecution()',即你可以用它攔截其他方面的建議,就像你在其他評論問。你甚至嘗試過嗎?無論如何,謝謝你接受我的回答,但我的意圖是真的幫助你。更精確地描述你的用例,然後我可以更新我的答案。 – kriegaex 2014-07-05 08:01:11
我剛剛重讀你的問題,目的似乎更清晰。我的答案後是否更新過?無論如何,我可以在週末看看它。目前我不在PC附近,我只有一臺平板電腦。 – kriegaex 2014-07-05 08:05:52
我很忙,在路上呆了一個多星期,但現在我已經更新了我的答案。檢查一下可能的解決方案。 – kriegaex 2014-07-16 15:21:47