慢來比較快有勾,虛心學技術
Spring 的緩存抽象在很大程度上是圍繞切面構建的仆邓。在 Spring 中啟用緩存時,會創(chuàng)建一個切面悼凑,它觸發(fā)一個或更多的 Spring 的緩存注解摊聋,Spring提供的緩存注解主要有以下幾個:
Ⅰ鸡捐、填充緩存
由上述注解可知,@Cacheable和@CachePut注解可以往緩存填充內容麻裁,兩者的共有屬性有:
在最簡單的情況下箍镜,在 @Cacheable 和 @CachePut 的這些屬性中,只需使用 value 屬性指定一個或多個緩存即可
上一篇文章中我們介紹了Spring整合Redis的過程悲立,我們依舊使用Redis緩存了解Spring對緩存的抽象
我們事先編寫一個BaseDao作為操作基準
@Component
public class BaseDao {
/**
* 根據id獲取信息
**/
@Cacheable(value = "myCache")
public String findOne(Integer id){
System.out.println("執(zhí)行findOne方法鹿寨。。薪夕。脚草。");
return "我是BaseDao"+id;
}
/**
* 根據id更改信息
**/
@CachePut(value = "myCache")
public String save(Integer id){
System.out.println("執(zhí)行save方法。原献。馏慨。。姑隅。");
return "BaseDao"+id;
}
/**
* 根據id移除信息
**/
@CacheEvict(value = "myCache")
public void remove(Integer id){
System.out.println("執(zhí)行remove方法写隶。。讲仰。慕趴。。");
}
}
編寫測試類:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {RedisCacheConfig.class})
public class AppTest {
@Autowired
private BaseDao baseDao;
}
測試使用@Cacheable存取數據
我們知道當緩存中沒有對應數據的時候鄙陡,會執(zhí)行使用了@Cacheable注解的方法冕房,并將結果存入緩存
如果緩存中已經存在對應數據,則直接將緩存數據返回:
@Test
public void testCacheAble(){
System.out.println(this.baseDao.findOne(0));
System.out.println(this.baseDao.findOne(0));
}
此處執(zhí)行兩次findOne(0)趁矾,測試結果:
執(zhí)行findOne方法耙册。。毫捣。详拙。
我是BaseDao0
我是BaseDao0
可以看到,此處只是實際上只有一次真正進入了findOne方法內蔓同,第二次從緩存中獲取數據饶辙,以下是redis-cli中看到的結果:
在緩存中,緩存的key值默認為 緩存名稱::傳參值
測試使用@CachePut更新數據
由于使用@CachePut注解默認每次都會進入方法并使用返回值更新緩存斑粱,所以該注解在實際業(yè)務中一般用在更新數據的方法上
@Test
public void testCachePut(){
this.baseDao.save(0);
this.baseDao.save(0);
System.out.println(this.baseDao.findOne(0));
}
測試結果:
執(zhí)行save方法畸悬。。。蹋宦。披粟。
執(zhí)行save方法。冷冗。守屉。。蒿辙。
BaseDao0
可以看到拇泛,此處兩次執(zhí)行save方法都進入了,執(zhí)行save之后再調用findOne方法思灌,依舊直接從緩存取值俺叭,緩存已更新
自定義緩存的key
@Cacheable 和 @CachePut 都有一個名為 key 屬性,這個屬性能夠替換默認的 key 泰偿,它是通過一個 SpEL 表達式計算得到的
如將上述findOne()和save()方法緩存的key定義為BaseDao的class
@Cacheable(value = "myCache",key = "#root.targetClass")
public String findOne(Integer id){
System.out.println("執(zhí)行findOne方法熄守。。耗跛。裕照。");
return "我是BaseDao"+id;
}
@CachePut(value = "myCache",key = "#root.targetClass")
public String save(Integer id){
System.out.println("執(zhí)行save方法。调塌。晋南。。羔砾。");
return "BaseDao"+id;
}
再次執(zhí)行測試testCacheAble()方法:
執(zhí)行findOne方法负间。。姜凄。政溃。
我是BaseDao0
我是BaseDao0
可以看到緩存如下:使用class com.my.spring.dao.BaseDao作為緩存的key
Ⅱ、移除緩存
使用@CacheEvict測試移除緩存
@Test
public void testCacheEvict(){
this.baseDao.remove(0);
}
執(zhí)行測試結果:
執(zhí)行remove方法檀葛。。腹缩。屿聋。。
緩存已經清除:
此時再去訪問findOne(),結果:
執(zhí)行findOne方法藏鹊。润讥。。盘寡。
我是BaseDao0
我是BaseDao0