0

いくつかのサービス クラス (CustomerService、AgreementService) があります。各メソッドの結果は、ehcache を使用してキャッシュされます。

一部のサービス メソッドの呼び出しは、かなりコストがかかるか、実行に時間がかかります。

私が顧客などをロードしているとき、次に顧客の同意が必要になる可能性が高いことを知っています。したがって、バックグラウンドでキャッシュするためにそれらをロードし、アプリケーションをより責任のあるものにする必要があります。

アスペクトを使ってみました。ポイントカットを CustomerService.getById(id) メソッドと @AfterReturning アドバイスに設定しました。

@AfterReturning(
    pointcut = "execution(* com.example.CustomerService.getById(..))", 
    returning = "result"
)
public void loadCustomerAgreements(Object result) {
    Customer customer = (Customer) result;
    // calls method which caches result into ehcache
    agreementService.findByCustomer(customer.getId());
}

残念ながら、このソリューションは顧客とその契約書を一度に読み込みます (応答が長いため、これは望ましくありません)。代わりに、顧客をロードしてユーザーに戻りたいと思います。次に、契約書を非同期に読み込みます。

そのためには、アドバイス@Afterが効果的です。しかし、顧客 ID を取得できないため、どの契約書をロードすればよいかわかりません。

アスペクトまたはSpringトリガーまたはその他のテクノロジーを使用してこれを行う方法はありますか?

アドバイスをありがとう。

4

1 に答える 1

0

アスペクトによって実行されるメソッドは、同じスレッドで実行されたため、それ以上のプログラムの実行をブロックしていることがわかりました。考えられる解決策は、Spring Task Execution フレームワークを使用して非同期でアスペクト メソッドを実行することです。

春の設定は次のようになります。

<task:annotation-driven executor="executorWithPoolSizeRange" scheduler="taskScheduler"/>
<task:executor id="executorWithPoolSizeRange" pool-size="5-25" queue-capacity="100"/>
<task:scheduler id="taskScheduler" pool-size="1"/>

次に、アスペクトは次のようになります。

@Async
@AfterReturning(
    pointcut = "execution(* com.example.CustomerService.getById(..))", 
    returning = "result"
)
public void loadCustomerAgreements(Object result) {
    Customer customer = (Customer) result;
    // calls method which caches result into ehcache
    agreementService.findByCustomer(customer.getId());
}

loadCustomerAgreements()利用可能な空きスレッドがある場合、これは別のスレッドでメソッドを実行します。

詳細については、次を参照してください。

于 2013-02-18T11:25:57.370 に答える