Spring缓存抽象(AdviceMode.ASPECTJ)在spring-data-jpa存储库

时间:2015-10-01 09:26:32

标签: java caching spring-data aspectj aspectj-maven-plugin

我使用spring-data-jpa 1.9.0.RELEASE并希望在我的存储库中使用spring缓存机制,例如。

public interface LandDao extends CrudRepository<Land, Long> {

    @Cacheable("laender")
    Land findByName(String land)
}

这是我的缓存配置:

@Configuration
@EnableCaching(mode=AdviceMode.ASPECTJ)
public class EhCacheConfiguration extends CachingConfigurerSupport {
...

请注意,我使用AdviceMode.ASPECTJ(编译时编织)。不幸的是,在调用repo方法时,缓存无法正常工作&#39; findByName&#39;。 将缓存模式更改为AdviceMode.PROXY一切正常。

为确保缓存原则上与aspectJ一起工作,我编写了以下服务:

@Service
public class LandService {

  @Autowired
  LandDao landDao;

  @Cacheable("landCache")
  public Land getLand(String bez) {
    return landDao.findByName(bez);
  }
}

在这种情况下,缓存就像魅力一样。所以我认为我的应用程序的所有部分都已正确配置,问题是spring-data-jpa和AspectJ缓存模式的组合。有没有人知道这里出了什么问题?

1 个答案:

答案 0 :(得分:2)

好的,我自己找到了问题的答案。负责方面org.springframework.cache.aspectj.AnnotationCacheAspect的javadoc说:

  

使用此方面时,必须注释实现类(和/或该类中的方法),而不是该类实现的接口(如果有)。 AspectJ遵循Java的规则,即接口上的注释不会被继承。

因此,不可能在存储库接口中使用@cacheable注释以及aspectj。我现在的解决方案是使用custom implementations for Spring Data repositories

自定义存储库功能的接口:

public interface LandRepositoryCustom {

    Land findByNameCached(String land);
}

使用查询dsl实现自定义存储库功能:

@Repository
public class LandRepositoryImpl extends QueryDslRepositorySupport 
       implements LandRepositoryCustom {

  @Override
  @Cacheable("landCache")
  public Land findByNameCached(String land) {
    return from(QLand.land).where(QLand.land.name.eq(land)).singleResult(QLand.land);
  }
}

请注意findByNameCached方法的@Cacheable注释。

基本存储库界面:

public interface LandRepository extends CrudRepository<Land, Long>, LandRepositoryCustom {
}

使用存储库:

public class SomeService {

  @Autowired
  LandRepository landDao;

  public void foo() {
    // Cache is working here:-)
    Land land = landDao.findByNameCached("Germany");
  }
}

在弹簧数据参考中添加与此限制相关的注释会很有帮助。