Spring 中使用缓存技术

本文介绍了Spring中如何启用和配置缓存支持,包括注解驱动的缓存和XML声明的缓存。通过添加@EnableCaching开启注解支持,并配置CacheManager。Spring提供了多种缓存管理器实现,如SimpleCacheManager、RedisCacheManager等。方法上使用@Cacheable、@CachePut、@CacheEvict等注解来声明缓存规则,自定义key和条件化缓存。最后,还探讨了使用XML声明缓存的方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、启用对缓存的支持

Spring 的缓存抽象在很大程度上是围绕切面构建的。
Spring 对缓存的支持有两种方式:

  • 注解驱动的缓存
  • XML 声明的缓存

在方法上添加 @CacheableCacheEvivt 注解来使用缓存。

启用 Spring 对注解驱动缓存的支持,在配置类上添加 @EnableCaching,并声明缓存管理器:

    @Bean
    public CacheManager cacheManager(){
        return  new ConcurrentMapCacheManager();
    }

xml配置:

<cache:annotation-driven />
<bean id="cacheManager" class="org.springframework.cache.concurrent.ConcurrentMapCacheManager" />

启用注解驱动缓存后,会创建一个切面并触发Spring 缓存注解的切点。根据使用的注解及缓存状态,这个切面会从缓存中获取数据,将数据添加到缓存中或者从缓存中移除。
缓存管理器是 Spring 缓存抽象的核心,它能与多个流行的缓存实现进行集成。ConcurrentMapCacheManager 是一个简单的缓存管理器,但它是基于内存的,其生命周期是与应用关联的。

1、配置缓存管理器

Spring 3.1 内置了五个缓存管理器实现:

  • SimpleCacheManager
  • NoOpCacheManager
  • ConcurrentMapCacheManager
  • CompositeCacheManager
  • EhCacheManager

Spring 3.2 又引入了另一个缓存管理器,它可以用于基于 JCache 的缓存提供商中。除了核心的Spring 框架,Spring Data又提供了两个缓存管理器:

  • RedisCacheManger(来自 Spring Data Redis)
  • GemfireCacheManager (Spring Data CemFire)

使用 Redis 缓存
通过传递一个 RedisTemplate 实例到其构造器,构建 RedisCacheManger

@Configuration
@EnableCaching
public class CachingConfig {
    /**
     * @author Cedar
     * @DESCRIPTION: 声明Redis缓存管理器
     * @params: []
     * @return: org.springframework.cache.CacheManager
     * @Date: 2019/2/27 16:08
     */
    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        return new RedisCacheManager(redisTemplate);
    }

    /**
     * @author Cedar
     * @DESCRIPTION: Redis连接工程 bean
     * @params: []
     * @return: org.springframework.data.redis.connection.jedis.JedisConnectionFactory
     * @Date: 2019/2/27 16:37
    */
    @Bean
    public JedisConnectionFactory redisConnectionFactory() {
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
        jedisConnectionFactory.afterPropertiesSet();
        return jedisConnectionFactory;
    }

    /**
     * @author Cedar
     * @DESCRIPTION: RedisTemplate
     * @params: [redisCF]
     * @return: org.springframework.data.redis.core.RedisTemplate<java.lang.String,java.lang.String>
     * @Date: 2019/2/27 16:40
    */
    @Bean
    public RedisTemplate<String,String> redisTemplate (RedisConnectionFactory redisCF){
        RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisCF);
        redisTemplate.afterPropertiesSet();
        return  redisTemplate;
    }
}

使用多个缓存管理器
CompositeCacheManager 要通过一个或更多的缓存管理器来进行配置,它会迭代这些缓存管理器,以查找之前所缓存的值。

	@Bean
    public CacheManager cacheManager(net.sf.ehcache.CacheManager cm, javax.cache.CacheManager jcm){
        CompositeCacheManager cacheManager = new CompositeCacheManager();
        ArrayList<CacheManager> cacheManagers = new ArrayList<>();
        cacheManagers.add(new JCacheCacheManager(jcm));
        cacheManagers.add(new EhCacheCacheManager(cm));
        cacheManagers.add(new RedisCacheManager(redisTemplate()));
        cacheManager.setCacheManagers(cacheManagers);
        return cacheManager;
    }

二、为方法添加注解以支持缓存

在 Spring 中启动缓存时创建一个切面,它触发一个或多个Spring 的缓存注解。Spring 提供了4个注解来声明缓存规则:

注解描述
@Cacheable表明 Spring 在调用方法之前,首先应该在这个缓存中查找方法的返回值。如果这个值能够找到,就会返回缓存的值。否则,调用这个方法,返回值会放到缓存中。
@CachePut表明 Spring 应该将方法的返回值放到缓存中。在方法的调用前不会检查缓存,方法始终被调用。
@CacheEvict表明Spring 应该在缓存中清除一个或多个条目
@Caching这是一个分组的注解,能够同时应用多个其他的缓存注解

这些注解可以用在方法或类上。

1、填充缓存

@Cacheale 和 @CachePut 都可以填充缓存,但也有差异,其共同属性:

属性类型描述
valueString[]要使用的缓存名称
conditionStringSpEl 表达式,如果得到的值是 false,不会将缓存应用到方法调用上
keyStringSpEl 表达式,用来计算自定义的缓存 key
unlessStringSpEl 表达式,值为 true ,返回值不会放到缓存中

当为接口方法添加注解后,注解会被所有实现继承。

将值放到缓存中
缓存默认的 key 基于方法的参数确定,如果方法参数为 userId, 则key为 userId 的值,参数为 user 对象,key 也为 user 对象。但是,缓存的值为 user 对象,key 为 user 对象则不是想要的结果,因此需要指定一个key。

自定义缓存 key
通过设置 key 属性,来自定义 key ,它是通过一个 SpEL 表达式计算得到的。如果想要将一个 user id 作为key,但是在保存这个 user 对象之前,还没有 id ,只能通过 save() 方法返回的 user 对象得到id属性。
在为缓存编写 SpEL 表达式的时候,Spring 暴露了一些很有用的元数据,Spring 提供了多个用来定义缓存规则的SpEL 表达式:

表达式描述
#root.args传递给缓存方法的参数,形式为数组
#root.caches该方法执行时所对应的的缓存,形式为数组
#root.target目标对象
#root.targetClass目标对象的类,是 #root.target.class 的简写
#root.method缓存方法
#root.methodName缓存方法的名字,#root.method.name 的简写
#result方法调用的返回值 (不能用在 @Cacheable 注解上)
#Argument任意的参数方法名(如 #argName)或索引参数(如 #a0 或 #p0)

因此可以自定义注解 key 为 id : @CachePut(value="userCache" key="#result.id")

条件化缓存
unlesscondition 属性用于实现条件化缓存。unless 属性只能阻止将对象放到缓存,但是这个方法调用时,依然会从缓存中查找,找到匹配的值就会返回该值, 如果 condition 的表达式结果是false,在调用方式时,缓存是被禁用的,不会去缓存中查找,也不会将值放进缓存。
例如:

//message为方法返回的对象属性
@Cacheable(value="userCache" unless= "#result.message.contaions('NoCache')")
User findOne(long id);
@Cacheable(value="userCache" unless= "#result.message.contaions('NoCache')" condition="#id >= 10")
User findOne(long id);

移除缓存条目
@CacheEvict 注解的方法被调用,一个或多个缓存的条目在缓存中移除。

@CacheEvivt("userCache")
void remove(long userId);

与 @Cacheable 和 @CachePut 不同,@CacheEvict 能够应用在返回值为 void 的方法上,另两个则需要非 void 的返回值。

缓存中被删除的条目的 key 与传递进来的 userId 的值相等。
@CacheEvict 的属性,没有 unless 属性,也提供了几个新的属性:

属性类型描述
valueString[]
keyString
conditionString
allEntriesboolean如果为 ture ,特定缓存的所有条目都会被移除掉
beforeInvocationboolean如果为 true ,在方法调用前移除条目。 false(默认),在方法调用成功后再移除条目。

三、使用 XML 声明缓存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值