《Spring实战》-第十三章:缓存数据(1)-Spring对缓存的支持

29 篇文章 0 订阅

慢来比较快,虚心学技术

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

Ⅰ、开启缓存支持

  • 注解开启:@EnableCaching
  • 配置开启: <cache:annotation-driven>

两种开启方法的工作方式是相同的。它们都会创建一个切面( aspect )并触发Spring 缓存注解的切点( pointcut )。根据所使用的注解以及缓存的状态,这个切面会从缓存中获取数据,将数据添加到缓存之中或者从缓存中移除某个值。

import org.springframework.cache.annotation.EnableCaching;
@Configuration
@EnableCaching
public class CacheConfig {
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
     <!--启用缓存注解功能,这个是必须的,否则注解不会生效-->
     <!--有一个cache-manager属性用来指定当前所使用的CacheManager对应的bean的名称,默认是cacheManager-->
     <cache:annotation-driven/>
</beans>

Ⅱ、配置缓存管理器

缓存管理器:是 Spring 缓存抽象的核心,它能够与多个流行的缓存实现进行集成

Spring内置了多个缓存管理器:

  • SimpleCacheManager
  • NoOpCacheManager
  • ConcurrentMapCacheManager----------默认使用的缓存管理器
  • CompositeCacheManager
  • EhCacheCacheManager-------------------较常用
  • RedisCacheManager (来自于 Spring Data Redis 项目)-----------------较常用
  • GemfireCacheManager (来自于 Spring Data GemFire 项目)

1、配置ConcurrentMapCacheManager

①注解配置

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableCaching
public class ConcurrentMapCacheConfig {
    @Bean
    public CacheManager cacheManager1(){
        return new ConcurrentMapCacheManager();
    }
}

②XML配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
    <cache:annotation-driven/>
    <!--定义缓存管理器-->
    <bean id="cacheManager" class="org.springframework.cache.concurrent.ConcurrentMapCacheManager">
    </bean>
</beans>

2、配置EhCacheCacheManager

EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider

缓存数据有三级:内存、堆外缓存Off-Heap、Disk缓存,因此无需担心容量问题。还可以通过RMI、可插入API等方式进行分布式缓存。

缓存数据会在虚拟机重启的过程中写入磁盘,持久化。

具有缓存和缓存管理器的侦听接口。

支持多缓存管理器实例,以及一个实例的多个缓存区域。

由于Spring只是提供了基本的管理器接口,还需要依赖于ehcache的第三方cache实现管理

引入依赖:

<!-- 引入Spring对cache的支持 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>${org.springframework.version}</version>
    <scope>compile</scope>
</dependency>

<!-- 引入ecache支持 -->
<!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache -->
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>2.10.3</version>
</dependency>

①注解配置,此处使用的CacheManager是ehcache的缓存管理器

import net.sf.ehcache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

@Configuration
@EnableCaching
public class EhCacheConfig {
    /**
     * 定义缓存管理器,EhCacheCacheManager是Spring提供的管理器支持,需要将ecache的缓存管理器注入到EhCacheCacheManager中
     **/
    @Bean
    public EhCacheCacheManager cacheManager2(CacheManager cm){
        return new EhCacheCacheManager(cm);
    }

    /**
     * 定义缓存管理器工厂,用于生产EhCacheManager
     **/
    @Bean
    public EhCacheManagerFactoryBean ehCacheManagerFactoryBean(){
        EhCacheManagerFactoryBean factoryBean = new EhCacheManagerFactoryBean();
        factoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
        return factoryBean;
    }
}

②XML配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
    <cache:annotation-driven/>

    <!--定义缓存管理器-->
    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
        <property name="cacheManager" ref="ehcache"></property>
   </bean>
    
    <!--定义缓存管理器工厂-->
    <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="classpath*:ehcache.xml"></property>
    </bean>
</beans>

其中,ehcache.xml配置文件简单配置如下:

<ehcache>
    <diskStore path="java.io.tmpdir"/>
    <!--
        maxElementsOnDisk:磁盘缓存中最多可以存放的元素数量,0表示无穷大  
        maxElementsInMemory:内存缓存中最多可以存放的元素数量,若放入Cache中的元素超过这个数值,则有以下两种情况  
                             1)若overflowToDisk=true,则会将Cache中多出的元素放入磁盘文件中  
                             2)若overflowToDisk=false,则根据memoryStoreEvictionPolicy策略替换Cache中原有的元素  
         eternal:缓存中对象是否永久有效,即是否永驻内存,true时将忽略timeToIdleSeconds和timeToLiveSeconds
         timeToIdleSeconds:缓存数据在失效前的允许闲置时间(单位:秒),仅当eternal=false时使用,默认值是0表示可闲置时间无穷大,此为可选属性  
                             即访问这个cache中元素的最大间隔时间,若超过这个时间没有访问此Cache中的某个元素,那么此元素将被从Cache中清除  
        timeToLiveSeconds:缓存数据在失效前的允许存活时间(单位:秒),仅当eternal=false时使用,默认值是0表示可存活时间无穷大  
                             即Cache中的某元素从创建到清楚的生存时间,也就是说从创建开始计时,当超过这个时间时,此元素将从Cache中清除
        overflowToDisk:内存不足时,是否启用磁盘缓存(即内存中对象数量达到maxElementsInMemory时,Ehcache会将对象写到磁盘中)  
                             会根据标签中path值查找对应的属性值,写入磁盘的文件会放在path文件夹下,文件的名称是cache的名称,后缀名是data  
        diskPersistent:是否持久化磁盘缓存,当这个属性的值为true时,系统在初始化时会在磁盘中查找文件名为cache名称,后缀名为index的文件  
                             这个文件中存放了已经持久化在磁盘中的cache的index,找到后会把cache加载到内存  
                             要想把cache真正持久化到磁盘,写程序时注意执行net.sf.ehcache.Cache.put(Element element)后要调用flush()方法
    -->
    <defaultCache
            maxElementsInMemory="1000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="false"/>
    <!--定义一个缓存-->
    <cache name="ehCache"
           maxElementsOnDisk="20000"
           maxElementsInMemory="2000"
           eternal="false"
           overflowToDisk="true"
           diskPersistent="true"/>
    
</ehcache>

3、配置RedisCacheManager

Redis 可以用来为 Spring 缓存抽象机制存储缓存条目, Spring Data Redis 提供了 RedisCacheManager ,这是 CacheManager 的一个实现。

RedisCacheManager 会与一个 Redis 服务器协作,并通过 RedisTemplate 将缓存条目存储到 Redis 中

上一节已经了解过Redis,此处我们需要先引入Redis支持:

<!--引入Spring Data Redis-->
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <version>2.1.5.RELEASE</version>
</dependency>

<!--引入jedis支持-->
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.1</version>
</dependency>

①混合配置

application-redis.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:cache="http://www.springframework.org/schema/cache"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <cache:annotation-driven cache-manager="redisCacheManager"/>
</beans>

RedisConfig.java

@Configuration
@ComponentScan(basePackages = {"com.my.spring.dao"})
@ImportResource("classpath:application-redis.xml")//引入配置文件
@EnableCaching
public class RedisCacheConfig {

    /**
     * 定义缓存管理器,注入redisConnectionFactory
     * @param redisConnectionFactory
     * @return
     */
    @Bean("redisCacheManager")
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory){
        RedisCacheManager.RedisCacheManagerBuilder builder = 
                    RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(redisConnectionFactory);
        Set<String> cacheNames = new HashSet<String>() {{
            add("myCache");
        }};
        //设置多个缓存
        builder.initialCacheNames(cacheNames);
        return builder.build();
    }

    /**
     * 定义Redis连接工厂
     * @return
     */
    @Bean
    public JedisConnectionFactory redisConnectionFactory(){
        JedisConnectionFactory factory = new JedisConnectionFactory();
        factory.afterPropertiesSet();
        return factory;
    }
}

四、混合使用多种缓存CompositeCacheManager

我们并不是只能有且仅有一个缓存管理器。如果你很难确定该使用哪个缓存管理器,或者有合法的技术理由使用超过一个缓存管理器的话,那么可以尝试使用 Spring 的 CompositeCacheManager.CompositeCacheManager 要通过一个或更多的缓存管理器来进行配置,它会迭代这些缓存管理器,以查找之前所缓存的值

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值