首页 > 编程语言 >【Java】Spring Cache 缓存

【Java】Spring Cache 缓存

时间:2022-12-14 18:11:31浏览次数:49  
标签:缓存 Java String Spring Cache user key public

Spring Cache


一、Spring缓存抽象

Spring从3.1开始定义了 org.springframework.cache.Cacheorg.springframework.cache.CacheManager 接口来统一不同的缓存技术; 并支持使用 JCache(JSR-107) 注解简化我们开发。

常用的缓存实现有 RedisCacheEhCacheCacheConcurrentMapCache 等。

JCache (JSR107)

Java Caching定义了5个核心接口,分别是 CachingProvider, CacheManager, Cache, Entry 和 Expiry。

  • CachingProvider:定义了创建、配置、获取、管理和控制多个CacheManager。一个应用可以在运行期访问多个CachingProvider。
  • CacheManager:定义了创建、配置、获取、管理和控制多个唯一命名的Cache,这些Cache存在于CacheManager的上下文中。一个CacheManager仅被一个CachingProvider所拥有。
  • Cache:是一个类似Map的数据结构并临时存储以Key为索引的值。一个Cache仅被一个CacheManager所拥有。
  • Entry:是一个存储在Cache中的key-value对。
  • Expiry:每一个存储在Cache中的条目有一个定义的有效期,即 Expiry Duration。一旦超过这个时间,条目为过期的状态。一旦过期,条目将不可访问、更新和删除。缓存有效期可以通过ExpiryPolicy设置。

二、Spring Cache 注解

@EnableCaching

启用基于 Spring 注解的缓存功能。

   @Configuration
   @EnableCaching
   public class AppConfig {
       @Bean
       public CacheManager cacheManager() {
           // 配置并返回Spring的CacheManager SPI的实现
           SimpleCacheManager cacheManager = new SimpleCacheManager();
           cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("default")));
           return cacheManager;
       }
   }

@CacheConfig

主要用于统一配置该类中会用到的一些共用的缓存配置。

在类级别声明 @CacheConfig 后,就可以不用每个 @Cacheable 都设置 value 属性,省事多了。当然,如果在方法上写了别的值,那依然以方法上的值为准。

  • 参数:
参数名 类型 描述
cacheNames String[] 在类级别定义缓存操作要使用的默认缓存的名称。如果在操作级别未设置任何值,则使用这些值而不是默认值。
keyGenerator String 用于指定key生成器,非必需。可以指定一个自定义的key生成器,需要实现 org.springframework.cache.interceptor.KeyGenerator 接口,并使用该参数来指定。该参数与key是互斥的
cacheManager String 用于指定使用哪个缓存管理器,非必需。只有当有多个时才需要使用。
cacheResolver String 用于指定使用那个缓存解析器,非必需。需通过 org.springframework.cache.interceptor.CacheResolver 接口来实现自己的缓存解析器,并用该参数指定。

@Service
@CacheConfig(cacheNames = {"taskLog"})
public class TaskLogService {

    @CachePut(key = "#tasklog.id")
    public boolean create(Tasklog tasklog){
        ...
        return true;
    }
 
    @Cacheable(key = "#id")
    public Tasklog findById(String id){
        ...
        return taskLogMapper.selectById(id);
    }
}

@Cacheable

主要方法返回值加入缓存。同时在查询时,会先从缓存中取,若不存在才再发起对数据库的访问。

  • 主要参数:
参数名 类型 描述
value String[] cacheNames 的别名
cacheNames String[] 指定缓存的名称,用于确定目标缓存(或多个缓存),匹配特定bean定义的限定符值或bean名称。如果没有在 @CacheConfig 中指定,则必须要这里指定至少一个。
key String 缓存的 key,为空则按照指定的 key 生成器生成,或使用缺省的方法生成(所有参数进行组合)。如果指定,要按照 SpEL 表达式编写。
condition String 是否使用缓存的条件 SpEL 表达式,返回 true 才进行缓存(在方法执行之前进行评估)。可以为空,表示方法结果始终缓存。
unless String 用来决定是否更新缓存的 SpEL 表达式,如果返回 false 才放入缓存。与 condition 不同,此表达式是在调用方法之后计算的,因此可以引用结果。默认值为空,表示缓存永远不会被否决。
sync boolean 缓存的同步。在多线程环境下,某些操作可能使用相同参数同步调用。默认情况下,缓存不锁定任何资源,可能导致多次计算,而违反了缓存的目的。对于这些特定的情况,属性 sync 可以指示底层将缓存锁住,使只有一个线程可以进入计算,而其他线程堵塞,直到返回结果更新到缓存中。

其它参数参考 @CacheConfig

  • 示例:
@Cacheable(cacheNames={"book"}, key="#name", condition="#name.length < 32")
public Book findBook(String name) { ... }

@CachePut

配置于函数上,能够根据参数定义条件进行缓存,与@Cacheable不同的是,每次回真实调用函数,所以主要用于数据新增和修改操作上

@CacheEvict

配置于函数上,通常用在删除方法上,用来从缓存中移除对应数据。

  • 主要参数:
参数名 类型 描述
value String[] cacheNames 的别名
cacheNames String[] @Cacheable
key String @Cacheable
condition String @Cacheable
allEntries boolean 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存。请注意,不允许将此参数设置为 true 并指定 key
beforeInvocation boolean 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存。
  • 示例:
@CacheEvict(cacheNames="books", allEntries=true)
public void loadBooks(InputStream batch) { ... }

@Caching

配置于函数上,组合多个Cache注解使用。

比如用户新增成功后,我们要添加id–>user;username—>user;email—>user的缓存;此时就需要@Caching组合多个注解标签了。


@Caching(put = {
    @CachePut(value = "user", key = "#user.id"),
    @CachePut(value = "user", key = "#user.username"),
    @CachePut(value = "user", key = "#user.email")
})
public User save(User user) { ... }

自定义缓存注解

比如上面的那个@Caching组合,会让方法上的注解显得整个代码比较乱,此时可以使用自定义注解把这些注解组合到一个注解中,如:

@Caching(put = {
    @CachePut(value = "user", key = "#user.id"),
    @CachePut(value = "user", key = "#user.username"),
    @CachePut(value = "user", key = "#user.email")
})
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface UserSaveCache {
}

这样我们在方法上使用如下代码即可,整个代码显得比较干净。

@UserSaveCache
public User save(User user) { ... }

SpEL 表达式介绍

自定义 Key 生成器

@Configuration
public class MyCacheConfig {

    @Bean("myKeyGenerator")
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {

            @Override
            public Object generate(Object target, Method method, Object... params) {
                return method.getName() + "[" + Arrays.asList(params).toString() + "]";
            }
        };
    }
}

二、Java 常用 Redis 库

  • Spring Data Redis 可能是将Redis集成到您的Spring应用程序中最简单,最快的方法,它为Redis提供了Spring Data平台的抽象。

  • Jedis 称自己为“一个极小而理智的Redis Java客户端” ,其构想是考虑了简单性和易用性

  • Reddison是Redis Java客户端,具有内存数据网格功能以及30多种可用的对象和服务 。 该库基于高性能的异步和无锁Java Redis客户端和Netty框架,在Codota的用户群中仅拥有8%的用户。优点是提供了很多redis的分布式操作和高级功能,缺点是api抽象,学习成本高。

  • Lettuce是一个完全无阻塞的Redis客户端,也是使用Netty框架构建的,它提供了反应式,异步和同步数据访问 。 根据我们的统计,这是5%开发人员的选择。优点是提供了很多redis高级功能,例如集群、哨兵、管道等,缺点是api抽象,学习成本高。

  • Jedis是Redis官方推荐的面向Java的操作Redis的客户端,而RedisTemplate,在SpringBoot1.x时是SpringDataRedis中对JedisApi的高度封装,而到了SpringBoot2.x,具体实现变成了 Lettuce

结论

跟 SpringBoot 走,用 Spring Data Redis

标签:缓存,Java,String,Spring,Cache,user,key,public
From: https://www.cnblogs.com/yangyxd/p/16982894.html

相关文章

  • Spring Integration的网络通量支持
    WebFluxSpring集成模块()允许以反应方式执行HTTP请求和处理入站HTTP请求。​​spring-integration-webflux​​您需要将此依赖项包含在项目中:<dependency><groupI......
  • Java: 在Excel中插入和提取图片
    在编辑Excel文档时,为了丰富文档内容或者更好地说明文档内容,有时我们会在单元格中插入图片。此外,整理文档内容时,也可以通过编程的方式将图片从Excel中提取出来。接下来我就将......
  • Java继承构造方法的注意点
    父类:注意(x,y是private,不能继承到子类中)classPar{privateintx;privateinty;inta;publicPar(){}publicPar(intx,inty){t......
  • JAVA中子类继承时构造方法注意事项
    JAVA中子类继承时构造方法注意事项类的继承不容易理解的一种情况:父类只存在有参构造,子类的构造方法必需要做相应的处理,比如说也创建有参构造,为什么?1、任何类,如果无显......
  • JAVA多态(超详细讲解)
    JAVA多态(超详细讲解)坠水于 2021-10-2914:29:56 发布31330收藏144版权声明:本文为博主原创文章,遵循CC4.0BY-SA版权协议,转载请附上原文出处链接和本声明。......
  • Java 继承解决了编程中的什么问题
    Java继承解决了编程中的什么问题?Java继承产生的背景?继承产生的原因:在一个项目中多个类具有很多相同的代码段,代码多了不仅仅容易出错,在需要系统升级的时候各个相同的代......
  • SpringMVC学习
    SpringMVC学习1.回顾MVC1.1什么是MVCMVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。是将业务逻辑、数据、显示分离的方法来组织代码......
  • 狂神说 javaweb
    javaweb1、基本概念web开发:web静态web动态web淘宝,不断变化技术栈:Servlet/JSPASPPHP1.2、web应用程序web应用程序:可以提供浏览器访问的程序能访问的任何页面都存在于世......
  • Java: 在Excel中插入和提取图片
    在编辑Excel文档时,为了丰富文档内容或者更好地说明文档内容,有时我们会在单元格中插入图片。此外,整理文档内容时,也可以通过编程的方式将图片从Excel中提取出来。接下来我就......
  • spring mvc环境之异常错误码的统一返回(十五)
    1.根据不同的请求方式,返回页面或json数据1).创建统一权限异常处理类,所有的权限异常走一个端口2).根据请求方式不同返回不同数据,页面请求返回403未授权页面,ajax请......