天天看点

Spring Boot 整合——Spring Cache的整合和注解介绍

本篇文章涉及的源码下载地址:https://gitee.com/daifyutils/springboot-samples

下一篇:Spring Cache使用Redis缓存、自定义注解参数值

抽象缓存

Spring Cache是Spring提供的一套缓存的抽象实现,通过配置Cache的数据源可以轻松的将缓存的存放地址进行修改。

引入依赖

Spring默认提供了对Spring Cache的支持,所以如果使用的是spring-boot-starter-parent则无需引入

参数配置

启动注释

要开启Spring Cache需要在启动类中添加注释

@EnableCaching

@SpringBootApplication
@EnableCaching
public class CacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(CacheApplication.class,args);
    }
}
           

创建缓存配置

除了启动类中添加注释,假如需要使用其他数据库作为缓存数据源需要实现CacheManager接口,但是对于测试时使用内存作为缓存管理器,则默认已经会实现,所以不需要实现任何接口

使用cache进行数据操作

/**
 * @author daify
 * @date 2020-10-13
 */
@Repository
public class CacheDao {

    /**
     * 获取数据
     * @param key
     * @return
     */
    @Cacheable(value = "string" ,key = "#key")
    public String find(String key) {
        return "";
    }

    /**
     * 设置数据
     * @param data
     * @param key
     * @return
     */
    @CachePut(value = "string" ,key = "#key")
    public String putStr(String data,String key) {
        return "";
    }

    /**
     * 清空缓存
     * @param key
     */
    @CacheEvict(value = "string" ,key = "#key")
    public void clear(String key) {

    }

}
           

测试用例

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = CacheApplication.class)
@EnableAutoConfiguration
@Slf4j
public class CacheDaoTest extends CacheApplication {

    @Autowired
    private CacheDao cacheDao;

    private static String KEY ="test";


    /**
     * 获取数据
     * @return
     */
    @Test
    public void find() {
        cacheDao.clear(KEY);
        String cacheData = cacheDao.find(KEY);
        Assert.assertTrue(StringUtils.isEmpty(cacheData));

        cacheDao.putStr("123",KEY);
        String cacheData2 = cacheDao.find(KEY);
        Assert.assertTrue("123".equals(cacheData2));
        log.info("测试执行完毕");
    }

}
           
输出结果
2020-10-17 12:22:09.059  INFO 28620 --- [           main] dai.samples.cache.dao.CacheDaoTest       : Started CacheDaoTest in 1.865 seconds (JVM running for 2.679)
2020-10-17 12:22:09.175  INFO 28620 --- [           main] dai.samples.cache.dao.CacheDaoTest       : 测试执行完毕
2020-10-17 12:22:09.179  INFO 28620 --- [       Thread-4] o.s.w.c.s.GenericWebApplicationContext   : Closing org.springframework.web.context.support.GenericWebApplicationContext@640f11a1: startup date [Sat Oct 17 12:22:07 CST 2020]; root of context hierarchy
           

使用cache注意事项

cache的原理

其实就是将需要缓存的方法进行代理,在执行具体逻辑之前会通过代理进行一些操作。
  1. 在同一个类中调用被缓存注解的方法会导致缓存失效

Spring cache 本质是动态生成proxy代理来对调用方法进行切面。但是当对象方法使用内部调用而不是外部引用的时候则会导致proxy失效。

  1. 静态方法无法使用cache注解

同样因为静态方法直接通过类名.方法名进行调用,绕过了spring proxy的代理类,无法使用切面拦截。

注释介绍

注解 作用
CacheAnnotationParser 指定缓存定义解析
CacheConfig 用来为当前类的缓存操作指定独特的配置
Cacheable 尝试获取缓存如果缓存不存在则不使用缓存进行查询并缓存返回值
CacheEvict 清空缓存
CachePut 更新缓存
Caching 集合了Cacheable、CacheEvict、CachePut 可是通过配置实现三者效果
CachingConfigurer 指定缓存配置
EnableCaching 开启缓存

CacheAnnotationParser

参数

参数 作用 参考值
parseCacheAnnotations 提供类缓存定义的解析
parseCacheAnnotations 提供方法缓存定义的解析

CacheConfig

此注解是一个类级注释,用来为当前类的缓存操作指定独特的配置

参数

参数 作用 参考值
cacheNames 设置此配置的缓存名称
keyGenerator 键生成器,定义了该方法之后可以根据业务自定义key 此参数为注入的bean名称,对应Bean需要实现org.springframework.cache.interceptor.KeyGenerator
cacheManager 自定义cacheManager 缓存管理器 注入的bean名称,实现org.springframework.cache.CacheManager接口
cacheResolver 自定义的缓存解析器 注入的bean名称,实现org.springframework.cache.interceptor.CacheResolver接口

Cacheable

参数

参数 作用 参考值
value 缓存的名称,至少指定一个
cacheNames 指定缓存名称
key 缓存的key,可以为空也可以使用SpEL表达式,默认按照方法的所有参数进行组合
keyGenerator 键生成器,定义了该方法之后可以根据业务自定义key 此参数为注入的bean名称,对应Bean需要实现org.springframework.cache.interceptor.KeyGenerator
cacheManager 自定义cacheManager 缓存管理器 注入的bean名称,实现org.springframework.cache.CacheManager接口
cacheResolver 自定义的缓存解析器 注入的bean名称,实现org.springframework.cache.interceptor.CacheResolver接口
condition 执行缓存的条件,使用SpEL表达式需要返回true或者false #age>2
unless 使用SpEL表达式,标识无需缓存的条件
sync 设置缓存的操作为同步进行

CacheEvict

参数

参数 作用 参考值
value 缓存的名称,至少指定一个
cacheNames 指定缓存名称
key 缓存的key,可以为空也可以使用SpEL表达式,默认按照方法的所有参数进行组合
keyGenerator 键生成器,定义了该方法之后可以根据业务自定义key 此参数为注入的bean名称,对应Bean需要实现org.springframework.cache.interceptor.KeyGenerator
cacheManager 自定义cacheManager 缓存管理器 注入的bean名称,实现org.springframework.cache.CacheManager接口
cacheResolver 自定义的缓存解析器 注入的bean名称,实现org.springframework.cache.interceptor.CacheResolver接口
condition 执行缓存的条件,使用SpEL表达式需要返回true或者false #age>2
allEntries 是否清空此value缓存下所有key缓存,而不是注解中对应的缓存 false
beforeInvocation 在执行方法之前就清空缓存 false

CachePut

参数

参数 作用 参考值
value 缓存的名称,至少指定一个
cacheNames 指定缓存名称
key 缓存的key,可以为空也可以使用SpEL表达式,默认按照方法的所有参数进行组合
keyGenerator 键生成器,定义了该方法之后可以根据业务自定义key 此参数为注入的bean名称,对应Bean需要实现org.springframework.cache.interceptor.KeyGenerator
cacheManager 自定义cacheManager 缓存管理器 注入的bean名称,实现org.springframework.cache.CacheManager接口
cacheResolver 自定义的缓存解析器 注入的bean名称,实现org.springframework.cache.interceptor.CacheResolver接口
condition 执行缓存的条件,使用SpEL表达式需要返回true或者false #age>2
unless 使用SpEL表达式,标识无需缓存的条件

Caching

此注解为某一方法提供了多个操作

参数

参数 作用 参考值
cacheable 查询缓存(设置)缓存的注解
put 设置缓存的注解
evict 清空缓存的注解
下面操作可以提供id->user 和 name->user的缓存
@Caching(
        put = {
            @CachePut(value = "animalById", key = "#user.id"),
            @CachePut(value = "animalById", key = "#user.name")
        }
    )
    public User saveUser(final User user){
        return user;
    }

           

CachingConfigurer

参数

参数 作用 参考值
cacheManager 自定义cacheManager 缓存管理器 注入的bean名称,实现org.springframework.cache.CacheManager接口
cacheResolver 自定义的缓存解析器 注入的bean名称,实现org.springframework.cache.interceptor.CacheResolver接口
keyGenerator 键生成器,定义了该方法之后可以根据业务自定义key 此参数为注入的bean名称,对应Bean需要实现org.springframework.cache.interceptor.KeyGenerator
errorHandler 异常处理操作 需要实现org.springframework.cache.interceptor.CacheErrorHandler

EnableCaching

参数

参数 作用 参考值
proxyTargetClass 设置代理方式,false为JDK动态代理;true为基于cglib动态代理 默认为false
mode 切面方式,false为JDK动态代理;true为基于aspectj动态代理 默认为false
order 一个切点存在多个操作的时候的执行顺序,默认为最低优先级 数字越大优先级越低

SpEL介绍

描述 语句
被调用方法名 root.method.name
被调用对象 root.target
被调用的类 root.targetClass
方法参数列表 root.args[0]
方法缓存列表 root.caches[0].name
被调用的参数的方法 {参数对象}.{属性字段}
方法执行后的返回值 result

示例

@CachePut(value = "string" ,
            key = "#root.method.name + '---' + #root.target + '---' + " +
                  "#root.targetClass + '---' + #root.args[0] + '---' + #root.caches[0].name")
    public String putStr2(String data,String key) {
        return data;
    }
           

下面内容Key会输出

putStr2---dai.samples.cache.dao.CacheDao@91f565d---class dai.samples.cache.dao.CacheDao---123---string123
           
个人水平有限,上面的内容可能存在没有描述清楚或者错误的地方,假如开发同学发现了,请及时告知,我会第一时间修改相关内容。假如我的这篇内容对你有任何帮助的话,麻烦给我点一个赞。你的点赞就是我前进的动力。