自学内容网 自学内容网

Spring缓存注解@Cacheable,@CacheEvict,@CachePut使用

示例方法一:使用java的jvm缓存

要在启动类加上@EnableCaching注解

@SpringBootApplication
@EnableCaching
public class ContractorApplication {
    
    public static void main(String[] args) throws UnknownHostException {
        SpringApplication.run(ContractorApplication.class, args);
}

在需要使用缓存的地方加上@Cacheable

   @Cacheable(value="user", key="#id")
   public User find(Integer id) {
      return null;
   }

可以在yml配置缓存的日志为trace查看是否生效

logging:
  level:
    org:
      springframework:
        cache: trace

示例方法二:使用java与redis整合缓存

package com.hdx.contractor.util;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;

/**
 * @Description: 承包商管理
 * @Author: xu
 * @Date: 2024-10-14
 * @Version: V1.0
 */
@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

        return RedisCacheManager.builder(redisConnectionFactory)
                .cacheDefaults(config)
                .build();
    }
}

在需要使用缓存的地方加上@Cacheable

   @Cacheable(value="user", key="#id")
   public User find(Integer id) {
      return null;
   }

可以在yml配置缓存的日志为trace查看是否生效

logging:
  level:
    org:
      springframework:
        data:
          redis: debug
        cache: trace

使用@Cacheable标记的方法在执行后Spring Cache将缓存其返回结果

@Cacheable可以标记在一个方法上,也可以标记在一个类上。

  • 当标记在一个方法上时表示该方法是支持缓存的

  • 当标记在一个类上时则表示该类所有的方法都是支持缓存的

value属性指定Cache名称

value属性是必须指定的,其表示当前方法的返回值是会被缓存在哪个Cache上的,对应Cache的名称。其可以是一个Cache也可以是多个Cache,当需要指定多个Cache时其是一个数组

/**Cache是发生在cache1上的,默认的key就是方法的参数*/
@Cacheable("cache1")
  public User find(Integer id) {
     return null;
   }

/**Cache是发生在cache1和cache2上的,默认的key就是方法的参数*/
@Cacheable({"cache1", "cache2"})
public User find(Integer id) {
   return null;

}

使用key属性自定义key

value自定义策略是指我们可以通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用方法参数及它们对应的属性。使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。下面是几个使用参数作为key的示例

   @Cacheable(value="user", key="#id")
   public User find(Integer id) {
      return null;
   }

   @Cacheable(value="user", key="#p0")
   public User find(Integer id) {
      return null;
   }

   @Cacheable(value="user", key="#user.id")
   public User find(User user) {
      return null;
   }

   @Cacheable(value="user", key="#p0.id")
   public User find(User user) {
      return null;

   }

需要注意的是当一个支持缓存的方法在对象内部被调用时是不会触发缓存功能的(所以生效一般是对于接口的重写),如下

/**
 * 通过查询指定code 获取字典
 * @param code
 * @return
 */
@Override
@Cacheable(value = "sys:cache:dict",key = "#code", unless = "#result == null ")
public List<DictModel> queryDictItemsByCode(String code) {
log.debug("无缓存dictCache的时候调用这里!");
return sysDictMapper.queryDictItemsByCode(code);
}
  • unless = "#result == null "标识,当返回结果为null不缓存,不为空才缓存

  • value = “sys:cache:dict” 有:号在redis中是以文件夹分割

  • key = “#code” 这个可以是动态变量的请求参数

@CachePut与@Cacheable比较

  • @Cacheable标注的方法,Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。

  • @CachePut也可以声明一个方法支持缓存功能。与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存

@CacheEvict是用来标注在需要清除缓存元素的方法或类上的

使用@CacheEvict标记的方法会在方法执行前或者执行后移除Spring Cache中的某些元素

allEntries属性

allEntries是boolean类型,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。有的时候我们需要Cache一下清除所有的元素,这比一个一个清除元素更有效率

   @CacheEvict(value="user", allEntries=true)
   public void delete(Integer id) {
      System.out.println("删除用户id: " + id);
   }

beforeInvocation属性

清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素

   @CacheEvict(value="user", beforeInvocation=true)
   public void delete(Integer id) {
      System.out.println("删除用户id: " + id);
   }


原文地址:https://blog.csdn.net/qq_19891197/article/details/142906343

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!