在Spring Boot中通過(guò)@EnableCaching
注解自動(dòng)化配置合適的緩存管理器(CacheManager),Spring Boot根據(jù)下面的順序去偵測(cè)緩存提供者:
- Generic
- JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)
- EhCache 2.x
- Hazelcast
- Infinispan
- Couchbase
- Redis
- Caffeine
- Simple
除了按順序偵測(cè)外,我們也可以通過(guò)配置屬性spring.cache.type來(lái)強(qiáng)制指定。我們也可以通過(guò)debug調(diào)試查看cacheManager
對(duì)象的實(shí)例來(lái)判斷當(dāng)前使用了什么緩存。在上一篇open in new window中,我們也展示了如何去查看當(dāng)前使用情況。
當(dāng)我們不指定具體其他第三方實(shí)現(xiàn)的時(shí)候,Spring Boot的Cache模塊會(huì)使用ConcurrentHashMap
來(lái)存儲(chǔ)。而實(shí)際生產(chǎn)使用的時(shí)候,因?yàn)槲覀兛赡苄枰嗥渌匦?,往往就?huì)采用其他緩存框架,所以接下來(lái)我們會(huì)分幾篇分別介紹幾個(gè)常用優(yōu)秀緩存的整合與使用。
#使用EhCache
本篇我們將介紹如何在Spring Boot中使用EhCache進(jìn)程內(nèi)緩存。這里我們將沿用上一篇open in new window的案例結(jié)果來(lái)進(jìn)行改造,以實(shí)現(xiàn)EhCache的使用。
先回顧下這個(gè)基礎(chǔ)案例的三個(gè)部分:
User實(shí)體的定義
@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實(shí)體的數(shù)據(jù)訪問(wèn)實(shí)現(xiàn)(涵蓋了緩存注解)
@CacheConfig(cacheNames = "users")
public interface UserRepository extends JpaRepository<User, Long> {
@Cacheable
User findByName(String name);
}
測(cè)試驗(yàn)證用例(涵蓋了CacheManager的注入,可用來(lái)觀察使用的緩存管理類)
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter51ApplicationTests {
@Autowired
private UserRepository userRepository;
@Autowired
private CacheManager cacheManager;
@Test
public void test() throws Exception {
// 創(chuàng)建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());
}
}
接下來(lái)我們通過(guò)下面的幾步操作,就可以輕松的把上面的緩存應(yīng)用改成使用ehcache緩存管理。
第一步:在pom.xml
中引入ehcache依賴
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
在Spring Boot的parent管理下,不需要指定具體版本,會(huì)自動(dòng)采用Spring Boot中指定的版本號(hào)。
第二步:在src/main/resources
目錄下創(chuàng)建: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>
完成上面的配置之后,再通過(guò)debug模式運(yùn)行單元測(cè)試,觀察此時(shí)CacheManager已經(jīng)是EhCacheManager實(shí)例,說(shuō)明EhCache開(kāi)啟成功了?;蛘咴跍y(cè)試用例中加一句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());
}
執(zhí)行測(cè)試輸出可以得到:
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
了。 - 第二次查詢的時(shí)候,沒(méi)有輸出SQL語(yǔ)句,所以是走的緩存獲取
整合成功!歡迎關(guān)注本系列教程:《Spring Boot 2.x基礎(chǔ)教程》
#代碼示例
本文的相關(guān)例子可以查看下面?zhèn)}庫(kù)中的chapter5-2
目錄:
- Github:https://github.com/dyc87112/SpringBoot-Learning/open in new window
- Gitee:https://gitee.com/didispace/SpringBoot-Learning/