Spring определяет интерфейсы CacheManager и Cache для унификации различных технологий кэширования. Например, JCache, EhCache, Hazelcast, Guava, Redis и т. д. При использовании Spring для интеграции Cache нам необходимо зарегистрировать Bean реализованного CacheManager. Spring Boot по умолчанию использует SimpleCacheConfiguration, который представляет собой кеш, реализованный с помощью ConcurrentMapCacheManager.
CacheManager: менеджер кеша, управляет различными компонентами кеша.
CacheManager | описывать |
---|---|
SimpleCacheManager | Используйте коллекцию контрольных точек для хранения кеша, в основном для тестирования |
ConcurrentMapCacheManager | Используйте ConcurrentMap для хранения кеша |
NoOpCacheManager | Только для тестирования, на самом деле не будет хранить кеш |
EhCacheCacheManager | Использование EhCache в качестве технологии кэширования |
GuavaCacheManager | Использование Guava в качестве технологии кэширования |
HazelcastCacheManager | Использование Hazelcast в качестве технологии кэширования |
JCacheCacheManager | Поддерживает реализацию стандарта JCache (JSR-107) в качестве технологии кэширования. |
RedisCacheManager | Использование Redis в качестве технологии кэширования |
Кэшировать детали аннотаций
-
@CacheConfig: в основном используется для настройки некоторых общих конфигураций кэша, которые будут использоваться в этом классе.
Здесь @CacheConfig(cacheNames = "users"): содержимое, возвращаемое в объекте доступа к данным, настроено для хранения в объекте кеша с именем users. Мы также можем настроить набор кеша напрямую через @Cacheable без использования этой аннотации. имя для определения . -
@Cacheable: в основном для настройки метода результат может быть кэширован в соответствии с параметрами запроса метода. При этом при запросе он сначала будет получен из кеша, а если его нет, то будет инициирован доступ к БД. Аннотация в основном имеет следующие параметры:
-
значение, cacheNames: Два эквивалентных параметра (cacheNames являются новыми в Spring 4, как псевдоним для значения), которые используются для указания имени коллекции кэш-хранилища. Из-за добавления @CacheConfig в Spring 4 атрибут value, который изначально требовался в Spring 3, также стал несущественным элементом.
-
key: значение ключа объекта кэша, хранящегося в коллекции Map, не требуется.По умолчанию в качестве значения ключа используются все комбинации параметров функции.Если вы настраиваете его самостоятельно, вам нужно использовать выражение SpEL, такое as: @Cacheable(key = "#p0"): use Первый параметр функции используется как кэшированное значение ключа. Подробнее о выражениях SpEL см. в официальной документации.
-
condition: Условие кэшируемого объекта, не требуется, также необходимо использовать выражение SpEL, кэшироваться будет только контент, удовлетворяющий условию выражения, например: @Cacheable(key = "#p0", condition = "#p0.length ()
-
unless: еще один параметр условия кэша, необязательный, для него необходимо использовать выражение SpEL. Разница между ним и параметром условия заключается в его времени оценки.Условие оценивается после вызова функции, поэтому о нем можно судить по результату.
-
keyGenerator: используется для указания генератора ключей, не требуется. Чтобы указать собственный генератор ключей, нам нужно реализовать
org.springframework.cache.interceptor.KeyGenerator
интерфейс и используйте этот параметр для указания. Следует отметить, что этот параметр и ключ являются взаимоисключающими. -
cacheManager: используется для указания используемого менеджера кеша, не требуется. Нужно использовать только в том случае, если их несколько.
-
cacheResolver: используется для указания используемого преобразователя кэша, не требуется. нужно пройти
org.springframework.cache.interceptor.CacheResolver
interface для реализации собственного преобразователя кэша и укажите его с помощью этого параметра.
-
-
@CachePut: Настроен на метод, может кэшироваться по условиям, заданным параметрами.Отличается от @Cacheable тем, что не проверяет, есть ли в кэше ранее выполненный результат, а каждый раз выполняет метод и выполняет Результаты сохраняются в кэше в виде пар ключ-значение, поэтому в основном используются для операций добавления и модификации данных. Его параметры аналогичны @Cacheable.Для конкретных функций см. анализ параметров @Cacheable выше.
-
@CacheEvict: настроен на функцию, обычно используемую в методе удаления, для удаления соответствующих данных из кэша. В дополнение к тем же параметрам, что и @Cacheable, он имеет следующие два параметра:
-
allEntries: не требуется, по умолчанию false. При значении true все данные будут удалены.
-
beforeInvocation: не требуется, по умолчанию false, данные будут удалены после вызова метода, если true, данные будут удалены до вызова метода.
-
Собрать кеш Spring Boot по умолчанию
Включить поддержку кеша
добавить в класс запуска@EnableCaching
Включите поддержку кэша для автоматического сканирования.
@SpringBootApplication
@EnableCaching // 开启缓存功能
public class CacheApplication {
public static void main(String[] args) {
SpringApplication.run(CacheApplication.class, args);
}
}
Добавить зависимость spring-boot-starter-cache
Добавьте зависимость spring-boot-starter-cache в pom.xml.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
Подготовить данные
Макет данных базы данных
/**
* 数据工厂,模拟数据库的数据
*
* @author star
**/
public class DataFactory {
private DataFactory() {
}
private static List<UserDto> userDtoList;
static {
// 初始化集合
userDtoList = new ArrayList<>();
UserDto user = null;
for (int i = 0; i < 10; i++) {
user = new UserDto();
user.setName("star" + i);
user.setAge("2" + i);
userDtoList.add(user);
}
}
public static List<UserDto> getUserDaoList() {
return userDtoList;
}
}
Написать бизнес-код кеша
- Напишите слой DAO
/**
* UserRepository
*
* @author star
**/
@Repository
public class UserRepository {
/**
* 获取用户信息(此处是模拟的数据)
*/
public UserDto getUser(String username) {
UserDto user = getUserFromList(username);
return user;
}
/**
* 删除用户信息
*/
public List<UserDto> deleteUser(String username) {
List<UserDto> userDaoList = DataFactory.getUserDaoList();
userDaoList.remove(getUserFromList(username));
return userDaoList;
}
/**
* 新增数据
*/
public List<UserDto> save(String username) {
// 添加到集合
List<UserDto> userDaoList = DataFactory.getUserDaoList();
for (UserDto userDto : userDaoList) {
// 不能重复添加相同数据
if (Objects.equals(userDto.getName(), username)) {
return userDaoList;
}
}
UserDto user = new UserDto();
user.setName(username);
user.setAge("50");
userDaoList.add(user);
return userDaoList;
}
/**
* 从模拟的数据集合中筛选 username 的数据
*/
private UserDto getUserFromList(String username) {
List<UserDto> userDaoList = DataFactory.getUserDaoList();
for (UserDto user : userDaoList) {
if (Objects.equals(user.getName(), username)) {
return user;
}
}
return null;
}
}
- Напишите сервисный слой
/**
* UserService
*
* @author star
**/
@Service
@CacheConfig(cacheNames = "users")// 指定缓存名称,在本类中是全局的
public class UserService {
@Autowired
private UserRepository userRepository;
/**
* 缓存 key 是 username 的数据到缓存 users 中,
* 如果没有指定 key,则方法参数作为 key 保存到缓存中
*/
@Cacheable(key = "#username")
public UserDto getUser(String username) {
System.out.println("从数据库中获取数据,而不是读取缓存");
return userRepository.getUser(username);
}
/**
* 新增或更新缓存中的数据
*/
@CachePut(key = "#username")
public List<UserDto> save(String username) {
return userRepository.save(username);
}
/**
* 从缓存 users 中删除 key 是 username 的数据
*/
@CacheEvict(key = "#username")
public List<UserDto> deleteUser(String username) {
System.out.println("从数据库中删除数据,以及缓存中的数据");
return userRepository.deleteUser(username);
}
}
- Напишите слой контроллера
/**
* CacheResource
*
* @author star
**/
@RestController
@RequestMapping("/api")
public class CacheResource {
@Autowired
private UserService userService;
@GetMapping("/users/{username}")
public ResponseEntity<UserDto> getUser(@PathVariable String username) {
// 获取数据
UserDto user = userService.getUser(username);
return ResponseEntity.ok(user);
}
@PutMapping("/users/{username}")
public ResponseEntity<List<UserDto>> save(@PathVariable String username) {
List<UserDto> userDtoList = userService.save(username);
return ResponseEntity.ok(userDtoList);
}
@DeleteMapping("/users/{username}")
public ResponseEntity<List<UserDto>> delete(@PathVariable String username) {
List<UserDto> userDtoList = userService.deleteUser(username);
return ResponseEntity.ok(userDtoList);
}
}
демо
через интерфейс несколько разhttp://localhost:8080/api/users/star1
ПОЛУЧИТЬ данные для наблюдения за эффектом:
Вы можете видеть, что кеш включен, и его эффекты следующие: