Недавно возникла необходимость кэшировать результаты возвращаемые сервисными методами. В проекте используется Spring, так что вполне очевидным было решение использовать spring-cache модуль. Посмотрел я на него - точнее, на версию 0.8 и понял, что это нам не годится - разработчики почему-то всунули все мыслимые и немыслимые зависимости в pom.xml причем scope - runtime или compile. И либа в 40 килобайт тянет за собой мегабайтные зависимости. Да и манера использования кэша мне тоже не очень понравилась: сбросить запись в кэше можно только программно, и только хорошо зная об устройстве самого кэша.
Короче - порешил я писать свою обертку вокруг кэша. И, естественно, с использованием AspectJ. Здесь можно скачать весь проект и использовать у себя.
Для применения достаточно повесить аннотацию на метод. Параметры метода будут ключом, а результаты, собственно, значением записи в кэше. Единственное условие - результаты и ключи лучше делать Serializable, так как многие кэши предлагают дополнительные фичи - запись содержимого на диск, удаленная синхронизация и тд. Сбрасывать значение кэша тоже легко - поставьте на метод, изменяющий объект, аннотация FlushEntry (ключом для записи будут те же параметры, что и при наполнении кэша), или FlushCache, чтобы сбросить все содержимое.
Проще всего разобраться с тем, как пользоваться кэшем, посмотреть тест, написанный для него:
@Cached("sampleCache")
public String getBigChunkOfData(String param) {
accessCount++;
return "hello " + param;
}
@FlushCache("sampleCache")
public void updateAllChunksOfData() {
// do something else
}
@FlushEntry("sampleCache")
public void updateBigChunkOfData(String param) {
// do something
}
@Cached на методе закэширует результат под ключом param, @FlushCache уберет все записи из поименованного кэша, а @FlushEntry уберет из кэша запись с ключом param.
Перед использованием аспекта, нужно его сконфигурировать CacheManager, две имплементации уже есть: EhCache и простой heap кэш. Конфигурируется очень просто:
aspect = CachingAspect.getInstance(); aspect.setCacheManager(myManager);
или через Spring:
<bean class="com.anydoby.cache.CachingAspect" factory-method="getInstance"> <property name="cacheManager" ref="defaultCacheManager"/> </bean> <bean id="defaultCacheManager" class="com.anydoby.cache.managers.SimpleMemoryCacheManager"/>
Этот кусочек конфигурации прилагается к проекту, так что его можно использовать вот так:
<import resource="classpath:com/anydoby/cache/spring.xml"/>
