第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 Java CDI 攔截器中獲取調(diào)用者類

在 Java CDI 攔截器中獲取調(diào)用者類

蠱毒傳說 2024-01-05 15:00:33
我正在嘗試實現(xiàn)一個緩存,該緩存保存特定業(yè)務(wù)方法調(diào)用的結(jié)果,然后每 30 分鐘刷新一次。我能夠通過使用調(diào)度方法使用單例 EJB 來實現(xiàn)這一點;但是,現(xiàn)在每個調(diào)用該業(yè)務(wù)方法的類都必須從公開緩存結(jié)果的單例中調(diào)用方法。我想避免這種行為并保持這些類中的代碼不變,因此我想到使用一個攔截器來攔截對該特定業(yè)務(wù)方法的每個調(diào)用,并返回緩存單例的結(jié)果。但是,此解決方案會導(dǎo)致應(yīng)用程序停止,因為單例調(diào)用攔截的業(yè)務(wù)方法本身來緩存其結(jié)果,因此攔截器會攔截該調(diào)用(請原諒重復(fù))并嘗試返回公開緩存值的單例方法的結(jié)果,而單例仍在等待對業(yè)務(wù)方法的調(diào)用繼續(xù)進行。最明顯的解決方案是從攔截器中獲取方法調(diào)用者,并檢查其類是否對應(yīng)于單例;如果是,則繼續(xù)調(diào)用,否則返回單例的緩存結(jié)果。但是,攔截器使用的對象似乎InvocationContext沒有公開任何方法來訪問有關(guān)被攔截方法的調(diào)用者的信息。有沒有其他方法可以訪問調(diào)用者的類,或者有解決此問題的方法嗎?這是我的單例類:@Singleton@Startuppublic class TopAlbumsHolder {    private List<Album> topAlbums;    @Inject    private DataAgent dataAgent;    @PostConstruct    @Schedule(hour = "*", minute = "*/30", persistent = false)    private void populateCache() {        this.topAlbums = this.dataAgent.getTopAlbums();    }    @Lock(LockType.READ)    public List<Album> getTopAlbums() {        return this.topAlbums;    }}這是我的攔截器:@Interceptor@Cacheable(type = "topAlbums")public class TopAlbumsInterceptor {    @Inject    private TopAlbumsHolder topAlbumsHolder;    @AroundInvoke    public Object interceptTopAlbumsCall(InvocationContext invocationContext) throws Exception {        // if the caller's class equals that of the cache singleton, then return invocationContext.proceed();         // otherwise:        return this.topAlbumsHolder.getTopAlbums();    }}請注意,該@Cacheable注釋是自定義攔截器綁定,而不是javax.persistence.Cacheable.編輯:我這樣修改了攔截器方法:@AroundInvokepublic Object interceptTopAlbumsCall(InvocationContext invocationContext) throws Exception {    for (StackTraceElement stackTraceElement : Thread.currentThread().getStackTrace())        if (TopAlbumsHolder.class.getName().equals(stackTraceElement.getClassName()))            return invocationContext.proceed();    return this.topAlbumsHolder.getTopAlbums();}但我懷疑這是最干凈的解決方案,而且我不知道它是否便攜。編輯2:如果還不夠清楚,我需要訪問有關(guān)被攔截方法的調(diào)用者類的信息,而不是訪問其方法被攔截的被調(diào)用類的信息;這就是為什么我要迭代堆棧跟蹤來訪問調(diào)用者的類,但我認為這不是一個優(yōu)雅的解決方案,即使它有效。
查看完整描述

3 回答

?
飲歌長嘯

TA貢獻1951條經(jīng)驗 獲得超3個贊

對于你需要做的事情,我會說使用攔截器或裝飾器。然而你的攔截器是錯誤的。首先,您缺少基本部分,即對將調(diào)用InvocationContext.proceed()轉(zhuǎn)發(fā)給下一個內(nèi)聯(lián)攔截器(如果有)或方法調(diào)用本身的調(diào)用。其次,您放置在那里的注入點非常具體,只有在攔截這種類型的 bean 時才會對您有所幫助。通常,周圍調(diào)用攔截器方法如下所示:


    @AroundInvoke

    Object intercept(InvocationContext ctx) throws Exception {

        // do something before the invocation of the intercepted method

        return ctx.proceed(); // this invoked next interceptor and ultimately the intercepted method

        // do something after the invocation of the intercepted method

    }

此外,如果您想要有關(guān)攔截哪個 bean 的元數(shù)據(jù)信息,每個攔截器都可以為此注入一個特殊的內(nèi)置 bean。從元數(shù)據(jù)中,您可以收集有關(guān)當(dāng)前正在攔截的 bean 的信息。以下是獲取元數(shù)據(jù)的方法:


    @Inject

    @Intercepted

    private Bean<?> bean;

請注意,攔截器不知道它們攔截的類型,它可以是任何類型,因此您通常需要對普通的進行操作Object。如果您需要更具體的東西,CDI 提供了一個裝飾器模式,它基本上是一個類型感知攔截器。它有一個特殊的注入點(委托),可以讓您直接訪問修飾的 bean。它可能更適合您的場景,請查看CDI 規(guī)范解釋裝飾器的這一部分。


查看完整回答
反對 回復(fù) 2024-01-05
?
慕容3067478

TA貢獻1773條經(jīng)驗 獲得超3個贊

迭代堆棧跟蹤來檢查TopAlbumsHolder是否存在并不是一個好方法。為了避免在調(diào)用from類
期間調(diào)用攔截器,您可以直接在收集數(shù)據(jù)并將其推送到 中指定調(diào)度程序。您可以采用另一種方式,但您的要點是直接調(diào)用DataAgent bean 內(nèi)的而不參與代理(在這種情況下,攔截器將不適用)。getTopAlbums()DataAgentDataAgentTopAlbumsHoldergetTopAlbums()

PS 請注意,緩存的數(shù)據(jù)應(yīng)該是不可變的(集合及其對象)。


查看完整回答
反對 回復(fù) 2024-01-05
?
慕村225694

TA貢獻1880條經(jīng)驗 獲得超4個贊

有一個誤會。您不將被攔截的對象注入到攔截器中,而是使用調(diào)用上下文。只需調(diào)用即可invocationContext.proceed(),無需遞歸。您可以緩存proceed() 的結(jié)果。



查看完整回答
反對 回復(fù) 2024-01-05
  • 3 回答
  • 0 關(guān)注
  • 170 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號