5

使用するキャッシュをランタイムで決定する必要があるため、Spring Boot プロジェクトにカスタムCacheResolverがあります。コンパイル エラーはありませんが、いくつかのテストを実行してカスタムCacheResolverにブレーク ポイントを配置すると、ステップインすることはありません。それ。

これは、キャッシュの構成クラスです。

@Configuration
@EnableCaching(proxyTargetClass = true)
@PropertySource(CacheConfig.CLASSPATH_DEPLOY_CACHE_PROPERTIES_PROPERTIES)
public class CacheConfig extends CachingConfigurerSupport{

      public static final String CLASSPATH_DEPLOY_CACHE_PROPERTIES_PROPERTIES = "classpath:/deploy/cache-properties.properties";

      public static final String CACHEABLE_DOCUMENTS_PROPERTY = "cacheable.documents";
      public static final String TTL_CACHEABLE_DOCUMENTS_PROPERTY = "ttl.cacheable.documents";
      public static final String SIZED_CACHEABLE_DOCUMENTS_PROPERTY = "sized.cacheable.documents";
      public static final String CACHE_NAME = "permanentCache";
      public static final String TTL_CACHE = "ttlCache";
      public static final String SIZED_CACHE = "sizedCache";
      public static final String CACHEABLE_DOCUMENTS = "cacheableDocuments";
      public static final String SIZED_CACHEABLE_DOCUMENTS = "sizedCacheableDocuments";
      public static final int WEIGHT = 1000000;
      public static final int TO_KBYTES = 1000;

      @Inject
      protected Environment environment;

      //@Bean
      @Override
      public CacheManager cacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        GuavaCache sizedCache = new GuavaCache(SIZED_CACHE, CacheBuilder.newBuilder().maximumWeight(WEIGHT).weigher(
                (key, storable) -> {
                  String json = ((Storable) storable).toJson();
                  return json.getBytes().length / TO_KBYTES;
                }
        ).build());
        GuavaCache permanentCache = new GuavaCache(CACHE_NAME,CacheBuilder.newBuilder().build());
        //GuavaCache ttlCache = new GuavaCache(TTL_CACHE, CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.MINUTES).build());
        cacheManager.setCaches(Arrays.asList(permanentCache,sizedCache));
        return cacheManager;
      }

      @Bean(name = "wgstCacheResolver")
      @Override
      public CacheResolver cacheResolver(){
        CacheResolver cacheResolver = new WgstCacheResolver(cacheManager(),cacheableDocuments(),sizedCacheableDocuments());
        return cacheResolver;
      }


      @Bean(name = CACHEABLE_DOCUMENTS)
      public List<String> cacheableDocuments(){
        String[] cacheableDocuments = StringUtils.commaDelimitedListToStringArray(environment.getProperty(CACHEABLE_DOCUMENTS_PROPERTY));
        return Arrays.asList(cacheableDocuments);
      }

      @Bean(name = SIZED_CACHEABLE_DOCUMENTS)
      public List<String> sizedCacheableDocuments(){
        String[] sizedCacheableDocuments = StringUtils.commaDelimitedListToStringArray(environment.getProperty(SIZED_CACHEABLE_DOCUMENTS_PROPERTY));
        return Arrays.asList(sizedCacheableDocuments);
      } 
    }

ここに私の CacheResolver があります

public class WgstCacheResolver extends AbstractCacheResolver {

  private final List<String> cacheableDocuments;
  private final List<String> sizedCacheableDocuments;

  public WgstCacheResolver(final CacheManager cacheManager,final List<String> cacheableDocuments, final List<String> sizedCacheableDocuments) {
    super(cacheManager);
    this.cacheableDocuments = cacheableDocuments;
    this.sizedCacheableDocuments = sizedCacheableDocuments;
  }

  /**
   * Resolves the cache(s) to be updated on runtime
   * @param context
   * @return*/
  @Override
  protected Collection<String> getCacheNames(final CacheOperationInvocationContext<?> context) {

    final Collection<String> cacheNames = new ArrayList<>();
    final AbstractDao dao = (AbstractDao)context.getTarget();
    final String documentType = dao.getDocumentType().toString();
    if (cacheableDocuments.contains(documentType)){
      cacheNames.add("permanentCache");
    }
    if (sizedCacheableDocuments.contains(documentType)){
      cacheNames.add("sizedCache");
    }
    return cacheNames;
  }
}

そして、ここでキャッシュを使用する私のDAO:

    @Component
    @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.DEFAULT)
    @CacheConfig(cacheResolver = "wgstCacheResolver")
    public class CacheableDao<T extends Storable> extends AbstractDao<T> {

      private final Logger logger = LoggerFactory.getLogger(CacheableDao.class);

      public CacheableDao(final Bucket bucket, final Class<T> typeParameterClass, final DocumentType documentType) {
        super(bucket, typeParameterClass, documentType);
      }

      @Cacheable(key = "{#root.methodName, #root.target.generateFullKey(#key)}")
      public T get(final String key) throws DatastoreAccessException, ObjectMappingException {
        //do something
      }
.
.
.
}

CacheResolver拡張する代わりに実装しようとしAbstractCacheResolverましたが、違いはありませんでした。

ありがとうございました。

4

2 に答える 2

0

少し行ったり来たりした後 (申し訳ありません!)、これは本当に Spring Framework のバグであることがわかりました。

SPR-13081を作成しました。次のメンテナンス リリースで修正される予定です ( 4.1.7.RELEASE)。サンプルプロジェクトありがとうございます!

于 2015-05-29T08:21:32.780 に答える