java 是否可以定义通用接口并使用Spring @CacheConfig?

ltqd579y  于 2023-03-06  发布在  Java
关注(0)|答案(2)|浏览(120)

this answer的启发,我尝试了以下操作

@NoRepositoryBean
public interface CacheableRepository<T, ID extends Serializable>
    extends JpaRepository<T, ID>, JpaSpecificationExecutor<T>,       PagingAndSortingRepository<T, ID> {

    @Cacheable()
    T findOne(ID id);

    @Cacheable()
    List<T> findAll();

   @Cacheable()
   Page<T> findAll(Pageable pageable);

   @CacheEvict(allEntries = true)
   <S extends T> S save(S entity);

   @CacheEvict(allEntries = true)
   void delete(ID id);

}

然后使用此接口定义Used存储库

@CacheConfig(cacheNames={"uniqueCache"})
 public interface SomeObjectRepo extends    CacheableRepository<SomeObject, Long>  {

     @Cacheable(key = "someobject+#p0")
     List<SomeObject> findByType(Integer type);

    @Cacheable(key = "someobject+#p0")
    List<SomeObject> findByCategory(String field);

    @Cacheable(key="someobject+#p0.concat(#p1)")
    List<SomeObject> findByCategoryAndWizardType_id(String field,Integer id);

 }

作品:

该高速缓存适用于findByTypefindByCategoryfindByCategoryAndWizardType_id

不工作:

对于在CacheableRepository定义的所有cacheable方法,SomeObjectRepo上的CacheConfig注解似乎不影响CacheableRepository

我的问题:

为什么注解不起作用?有没有变通办法让这个结构起作用?
谢谢,奥克

zlhcx6iw

zlhcx6iw1#

是的,这差不多就是奥利和我在试图支持这种情况时发现的。
我建议您在spring data项目中创建一个问题来请求该特性。

ycl3bljg

ycl3bljg2#

通过使用如下所示的CacheResolver,可以根据目标存储库的名称(执行了其方法)来确定该高速缓存名称。
用于定义默认CacheResolver的配置:

@Configuration
@EnableCaching
@RequiredArgsConstructor
public class CacheConfig extends CachingConfigurerSupport {

  @Lazy private final CacheManager cacheManager;

  @Override
  public CacheResolver cacheResolver() {
    return new CustomCacheResolver(this.cacheManager);
  }

  public static class CustomCacheResolver extends SimpleCacheResolver {

    protected CustomCacheResolver(CacheManager cacheManager) {
      super(cacheManager);
    }

    @Override
    protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> context) {
      return List.of(context.getTarget().getClass().getInterfaces()[0].getSimpleName());
    }
  }
}

使用这个解决方案,不需要指定缓存名称,因为所有可缓存的方法都缓存在SomeObjectRepo缓存名称下。
注意:要缓存类方法,应该向getCacheNames添加额外的逻辑,否则它将无法工作。

相关问题