@Cacheable缓存注解(以Redis作为缓存)
使⽤时需要先导⼊依赖包,
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
此处注意,导⼊2.1.3版本的依赖时会报错不到加载类的错误,尽管在maven官⽅仓库中包含了2.1.3的依赖信息,所以导⼊的使⽤较多的2.1.1依赖。
使⽤⽅法
1.@Cacheable
el表达式执行结果为
在启动类***Application.java主类中中加⼊注解@EnableCaching。之后再任意⽅法或者类上加⼊@Cacheable注解,当标记在⼀个⽅法上时表⽰该⽅法是⽀持缓存的,当标记在⼀个类上时则表⽰该类所有的⽅法都是⽀持缓存的。对于⼀个⽀持缓存的⽅法,Spring会在其被调⽤后将其返回值缓存起来,以保证下次利⽤同样的参数来执⾏该⽅法时可以直接从缓存中获取结果,⽽不需要再次执⾏该⽅法。Spring在缓存⽅法的返回值时是以键值对进⾏缓存的,值就是⽅法的返回结果,⾄于键的话,Spring⼜⽀持两种策略,默认策略和⾃定义策略,这个稍后会进⾏说明。需要注意的是当⼀个⽀持缓存的⽅法在对象内部被调⽤时是不会触发缓存功能的。@Cacheable可以指定三个基本属
性,value、key和condition。
所谓键值对缓存key,就是说redis缓存的时候key的⽣成时如下格式:value::key,例如,指定value为test,key为1,即
@Cacheable(value="test",key="1")⽣成的缓存key值为test::1。
在@Cacheable注解中key的取值也可以使⽤SpringEL表达式来⽣成,内部可以嵌套⽅法的参数信息,例如,
@Cacheable(value = "fuck",key = "#id")
public List<String> getPrud(@RequestParam("test") String id){
System.out.println("如果第⼆次没有⾛到这⾥说明缓存被添加了");
List<String> list = new ArrayList<>();
list.add(id);
list.add("123");
list.add("123");
return list;
}
此处的key值⽣成就是使⽤getPrud⽅法中的id参数⽣成的,即fuck:: + 参数id,除了这种⽅法以外还可以使⽤keyGenerator策略来⽣成key,即实现KeyGenerator⽅法,
@Component("myKeyGenerator")
public class MyKeyGenerator implements KeyGenerator {
@Override
public Object generate(Object o, Method method, objects) {
return "";
}
在此⽅法中⽣成的返回值就是最终拼凑起来的test::后⾯的东西,实现⽅法之后再需要使⽤⽣成策略的⽅法中使⽤,
@Cacheable(value = "fuck",keyGenerator = "myKeyGenerator")
public List<String> getPrud(@RequestParam("test") String id){
System.out.println("如果第⼆次没有⾛到这⾥说明缓存被添加了");
List<String> list = new ArrayList<>();
list.add(id);
list.add("123");
list.add("123");
return list;
}
此⽅法的Redis缓存key值会按照fuck:: + myKeyGenerator组件中声明的返回值来⽣成。
condition属性是⽤来指定判断条件从⽽确定是否⽣成缓存,例如
@Cacheable(value = "fuck",key = "#id",condition="#id%2 == 0")
public List<String> getPrud(@RequestParam("test") int id){
System.out.println("如果第⼆次没有⾛到这⾥说明缓存被添加了");
List<String> list = new ArrayList<>();
list.add(String.valueOf(id));
list.add("123");
list.add("123");
return list;
}
在此例⼦中,如果id%2 == 0判断条件成⽴的话,将会⽣成redis缓存,即返回true时⽣成Redis缓存,如果EL表达式返回false的话则不⽣成缓存。
注意:使⽤@Cacheable⽣成的缓存是不会清除的,同时当redis中已经存在相同的key时,@Cacheable默认不⽣成缓存,即
@Cacheable(value = "fuck")
public List<String> getPrud(@RequestParam("test") String id){
System.out.println("如果第⼆次没有⾛到这⾥说明缓存被添加了");
List<String> list = new ArrayList<>();
list.add(id);
list.add("123");
list.add("123");
return list;
}
在这段代码中只会⽣成⼀个缓存,就是第⼀次运⾏程序时⽣成的fuck::,在第⼆次运⾏程序时将不会⽣成缓存因为Redis中已经⽣成了该缓存fuck::,程序检查Redis服务器的key,发现已存在key则不⽣成缓存,同理在@cacheable中加⼊Key参数也是同样的判断逻辑。
2.@CachePut
对于使⽤@Cacheable标注的⽅法,Spring在每次执⾏前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执⾏该⽅法,⽽是直接从缓存中获取结果进⾏返回,否则才会执⾏并将返回结果存⼊指定的缓存中。@CachePut也可以声明⼀个⽅法⽀持缓存功能。与
@Cacheable不同的是使⽤@CachePut标注的⽅法在执⾏前不会去检查缓存中是否存在之前执⾏过的结果,⽽是每次都会执⾏该⽅法,并将执⾏结果以键值对的形式存⼊指定的缓存中。
3.@CacheEvict
@CacheEvict是⽤来标注在需要清除缓存元素的⽅法或类上的。当标记在⼀个类上时表⽰其中所有的⽅法的执⾏都会触发缓存的清除操作。@CacheEvict可以指定的属性有value、key、condition、allEntries和beforeInvocation。其中value、key和condition的语义与
@Cacheable对应的属性类似。即value表⽰清除操作是发⽣在哪些Cache上的(对应Cache的名称);key表⽰需要清除的是哪个key,如未指定则会使⽤默认策略⽣成的key;condition表⽰清除操作发⽣的条件。下⾯我们来介绍⼀下新出现的两个属性allEntries和beforeInvocation。
此注解的使⽤⽅法与@Cacheable基本⼀致,也有三个基本属性,value、key和condition。不同的是在此注解中筛选出来的key值将被清除掉,例如:
@CacheEvict(value = "fuck",key = "1")
public String test1(){
return "fuck";
}
执⾏这个⽅法的时候我的redis库中存在三个缓存分别如下所⽰,
执⾏完毕之后,结果为,
同时@CacheEvict也有⾃⼰的独有的属性操作,
3.1 allEntries属性
allEntries是boolean类型,表⽰是否需要清除缓存中的所有元素。默认为false,表⽰不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。有的时候我们需要Cache⼀下清除所有的元素,这⽐⼀个⼀个清除元素更有效率。
@CacheEvict(value="users", allEntries=true)
public void delete(Integer id) {
System.out.println("delete user by id: " + id);
}
3.2  beforeInvocation属性
清除操作默认是在对应⽅法成功执⾏之后触发的,即⽅法如果因为抛出异常⽽未能成功返回时也不会触发清除操作。使⽤beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调⽤该⽅法之前清除缓存中的指定元素。
@CacheEvict(value="users", beforeInvocation=true)
public void delete(Integer id) {
System.out.println("delete user by id: " + id);
}
4.Caching
@Caching注解可以让我们在⼀个⽅法或者类上同时指定多个Spring Cache相关的注解。其拥有三个属性:cacheable、put和evict,分别⽤于指定@Cacheable、@CachePut和@CacheEvict。
@Caching(cacheable = @Cacheable("users"), evict = { @CacheEvict("cache2"),
@CacheEvict(value = "cache3", allEntries = true) })
public User find(Integer id) {
returnnull;
}
5.使⽤⾃定义注解
Spring允许我们在配置可缓存的⽅法时使⽤⾃定义的注解,前提是⾃定义的注解上必须使⽤对应的注解进⾏标注。如我们有如下这么⼀个使⽤@Cacheable进⾏标注的⾃定义注解。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Cacheable(value="users")
public @interface MyCacheable {
}
那么在我们需要缓存的⽅法上使⽤@MyCacheable进⾏标注也可以达到同样的效果。
@MyCacheable
public User findById(Integer id) {
System.out.println("find user by id: " + id);
User user = new User();
user.setId(id);
user.setName("Name" + id);
return user;
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。