Spring集成ehcache缓存配置文件模板

最近在解决一个系统的缓存不生效bug,用到的是spring框架自带缓存技术ehcache

对比我们常用的缓存中间件Redis,ehcache在Java生态下也具有他适用场景。
借此机会,正好学习一下,系统中ehcache缓存框架的集成过程。

第一步,导入ehcache需要的依赖

这里是我这边项目原先使用的依赖,如果不适用,可以参考其他文章引入的依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
    <version>1.4.2.RELEASE</version>
</dependency>

<dependency>
	<groupId>net.sf.ehcache</groupId>
	<artifactId>ehcache-core</artifactId>
	<version>2.4.5</version>
</dependency>

第二步,使用场景demo(service层)

查询方法上添加@Cacheable,便可以达到缓存数据的目的。

@Override
@Cacheable(value = CacheConstants.MCCP_HIGHLOAD_GETHIGHLOAD45GCHAIN_DAY_CACHE,key = "#param.starttime+'_'+#param.endtime")
public List<Map<String, Object>> getHighload45GChain(HighloadParam param) {
   return iHighloadPortraitMapper.getHighload45GChain(param);
}

ps: ctrl+鼠标,点击@Cacheable注解,可以看到该注解的两个常用参数value(cacheNames)和key,
value是一个String类型的数组,可以指定多个,
key一般是填你方法对应的参数,(注意key不能是对象,因为对象是变化的,可能导致缓存失效!)

//使用到的常量类
public class CacheConstants {

    // 45G流量环比,5G分流比环比
    public final static String  MCCP_HIGHLOAD_GETHIGHLOAD45GCHAIN_DAY_CACHE  = "highload_gethighload45gchain_day_cache";
}
/**
* 实体类
* 项目使用了swagger,没有集成的话,把@ApiModel,@ApiModelProperty去掉就行
* 注意,List<String> city也是对象,缓存的key尽量避免使用。
*/
@ApiModel
public class HighloadParam implements Serializable {

    @ApiModelProperty(name = "starttime",value = "2021-05-17",required = false)
    private String starttime;
    @ApiModelProperty(name = "endtime",value = "2021-07-05",required = false)
    private String endtime;
    @ApiModelProperty(name = "city",value = "地市",required = false)
    private List<String> city;
    
    @Override
    public String toString() {
        return "HighloadParam{" +
                "starttime='" + starttime + '\'' +
                ", endtime='" + endtime + '\'' +
                ", city=" + city  +
                '}';
    }
}

第三步,编写ehcache.xml配置文件,这里提供通用模板。

在项目的resources目录下新建ehcache文件夹,并创建ehcache.xml文件。
ehcache会将相关缓存数据存放在这个文件下。

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

	<diskStore path="java.io.tmpdir"/>

	<!--
		defaultCache:默认的缓存配置信息,如果不加特殊说明,则所有对象按照此配置项处理
		
		maxElementsInMemory:设置了缓存的上限,最多存储多少个记录对象
		eternal:代表对象是否永不过期
		overflowToDisk:当内存中Element数量达到maxElementsInMemory时,Ehcache将会Element写到磁盘中
		
		maxElementsInMemory设置成1,overflowToDisk设置成true,只要有一个缓存元素,就直接存到硬盘上去
		eternal设置成true,代表对象永久有效
		maxElementsOnDisk设置成0 表示硬盘中最大缓存对象数无限大
		diskPersistent设置成true表示缓存虚拟机重启期数据
     -->
	<defaultCache
			maxElementsInMemory="10000"
			maxElementsOnDisk="0"
			eternal="true"
			overflowToDisk="true"
			diskPersistent="false"
			timeToIdleSeconds="0"
			timeToLiveSeconds="0"
			diskSpoolBufferSizeMB="50"
			diskExpiryThreadIntervalSeconds="120"
			memoryStoreEvictionPolicy="LFU"
	/>

	<!-- cache设定具体的命名缓存的数据过期策略-->
	<!-- eternal 如果为true,表示对象永远不会过期 会忽略time-->
	<!-- diskPersistent 是否disk store在虚拟机启动时持久化。默认为false-->
	<!-- 45G流量环比,5G分流比环比:失效时间:永久  -->
	<cache name="highload_gethighload45gchain_day_cache" eternal="false"
		   maxElementsInMemory="1000"
		   overflowToDisk="true"
		   diskPersistent="false"
		   timeToIdleSeconds="0"
		   timeToLiveSeconds="1800"
		   memoryStoreEvictionPolicy="LRU" />

	<!-- 多个方法使用缓存,依次copy<cache>标签,注意更改name就行  -->
	<cache name="xxxxxxx" eternal="false"
		   maxElementsInMemory="1000"
		   overflowToDisk="true"
		   diskPersistent="false"
		   timeToIdleSeconds="0"
		   timeToLiveSeconds="1800"
		   memoryStoreEvictionPolicy="LRU" />

</ehcache>

该项目没有使用在启动类上使用注解的方式,开启ehcache的缓存注解声明,
而是采用spring配置的方式,来声明对应的bean,
在resources目录下创建applicationContext-ehcache.xml文件,可以直接copy模板

<?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:p="http://www.springframework.org/schema/p"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:cache="http://www.springframework.org/schema/cache"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
		http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"
  default-autowire="byName" default-lazy-init="false">
    
    <description>Spring3.1原生EhCache缓存</description>
    
    <!-- 启用缓存注解功能 -->
	<cache:annotation-driven cache-manager="ehCacheManager" />
	
	<!-- 声明cacheManager -->
	<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
	p:cacheManager-ref="ehCacheManagerFactory" /> 

    <!-- cacheManagerFactory工厂类 -->
    <bean id="ehCacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
		<property name="configLocation" value="classpath:ehcache/ehcache.xml" />
	</bean>
</beans>

第四步,验证ehcache缓存流程,及缓存实现的逻辑(通用思想)

这里先介绍使用缓存的逻辑过程,看图说话。
总之,一句话,使用缓存就是除了第一次查询外,后面的查询都不直接查询数据库,提高查询速度。
缓存逻辑
查看项目日志进行验证,
第一次调用该方法,走数据库,日志有打印查询SQL;
第二次调用该方法,日志无SQL日志输出,访问页面响应速度变快。

第四步,测试缓存引是否成功的方法

@RestController
@RequestMapping(value = "/highload")
public class HighloadController {
	
	@Autowired
    private EhCacheManagerFactoryBean ehCacheManagerFactory;

	@PostMapping("/testCache")
    public R testCache(@RequestParam(name="key") String key,@RequestParam(name="val")String val) {
        CacheManager cacheManager = ehCacheManagerFactory.getObject();
        Cache cache = cacheManager.getCache(CacheConstants.MCCP_HIGHLOAD_GETHIGHLOAD45G_DAY_CACHE);
        Element element = cache.get(key);
        //缓存判断
        if(element==null){
            cache.put(new Element(key, val));
            return R.success("cache首次进入");
        }else{
            System.out.println(element.getObjectValue());
            return R.success(element.getObjectValue().toString(),"进来缓存了:");
        }
    }
    
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值