8

Spring フレームワークのコミットに関連するhttps://github.com/spring-projects/spring-framework/commit/5aefcc802ef05abc51bbfbeb4a78b3032ff9eee3

初期化は、 afterPropertiesSet()からafterSingletonsInstantiated( )までの後の段階に設定されます。

要するに:これにより、 @PostConstruct ユースケースで使用するときにキャッシュが機能しなくなります。

より長いバージョン:これにより、使用するケースが防止されます

  1. methodB で @Cacheable を使用して serviceB を作成する

  2. @PostConstruct を使用して serviceA を作成し、serviceB.methodB を呼び出します

    @Component 
    public class ServiceA{
    
    @Autowired
    private ServiceB serviceB;
    
    @PostConstruct
    public void init() {
        List<String> list = serviceB.loadSomething();
    }
    

これにより、現在 org.springframework.cache.interceptor.CacheAspectSupport が初期化されていないため、結果がキャッシュされません。

protected Object execute(CacheOperationInvoker invoker, Object target, Method method, Object[] args) {
   // check whether aspect is enabled
   // to cope with cases where the AJ is pulled in automatically
   if (this.initialized) {
//>>>>>>>>>>>> NOT Being called
      Class<?> targetClass = getTargetClass(target);
      Collection<CacheOperation> operations = getCacheOperationSource().getCacheOperations(method, targetClass);
      if (!CollectionUtils.isEmpty(operations)) {
         return execute(invoker, new CacheOperationContexts(operations, method, args, target, targetClass));
      }
   }
//>>>>>>>>>>>> Being called
   return invoker.invoke();
}

私の回避策は、初期化メソッドを手動で呼び出すことです。

@Configuration
public class SomeConfigClass{

  @Inject
  private CacheInterceptor cacheInterceptor;

  @PostConstruct
  public void init() {
    cacheInterceptor.afterSingletonsInstantiated();
  }

これはもちろん私の問題を解決しますが、2回呼び出されるだけで副作用がありますか(意図したとおりに1回のマニュアルと1回のフレームワークによる)

私の質問は次のとおりです:

4

3 に答える 3

6

Marten が既に述べたようにPostConstruct、この時点でプロキシ インターセプターが完全に開始されているという保証がないため、このフェーズでこれらのサービスを使用することは想定されていません。

キャッシュをプリロードする最善の方法は、リッスンしてContextRefreshedEvent(4.2 でより多くのサポートが予定されています)、そこで作業を行うことです。そうは言っても、そのような使用が禁止されていることが明確でない可能性があることを理解しているため、ドキュメントを改善するためにSPR-12700を作成しました。あなたが言及していたjavadocがわかりません。

あなたの質問に答えるには:いいえ、安全な回避策ではありません。以前に使用していたものは「副作用」によって機能しました (つまり、Bean が以前のCacheInterceptorバージョンのフレームワークで同じ問題が発生する前に初期化された場合、機能するはずがありませんでした)。このような低レベルのインフラストラクチャを独自のコードで呼び出さないでください。

于 2015-02-07T14:07:47.537 に答える