spring boot 3.1以后加入了对缓存的支持,通常使用@Cacheable、@CacheEvict、@CachePut等注解,一般作用与方法上,基本实现为当调用一个缓存方法时会把该方法参数和返回结果作为一个键值对存放在缓存中,等到下次利用同样的参数来调用该方法时将不再执行该方法,而是直接从缓存中获取结果进行返回。
@Cacheable
进行了@Cacheable的方法,Spring会在其被调用后将其返回值缓存起来,以保证下次利用同样的参数来执行该方法时可以直接从缓存中获取结果,而不需要再次执行该方法。
Spring在缓存方法的返回值时是以键值对进行缓存的,值就是方法的返回结果。需要注意的是当一个缓存方法在对象内部被调用时是不会触发缓存功能的。
@Cacheable的三个属性,value、key和condition。
@Cacheable可以标记在方法上,也可以标记在类上。当标记在一个方法上时表示该方法是支持缓存的,当标记在一个类上时则表示该类所有的方法都是支持缓存的。
@Cacheable value属性是必须指定的,其表示当前方法的返回值是会被缓存在哪个Cache上的,对应Cache的名称。其可以是一个Cache也可以是多个Cache,当需要指定多个Cache时其是一个数组。
@Cacheable("cache")//Cache是发生在cache上的
public Test find(Integer id) {
return null;
}
@Cacheable({"cache1", "cache2"})//Cache是发生在cache1和cache2上的
public Test find(Integer id) {
return null;
}
key属性是用来指定Spring缓存方法的返回结果时对应的key的。该属性支持SpringEL表达式。当没有指定该属性时,Spring将使用默认策略生成key。
自定义策略:
/*** key 是指传入时的参数**/
@Cacheable(value="test", key="#id")
public Test find(Integer id) {
return null;
}
// 表示第一个参数
@Cacheable(value="test", key="#p0")
public Test find(Integer id) {
return null;
}
// 表示Test 中的id值
@Cacheable(value="test", key="#test.id")
public Test find(Test test) {
return null;
}
// 表示第一个参数里的id属性值
@Cacheable(value="test", key="#p0.id")
public Test find(Test test) {
return null;
}
自定义策略可以通过Spring的EL表达式来指定key。这里的EL表达式可以使用方法参数及它们对应的属性。使用方法参数时可以直接使用“#参数名”或者“#p参数index”。
Spring还为我们提供了一个root对象可以用来生成key。
使用root对象的属性作为key
// key值为: Test 中的name属性的值
@Cacheable(value={"Test ", "xxx"}, key="caches[1].name")
public Test find(Test test) {
return null;
}
我们可以通过condition属性进行是否进行缓存设定,通过SpringEL表达式来指定的,当为true时表示进行缓存处理;当为false时表示不进行缓存处理,该方法每次调用都会执行一次。
// 根据条件判断是否缓存
@Cacheable(value={"test"}, key="#test.id", condition="#test.id%2==0")
public Test find(Test test) {
System.out.println("find test by test" + test);
return test;
}
@CachePut
@CachePut 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用
//@CachePut和@Cacheable使用是一样的。
@CachePut("test") //每次都会执行方法,并将结果存入指定的缓存中
public Test find(Integer id) {
return null;
}
@CacheEvict
@CacheEvict是用来标注在需要清除缓存元素的方法或类上的。当标记在一个类上时表示其中所有的方法的执行都会触发缓存的清除操作。@CacheEvict可以指定的属性有value、key、condition、allEntries和beforeInvocation。其中value、key和condition的语义与@Cacheable对应的属性类似。即value表示清除操作是发生在哪些Cache上的(对应Cache的名称);key表示需要清除的是哪个key,如未指定则会使用默认策略生成的key;condition表示清除操作发生的条件。
allEntries是boolean类型,用来删除所有缓存,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。
@CacheEvict(value="test", allEntries=true)
public void delete(Integer id) {
System.out.println("delete test by id: " + id);
}
清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。
@CacheEvict(value="test", beforeInvocation=true)
public void delete(Integer id) {
System.out.println("delete test by id: " + id);
}
@Caching
@Caching注解可以在一个方法或者类上同时指定多个Spring Cache相关的注解。其拥有三个属性:cacheable、put和evict,分别用于指定@Cacheable、@CachePut和@CacheEvict。
@Caching(cacheable = @Cacheable("test1"), put = @CachePut("test2") ,evict = { @CacheEvict("test3"), @CacheEvict(value = "test4", allEntries = true) })
public Test find(Integer id) {
return null;
}