上一篇我们学会了如何使用 Spring Boot 使用进程内缓存在加速数据访问. 可能大家会问, 那我们在 Spring Boot 中到底使用了什么缓存呢?
在 Spring Boot 中通过 @EnableCaching 注解自动化配置合适的缓存管理器 (CacheManager),Spring Boot 根据下面的顺序去侦测缓存提供者:
- Generic
- JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)
- EhCache 2.x
- Hazelcast
- Infinispan
- Couchbase
- Redis
- Caffeine
- Simple
除了按顺序侦测外, 我们也可以通过配置属性 spring.cache.type 来强制指定. 我们也可以通过 debug 调试查看 cacheManager 对象的实例来判断当前使用了什么缓存. 在上一篇中, 我们也展示了如何去查看当前使用情况.
当我们不指定具体其他第三方实现的时候, Spring Boot 的 Cache 模块会使用 ConcurrentHashMap 来存储. 而实际生产使用的时候, 因为我们可能需要更多其他特性, 往往就会采用其他缓存框架, 所以接下来我们会分几篇分别介绍几个常用优秀缓存的整合与使用.
使用 EhCache
本篇我们将介绍如何在 Spring Boot 中使用 EhCache 进程内缓存. 这里我们将沿用上一篇的案例结果来进行改造, 以实现 EhCache 的使用.
先回顾下这个基础案例的三个部分:
User 实体的定义
- @Entity
- @Data
- @NoArgsConstructor
- public class User {
- @Id
- @GeneratedValue
- private Long id;
- private String name;
- private Integer age;
- public User(String name, Integer age) {
- this.name = name;
- this.age = age;
- }
- }
User 实体的数据访问实现 (涵盖了缓存注解)
- @CacheConfig(cacheNames = "users")
- public interface UserRepository extends JpaRepository<User, Long> {
- @Cacheable
- User findByName(String name);
- }
测试验证用例 (涵盖了 CacheManager 的注入, 可用来观察使用的缓存管理类)
- @Slf4j
- @RunWith(SpringRunner.class)
- @SpringBootTest
- public class Chapter51ApplicationTests {
- @Autowired
- private UserRepository userRepository;
- @Autowired
- private CacheManager cacheManager;
- @Test
- public void test() throws Exception {
- // 创建 1 条记录
- userRepository.save(new User("AAA", 10));
- User u1 = userRepository.findByName("AAA");
- System.out.println("第一次查询:" + u1.getAge());
- User u2 = userRepository.findByName("AAA");
- System.out.println("第二次查询:" + u2.getAge());
- }
- }
接下来我们通过下面的几步操作, 就可以轻松的把上面的缓存应用改成使用 ehcache 缓存管理.
第一步: 在 pom.xml 中引入 ehcache 依赖
- <dependency>
- <groupId.NET.sf.ehcache</groupId>
- <artifactId>ehcache</artifactId>
- </dependency>
在 Spring Boot 的 parent 管理下, 不需要指定具体版本, 会自动采用 Spring Boot 中指定的版本号.
第二步: 在 src/main/resources 目录下创建: ehcache.xml
- <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="ehcache.xsd">
- <cache name="users"
- maxEntriesLocalHeap="200"
- timeToLiveSeconds="600">
- </cache>
- </ehcache>
完成上面的配置之后, 再通过 debug 模式运行单元测试, 观察此时 CacheManager 已经是 EhCacheManager 实例, 说明 EhCache 开启成功了. 或者在测试用例中加一句 CacheManager 的输出, 比如:
- @Autowired
- private CacheManager cacheManager;
- @Test
- public void test() throws Exception {
- System.out.println("CacheManager type :" + cacheManager.getClass());
- userRepository.save(new User("AAA", 10));
- User u1 = userRepository.findByName("AAA");
- System.out.println("第一次查询:" + u1.getAge());
- User u2 = userRepository.findByName("AAA");
- System.out.println("第二次查询:" + u2.getAge());
- }
执行测试输出可以得到:
- CacheManager type : class org.springframework.cache.ehcache.EhCacheCacheManager
- Hibernate: select next_val as id_val from hibernate_sequence for update
- Hibernate: update hibernate_sequence set next_val= ? where next_val=?
- Hibernate: insert into user (age, name, id) values (?, ?, ?)
- 2020-07-14 18:09:28.465 INFO 58538 --- [ main] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
- Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.name as name3_0_ from user user0_ where user0_.name=?
第一次查询: 10
第二次查询: 10
可以看到:
第一行输出的 CacheManager type 为
org.springframework.cache.ehcache.EhCacheCacheManager
, 而不是上一篇中的 ConcurrentHashMap 了.
第二次查询的时候, 没有输出 SQL 语句, 所以是走的缓存获取
整合成功!
代码示例
本文的相关例子可以查看下面仓库中的 chapter5-2 目录:
GitHub:
Gitee:
如果您觉得本文不错, 欢迎 Star 支持, 您的关注是我坚持的动力!
来源: https://segmentfault.com/a/1190000023253070