1 回答

TA貢獻1802條經(jīng)驗 獲得超5個贊
正如JB Nizet已經(jīng)說過的那樣,@annotation(my.package.MyAnnotation)
它旨在捕獲方法上的注釋,而不是字段上的注釋,這解釋了為什么您對任何事情發(fā)生的期望都是錯誤的。
如果你想通過 AOP 找出一個類是否有一個帶有特定注釋的成員,你需要使用一個特殊的切入點,比如hasfield(@MyAnnotation * *)
.?但是這個切入點在 Spring AOP 中不可用,你需要切換到 AspectJ。get(@MyAnnotation MyType *)
如果您想通過或攔截對此類字段的讀/寫訪問,也是如此set(@MyAnnotation MyType *)
。
AspectJ 還提供了特殊的切入點
在類加載后攔截類的靜態(tài)初始化 - >
staticinitialization()
攔截構(gòu)造函數(shù)執(zhí)行->
MyType.new()
只要是合適的時間,您就可以使用它們來執(zhí)行您的方面建議。@PostConstruct
在您的示例中,如果很明顯所有目標類都有其中一個,您還可以更輕松地掛接到方法中。
我的回答很籠統(tǒng),因為你沒有詳細解釋你到底想做什么。所以請隨時提出后續(xù)問題。
更新:我檢查了你最新的問題更新。我不明白,這是針對一個非常簡單的問題的非常人為的解決方案,也不是 AOP 解決的好案例。盡管我很喜歡 AOP,但我看不出這種情況是一個橫切關(guān)注點:
它似乎只影響一個類,
InfluxDBReporter
.您正在使用一個注釋,該注釋的存在唯一目的是告訴一個方面要做什么。
更糟糕的是,您將注釋放在私有字段上,但期望外部類(在本例中為方面)對其作出反應。雖然這在技術(shù)上使用 AspectJ 是可行的,但它是糟糕的設(shè)計,因為您將私有信息泄漏到外部。
通過從您的示例類中跳過公共方法,您不會保存任何昂貴的與數(shù)據(jù)庫相關(guān)的操作,因為迭代一個空
KeySet
意味著什么都不會發(fā)生,因此也不會有任何與數(shù)據(jù)庫相關(guān)的錯誤。這里唯一真正發(fā)生的是構(gòu)建器調(diào)用。它們應該很便宜。
即使假設(shè)你有更多應該跳過的公共方法,如果你確實想堅持使用這種方法,我實際上會設(shè)計這樣的 AOP 解決方案:
向您的應用程序類添加一個方法
public boolean isConnectedToDB() { return !dbs.isEmpty(); }
。在您方面,使用
@Around
建議并從那里調(diào)用布爾方法,僅joinPoint.proceed()
在有任何連接時才調(diào)用。否則不要繼續(xù),而是什么也不做(對于void
方法)或返回一個虛擬結(jié)果null
(對于非void
方法)。
確切的解決方案取決于您是否只有這個類或多個具有類似要求的類,如果您只有public void
方法或非空方法。
此外,您提到INFLUX_DB_SERVER
但我不知道這是什么,因為我在您的代碼中的任何地方都看不到它。
最后但并非最不重要的一點是:我剛剛注意到您希望在 . 注釋的方法中發(fā)生某些事情@Pointcut
。抱歉,即使切入點沒有錯,那里也會發(fā)生一些事情,因為切入點定義只是用于實際的建議方法,例如@Before
,?@After
,?@Around
。您想要執(zhí)行的操作進入通知,而不是進入切入點。我建議您在嘗試設(shè)計基于 AOP 的解決方案之前先學習 AOP 基礎(chǔ)知識。
添加回答
舉報