你的浏览器不支持canvas

做你害怕做的事情,然后你会发现,不过如此。

Spring缓存注解@Cacheable、@CacheEvict、@CachePut

时间: 作者: 黄运鑫

本文章属原创文章,未经作者许可,禁止转载,复制,下载,以及用作商业用途。原作者保留所有解释权。


@Cacheable

  • @Cacheable可以作为方法注解,也可以作为类注解。作为类注解则当前类的所有方法都支持该注解。
  • 当注解的方法被访问时,如果缓存中有值,则直接返回缓存结果,不执行方法中的代码。
  • @Cacheable的参数:

    参数 作用 例子
    value 缓存的空间名称,必须指定。
    也可以用cacheNames
    @Cacheable(value=”unreadNum”)
    @Cacheable(cacheNames=”unreadNum”)
    以上两种写法相同。
    key 缓存的key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合。
    同一个空间名称value下的key唯一。
    @Cacheable(value=”testcache”,key=”‘user_’+#userId”)
    @Cacheable(value=”testcache”,key=”‘user_’+#root.args[0]”)
    以上两种写法key相同。
    condition 缓存的条件,默认为true,使用 SpEL 编写,返回true或者false,只有为true才进行缓存。
    true时:如果缓存有值,则不执行方法;如果缓存没值,则执行方法并将结果保存到缓存。
    false时:不执行缓存,每次都执行方法。
    @Cacheable(cacheNames = “unreadNum”, key = “‘user_’+#userId”, condition = “#userId > 100”)
  • 实例如下:

      /**
       * 表示当userId大于100时开启缓存,缓存空间名为unreadNum,缓存的key为'user_'+#userId
       */
      @Cacheable(cacheNames = "unreadNum", key = "'user_'+#userId", condition = "#userId > 100")
      public Integer userUnreadNum(Long userId) {
          Integer integer = interactiveRepository.userUnreadNum(userId);
          return integer == null ? 0 : integer;
      }
    

@CachePut

  • @CachePut@Cacheable的区别:
    • @CachePut是方法注解。
    • @CachePut不影响方法中代码的执行,每次都会执行代码并且将执行结果保存到缓存。
  • @CachePut的参数:

    参数 作用 例子
    value @Cacheable @Cacheable
    key @Cacheable @Cacheable
    condition @Cacheable区别是,无论是true还是false都会执行方法。 @Cacheable
  • 实例如下:

      /**
       * 表示当userId大于100时开启缓存,缓存空间名为unreadNum,缓存的key为'user_'+#userId
       */
      @CachePut(cacheNames = "unreadNum", key = "'user_'+#userId", condition = "#userId > 100")
      public Integer updateUserUnreadCache(Long userId) {
          Integer integer = interactiveRepository.userUnreadNum(userId);
          return integer == null ? 0 : integer;
      }
    

@CacheEvict

  • @CacheEvict是方法注解,主要作用是删除缓存数据。
  • @CacheEvict的参数:

    参数 作用 例子
    value @Cacheable @Cacheable
    key @Cacheable @Cacheable
    condition 缓存的条件,可以为空,使用 SpEL 编写,返回true或者false,只有为 true 才进行缓存。 @Cacheable
    allEntries 是否清空所有缓存内容,默认为 false。
    如果为 true,则方法调用后将清空指定value空间下的所有缓存。
    @CachEvict(value=”unreadNum”,allEntries=true)
    beforeInvocation 是否在方法执行前就清空,默认为false
    如果为true,则在方法执行前就清空缓存。
    false时,如果方法执行抛出异常,则不会清空缓存。
    @CachEvict(value=”unreadNum”,beforeInvocation=true)
  • 实例如下:

      /**
       * 表示删除unreadNum空间中key为'user_'+#userId的缓存
       */
      @CacheEvict(cacheNames = "unreadNum", key = "'user_'+#userId", allEntries = false, beforeInvocation = true)
      public Integer userUnreadNum(Long userId) {
          Integer integer = interactiveRepository.userUnreadNum(userId);
          return integer == null ? 0 : integer;
      }
    

注意

  • 在同一个类中使用this调用其他方法,则不执行缓存。
  • 实例如下:

      @Service
      public class InteractiveService implements ApplicationContextAware {
        
          @Autowired
          @BaseComponent
          private InteractiveRepository interactiveRepository;
        
          private ApplicationContext appContext;
        
          @Override
          public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
              appContext = applicationContext;
          }
        
          /**
           * 用户未读统计(更新redis)
           */
          @CachePut(cacheNames = "unreadNum", key = "'user_'+#userId")
          public Integer updateUserUnreadCache(Long userId) {
              Integer integer = interactiveRepository.userUnreadNum(userId);
              return integer == null ? 0 : integer;
          }
          /**
           * 更新用户未读
           */
          public void updateUserUnread(Long userId){
              //业务代码略...
              //不会更新redis
              this.updateUserUnreadCache(userId);
              //会更新redis
              InteractiveService interactiveService = appContext.getBean(InteractiveService.class);
              interactiveService.updateUserUnreadCache(userId);
          }
      }
    

对于本文内容有问题或建议的小伙伴,欢迎在文章底部留言交流讨论。