8.5.3 使用@CacheEvict清除缓存
被@CacheEvict
注解修饰的方法可用于清除缓存,使用@CacheEvict
注解时可指定如下属性。
属性 |
描述 |
value |
必需属性。用于指定该方法用于清除哪个缓存区的数据 |
key |
通过SpEL 表达式显式指定缓存的key |
allEntries |
该属性指定是否清空整个缓存区 |
beforeInvocation |
该属性指定是否在执行方法之前清除缓存。默认是在方法成功完成之后才清除缓存。 |
condition |
该属性指定一个SpEL 表达式,只有当该表达式为true 时才清除缓存。 |
程序示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| E:\workspace_QingLiangJiJavaEEQiYeYingYongShiZhang5\CacheEvict └─src\ ├─beans.xml ├─ehcache.xml ├─lee\ │ └─SpringTest.java └─org\ └─crazyit\ └─app\ ├─domain\ │ └─User.java └─service\ ├─impl\ │ └─UserServiceImpl.java └─UserService.java
|
为UserServiceImpl
类增加两个方法,分别用于清空指定缓存和清空缓存。下面是UserServiceImpl
类的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| package org.crazyit.app.service.impl;
import org.crazyit.app.domain.User; import org.crazyit.app.service.UserService; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service;
@Service("userService") @Cacheable(value = "users") public class UserServiceImpl implements UserService { public User getUsersByNameAndAge(String name, int age) { System.out.println("--正在执行findUsersByNameAndAge()查询方法--"); return new User(name, age); } public User getAnotherUser(String name, int age) { System.out.println("--正在执行findAnotherUser()查询方法--"); return new User(name, age); } @CacheEvict(value = "users") public void evictUser(String name, int age) { System.out.println("--正在清空" + name + " , " + age + "对应的缓存--"); } @CacheEvict( value = "users", allEntries = true) public void evictAll() { System.out.println("--正在清空整个缓存--"); } }
|
上面程序中
第一个@CacheEvict
注解只是指定了value="users"
一个属性,这表明该注解用于清除users
缓存区中的数据,程序将会根据传入的name
、age
参数清除对应的数据。
第二个@CacheEvict
注解则指定了allEntries=true
,这表明该方法将会清空整个users
缓存区。
使用如下主程序来测试它。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| package lee;
import org.crazyit.app.service.UserService; import org.crazyit.app.domain.User; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTest { public static void main(String[] args) { @SuppressWarnings("resource") ApplicationContext ctx = new ClassPathXmlApplicationContext( "beans.xml"); UserService us = ctx.getBean("userService", UserService.class); User u1 = us.getUsersByNameAndAge("孙悟空", 500); User u2 = us.getAnotherUser("猪八戒", 400); us.evictUser("猪八戒", 400); User u3 = us.getAnotherUser("猪八戒", 400); System.out.println(u2 == u3); User u4 = us.getAnotherUser("孙悟空", 500); System.out.println(u1 == u4); us.evictAll(); User u5 = us.getAnotherUser("孙悟空", 500); User u6 = us.getAnotherUser("猪八戒", 400); System.out.println(u1 == u5); System.out.println(u3 == u6); } }
|
上面程序中us.evictUser("猪八戒", 400);
这行代码只是清除了缓存区中"猪八戒",400"
对应的数据,因此上面程序在①号代码处需要重新执行该方法;但在②号代码处将可直接利用缓存区中的数据,无须重新执行该方法。
程序中第二行粗体字代码清空了整个缓存,因此第二行粗体字代码以后的两次调用方法都需要重新执行(因为缓存区中已经没数据了)。
执行该程序可以看到如下输出:
1 2 3 4 5 6 7 8 9 10 11
| --正在执行findUsersByNameAndAge()查询方法-- --正在执行findAnotherUser()查询方法-- --正在清空猪八戒 , 400对应的缓存-- --正在执行findAnotherUser()查询方法-- false true --正在清空整个缓存-- --正在执行findAnotherUser()查询方法-- --正在执行findAnotherUser()查询方法-- false false
|