Spring学习笔记之缓存数据

缓存(Caching)可以存储经常会用到的信息,这样每次需要的时候,这些信息都是立即可用的。在本章中,我们将会了解到Spring的缓存抽象。尽管Spring自身并没有实现缓存解决方案,但是它对缓存功能提供了声明式的支持,能够与多种流行的缓存实现进行集成。

1.启用对缓存的支持

Spring对缓存的支持有两种方式:

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

启用注解驱动的缓存:
Java配置:

@Configuration
@EnableCaching //启用缓存
public class CachingConfig {

    //声明缓存管理器
    @Bean
    public CacheManager cacheManager(){
        return new ConcurrentMapCacheManager();
    }
}

XML配置:

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

本质上,@EnableCaching 和<cache:annotation-driven />的工作方式是相同的。他们都会创建一个切面并触发Spring缓存注解的切点。根据所使用的注解以及缓存的状态,这个切面会从缓存中获取数据,将数据添加到缓存之中或者从缓存中移除某一个值。

在上面的代码中,我们不仅启用了缓存,还配置了一个缓存管理器。缓存管理器是Spring缓存抽象的核心,它能够与多个流行的缓存实现进行集成。上面声明的ConcurrentMapCacheManager使用java.util.concurrent.ConcurrentHashMap作为其缓存存储。你猜的不错,它是基于内存的,所以它的声明周期是与应用关联的。对于生产级别的大型企业级应用程序,这可能并不是理想的选择。
下面,让我们看一下几个最为常用的缓存管理器。

1.1配置缓存管理器

Spring 3.1内置了五个缓存管理器的实现,如下所示:

  • SimpleCacheManager
  • NoOpCacheManager
  • ConcurrentMapManager
  • CompositeCacheManager
  • EhCahceCacheManager

除了核心的Spring框架,Spring Data又提供了两个缓存管理器:

  • RedisCacheManager(来自Spring Data Redis项目)
  • GemfireCacheManager(来自于Spring Data GenFire项目)

使用Ehcache缓存:
Java配置:

@Configuration
@EnableCaching //启用缓存
public class CachingConfig {

    //声明缓存管理器
    @Bean
    public EhCacheCacheManager cacheManager(CacheManager cm){
        return new EhCacheCacheManager(cm);
    }

    @Bean
    public EhCacheManagerFactoryBean ehcache(){
        EhCacheManagerFactoryBean ehCacheFactoryBean = new EhCacheManagerFactoryBean();
        ehCacheFactoryBean.setConfigLocation(
                new ClassPathResource("cache/ehcache.xml"));
        ehCacheFactoryBean.setShared(true);
        return ehCacheFactoryBean;
    }
}

ehcache.xml:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
       xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">  

<cache name="testCache"
        maxBytesLocalHeap="50m"
        timeToLiveSeconds="100">
</cache>

</ehcache>  

Spring和Ehcache都定义了CacheManager类型。需要明确的是,EhCache的CacheManager要被注入到Spring的EhCacheCacheManager(Spring CacheManager的实现)之中。除此之外,EhCache为XML定义了自己的配置模式,我们需要在一个XML文件中配置缓存,上面的ehcache.xml就是一个简单的配置:声明了一个名为testCache的缓存,它最大的堆存储为50MB,存活时间为100秒。

使用Redis缓存
后续补上

2.为方法添加注解以支持缓存

表中的所有注解都能运用在方法或类上。当将其放在单个方法上时,注解所描述的缓存行为只会运用到这个方法上。如果注解放在类级别的话,那么缓存行为就会应用到这个类的所有方法上。

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

2.1填充缓存

@Cacheable和@CachePut有一些共有的属性:

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

示例:

@Cacheable("testCache")
    public User findOne(int id){
        System.out.println("findOne方法开始执行");
        return this.sdjr.findOne(id);
    }

    @CachePut(value="testCache",key="#result.id")
    public User save(User user){
        System.out.println("save方法开始执行");
        return this.sdjr.saveAndFlush(user);
    }

key=”result.id”是一个自定义的缓存key,用的是SpEL表达式。
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)

@Cacheable和@CachePut提供了两个属性用以实现条件化缓存:unless和condition,这两个属性都接受一个SpEL表达式。它们之间有一点细微的差别。unless属性只能阻止将对象放进缓存,当它为true的时候,缓存方法返回的数据就不会放到缓存中。但是在这个方法调用的时候,依然会去缓存中进行查找,如果找到匹配的值,就会返回匹配的值。与之不同,如果condition的表达式计算结果为false,那么在这个方法调用的过程中,缓存是被禁用的。就是说,不会去缓存进行查找,同时返回值也不会放进缓存中。

2.2移除缓存条目

@CacheEvict并不会往缓存中添加任何其他东西。相反,如果带有@CacheEvict注解的方法被调用的话,那么会有一个或更多的条目会在缓存中移除。
@CacheEvict注解的属性,指定了哪些缓存条目应该被移除掉

属性类型描述
valueString[]要使用的缓存名称
keyString[]SpEL表达式,用来计算自定义的缓存key
conditionStringSpEL表达式,如果得到的值是false的话,缓存不会应用到方法调用上
allEntriesboolean如果为true的话,特定缓存的所有条目都会被移除掉
beforeInvocationboolean如果为true的话,在方法调用之前移除条目。如果为false(默认值)的话,在方法成功调用之后再移除条目
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值