Если вариант с аннотациями не подходят (возможно, ввиду отсутствия доступа к источникам или внешнего кода), можно использовать XML для декларативного кэширования. Таким образом, вместо аннотирования методов для кэширования можно задать целевой метод и директивы кэширования извне (аналогично Advice для управления декларативными транзакциями). Пример из предыдущего раздела можно переложить на следующий пример:

<!-- служба, которую нам нужно сделать кэшируемой -->
<bean id="bookService" class="x.y.service.DefaultBookService"/>
<!-- определения кэша -->
<cache:advice id="cacheAdvice" cache-manager="cacheManager">
    <cache:caching cache="books">
        <cache:cacheable method="findBook" key="#isbn"/>
        <cache:cache-evict method="loadBooks" all-entries="true"/>
    </cache:caching>
</cache:advice>
<!-- применяем кэшируемую логику работы ко всем интерфейсам BookService -->
<aop:config>
    <aop:advisor advice-ref="cacheAdvice" pointcut="execution(* x.y.BookService.*(..))"/>
</aop:config>
<!-- определение диспетчера кэша опущено -->

В предыдущей конфигурации служба bookService сделана кэшируемой. Применяемая семантика кэширования инкапсулирована в определении cache:advice, что позволяет использовать метод findBooks для помещения данных в кэш, а метод loadBooks – для вытеснения данных. Оба определения работают относительно кэша books.

Определение aop:config применяет Advice кэша к соответствующим точкам программы с помощью выражения среза на AspectJ. В предыдущем примере описаны все методы из BookService, и к ним можно применять Advice кэша.

Декларативное кэширование XML поддерживает любые модели, основанные на аннотациях, поэтому переход между ними должен быть довольно простым. Более того, оба подхода могут использоваться в одном приложении. Подход на основе XML не затрагивает целевой код. Однако по своей природе он более перегружен. При работе с классами, имеющими перегруженные методы, которые предназначены для кэширования, определение нужных методов требует дополнительных усилий, поскольку аргумент для method не является хорошим дискриминатором. В этих случаях можно использовать срез из AspectJ, чтобы выбрать целевые методы и применять соответствующую функциональность кэширования. Однако через XML легче применять кэширование в масштабах пакета, группы или интерфейса (опять же, благодаря срезу из AspectJ) и создавать шаблоноподобные определения (как это сделано в предыдущем примере путём определения целевого кэша с помощью атрибута cache:definitions cache).