并发(六)之堆缓存(二级缓存):SpringBoot整合ehcache2.x或3.x

  |   0 评论   |   0 浏览

基础配置

  • 测试对象

    @Data
    public class ProductInfoModel implements Serializable
    {
        private int id;
        private String title;
        private String desc;
        private BigDecimal price;
        private String icons;
        private int inventoryId;
    
        // 缓存最后更新的时间
        private Date cacheLastUpdate;
    }
    
  • 测试服务及实现

    // 接口
    public interface ProductInfoCacheService
    {
        ProductInfoModel findById(Integer productId);
    
        ProductInfoModel saveProductInfo(ProductInfoModel productInfo);
    }
    
    // 实现
    import com.lupf.shopproduct.service.model.ProductInfoModel;
    import org.springframework.cache.annotation.CachePut;
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.stereotype.Service;
    
    @Service
    public class ProductInfoCacheServiceImpl implements ProductInfoCacheService
    {
        public static final String CACHE_NAME = "product_service";
    
        @Override
        @Cacheable(value = CACHE_NAME, key = "'key_'+#productId")
        public ProductInfoModel findById(Integer productId)
        {
            return null;
        }
    
        @Override
        @CachePut(value = CACHE_NAME, key = "'key_'+#productInfo.getId()")
        public ProductInfoModel saveProductInfo(ProductInfoModel productInfo)
        {
            return productInfo;
        }
    }
    
  • 测试用例

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class ShopProductApplicationTests
    {
    
        @Autowired
        ProductInfoCacheService productInfoCacheService;
    
        @Test
        public void cacheTest()
        {
            String data = "{\"desc\":\"重构一切\",\"icons\":\"a.png;b.png\",\"id\":1,\"inventoryId\":1,\"price\":4999.00,\"title\":\"xxx手机\"}";
            ProductInfoModel productInfoModel = JSON.parseObject(data, ProductInfoModel.class);
            productInfoCacheService.saveProductInfo(productInfoModel);
    
            ProductInfoModel productInfoModel1 = productInfoCacheService.findById(1);
            System.out.println(JSON.toJSONString(productInfoModel1));
    
            ProductInfoModel productInfoModel2 = productInfoCacheService.findById(2);
            System.out.println(JSON.toJSONString(productInfoModel2));
        }
    
    }
    

ehcache 2.x

  • 引入资源

    <dependency>
        <groupId>net.sf.ehcache</groupId>
        <artifactId>ehcache</artifactId>
        <version>2.10.6</version>
    </dependency>
    
  • 添加xml配置 ehcache-2.10.6.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"
             updateCheck="false">
    
        <diskStore path="java.io.tmpdir/Tmp_EhCache"/>
    
        <!-- eternal 设置true的话timeout的策略失效,所以这里使用false -->
        <!-- maxElementsInMemory 最多缓存的条目数 -->
        <!-- overflowToDisk内存不够的情况下,是否溢出到磁盘 -->
        <!-- diskPersistent 是否启动持久化机制 在JVM重启时 数据是否有效 -->
        <!-- timeToIdleSeconds 设置最大闲置时间,闲置多久没有使用,自动删除 -->
        <!-- timeToLiveSeconds 设置最大存活时间,超过存活时间自动删除 -->
        <!-- memoryStoreEvictionPolicy 当达到最大条目时使用的清除策略 LRU(最近最少使用) FIFO(先进先出) LFU(较少使用)-->
        <defaultCache
                eternal="false"
                maxElementsInMemory="1000"
                overflowToDisk="false"
                diskPersistent="false"
                timeToIdleSeconds="0"
                timeToLiveSeconds="0"
                memoryStoreEvictionPolicy="LRU"/>
    
        <!-- name 缓存策略的名称 缓存时@Cacheable和@CachePut会使用到-->
        <cache
                name="product_service"
                eternal="false"
                maxElementsInMemory="1000"
                overflowToDisk="false"
                diskPersistent="false"
                timeToIdleSeconds="0"
                timeToLiveSeconds="0"
                memoryStoreEvictionPolicy="LRU"/>
    
    </ehcache>
    
  • 初始化Factory和Manager

    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 CacheConfiguration
    {
    
        @Bean
        public EhCacheManagerFactoryBean ehCacheManagerFactoryBean()
        {
            EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean();
            cacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache-2.10.6.xml"));
            cacheManagerFactoryBean.setShared(true);
            return cacheManagerFactoryBean;
        }
    
        @Bean
        public EhCacheCacheManager ehCacheCacheManager(EhCacheManagerFactoryBean bean)
        {
            return new EhCacheCacheManager(bean.getObject());
        }
    
    }
    

    file 如遇图片加载失败,可尝试使用手机流量访问

ehcache 3.x

  • 资源引入

    <!-- cache规范 -->
    <dependency>
        <groupId>javax.cache</groupId>
        <artifactId>cache-api</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.ehcache</groupId>
        <artifactId>ehcache</artifactId>
        <version>3.8.1</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    
  • 添加xml配置 ehcache-3.8.1.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <eh:config
            xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
            xmlns:eh='http://www.ehcache.org/v3'
            xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.3.xsd">
        <!--指定缓存目录-->
        <eh:persistence directory="${java.io.tmpdir}/cache-data"/>
    
        <!--缓存模板 用于定义基础的模版-->
        <eh:cache-template name="default">
            <eh:expiry>
                <!-- 过期策略 ttl:time to live,指定条目的存活时间 -->
                <eh:ttl unit="seconds">600</eh:ttl>
    
                <!-- 过期策略 tti:time to idle,条目在指定时间段内未被使用,则过期 -->
                <!-- <eh:tti unit="seconds">600</eh:tti>-->
    
                <!-- 不过期 只能手动删除 -->
                <!--<eh:none/>-->
            </eh:expiry>
            <eh:resources>
                <!--堆内内存可以的条目-->
                <eh:heap unit="entries">1000</eh:heap>
    
                <!-- 超过条目,保存到堆外内存 不配表示关闭-->
                <!--<eh:offheap unit="MB">10</eh:offheap>-->
    
                <!-- 堆外内存超了之后 保存至磁盘 -->
                <!--<eh:disk unit="MB">10</eh:disk>-->
    
                <!--缓存顺序-->
            </eh:resources>
        </eh:cache-template>
    
        <!-- 继承自defalt的配置 -->
        <eh:cache alias="sample" uses-template="default"></eh:cache>
    
        <!-- 继承自defaule 自定义了相关参数 -->
        <eh:cache alias="product_service" uses-template="default">
            <eh:expiry>
                <eh:ttl unit="hours">1</eh:ttl>
            </eh:expiry>
        </eh:cache>
    </eh:config>
    
  • application.yaml配置

    spring:
      cache:
        jcache:
          config: classpath:ehcache-3.8.1.xml
    
  • 创建测试对象

    // 务必开启 否则缓存会失败
    @EnableCaching
    

    file 如遇图片加载失败,可尝试使用手机流量访问

  • 测试结果file 如遇图片加载失败,可尝试使用手机流量访问



标题:并发(六)之堆缓存(二级缓存):SpringBoot整合ehcache2.x或3.x
作者:码霸霸
地址:https://blog.lupf.cn/articles/2020/04/17/1587096092192.html