该文章的主要内容为:springboot项目需要整合ehcache和redis,在整合ehcache和redis的过程中,ehcache部分的配置,以及简单的测试使用。
该文章主要展示了相关代码,具体的介绍有所省略。
一、springboot项目中整合ehcache和redis
springboot项目整合ehcache和redis的思路是,在RedisCacheManager和EhcacheCacheManager的基础上,构建一个整合性质的组件(Component_A),其可以根据缓存key从不同的Manager中获取对应的缓存区域(Cache)。
整合性质的组件(Component_A)的代码为:
package com.snail.spt4.basecommon.cache.cachecombine;
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.ehcache.EhCacheCacheManager; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.data.redis.cache.RedisCacheManager;
import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection;
/** * 缓存集成配置类,当前集成了redis,和ehcache。 * <p> * 该类通过向spring提供统一的{@link CacheManager}以达到集成不同缓存中间件的目的。<br> * 该类重写了{@link CachingConfigurerSupport#cacheManager()}和{@link CachingConfigurerSupport#keyGenerator()}的方法。 * * @author 51 * @version v0.1 2018年2月5日 下午6:45:44 51 * @see CachingConfigurerSupport */ @EnableCaching @Configuration public class CombineCacheConfig extends CachingConfigurerSupport { private static Logger logger = LoggerFactory.getLogger(CombineCacheConfig.class); /** * redis缓存前缀 * <p>用于通过缓存名前缀识别缓存中间件 */ private static final String REDIS_PREFIX = "redis_"; /** * ehcache缓存前缀 */ private static final String EHCACHE_PREFIX = "ehcache_"; @Autowired(required = false) private volatile RedisCacheManager redisCacheManager; @Autowired(required = false) private volatile EhCacheCacheManager ehCacheCacheManager; /** * 构造函数 */ public CombineCacheConfig() { super(); logger.info("执行了CombineCacheConfig.CombineCacheConfig()构造方法...\n"); } /** * 构建CacheManager的实例combineCacheManager * <p>combineCacheManager通过缓存名称<b>前缀</b>来识别缓存类型: * <ul> * <li>"redis_": redis cache</li> * <li>"ehcache_": ehcache cache</li> * </ul> * 该实例是spring操作缓存所必须的,且需要保证唯一,这意味着如果还需要Spring集成其它缓存中间件, * 仍然需要集成到combineCacheManager。<br> * * @see CachingConfigurerSupport#cacheManager() */ @Bean(name = "combineCacheManager") @Override public CacheManager cacheManager() { logger.info("执行了CombineCacheConfig.cacheManager()方法..." + "\nredisCacheManager=" + redisCacheManager + " ehCacheCacheManager=" + ehCacheCacheManager + "\n"); return new CacheManager() { @Override public Collection<String> getCacheNames() { logger.info("执行了CombineCacheConfig.cacheManager()#getCacheNames()方法...\n"); Collection<String> cacheNames = new ArrayList<String>(); if (redisCacheManager != null) { cacheNames.addAll(redisCacheManager.getCacheNames()); } if (ehCacheCacheManager != null) { cacheNames.addAll(ehCacheCacheManager.getCacheNames()); } return cacheNames; } @Override public Cache getCache(String name) { logger.info("执行了CombineCacheConfig.cacheManager()#getCache(String name)方法...name=" + name + "\n"); if (name.startsWith(REDIS_PREFIX)) { return redisCacheManager == null ? null : redisCacheManager.getCache(name); } if (name.startsWith(EHCACHE_PREFIX)) { return ehCacheCacheManager == null ? null : ehCacheCacheManager.getCache(name); } return null; } }; } /** * 构建默认的键生成器 * * @see CachingConfigurerSupport#keyGenerator() */ @Bean @Override public KeyGenerator keyGenerator() { logger.info("执行了CacheCombineConfig.keyGenerator()方法..." + "\nredisCacheManager=" + redisCacheManager + " ehCacheCacheManager=" + ehCacheCacheManager + "\n"); return new KeyGenerator() { @Override public Object generate(Object target, Method method, Object... params) { //logger.info("执行了CombineCacheConfig.keyGenerator()#generate()方法...\n"); StringBuilder keyStrBuilder = new StringBuilder(); keyStrBuilder.append(target.getClass().getName()).append("."); keyStrBuilder.append(method.getName()).append(":"); for (Object _param : params) { keyStrBuilder.append(_param.toString()).append(","); } //logger.info("keyStrBuilder.toString()="+ keyStrBuilder.toString()+ "\n"); return keyStrBuilder.toString(); } }; } public RedisCacheManager getRedisCacheManager() { return redisCacheManager; } public void setRedisCacheManager(RedisCacheManager redisCacheManager) { //logger.info("执行了setRedisCacheManager()方法..."); this.redisCacheManager = redisCacheManager; } public EhCacheCacheManager getEhCacheCacheManager() { return ehCacheCacheManager; } public void setEhCacheCacheManager(EhCacheCacheManager ehCacheCacheManager) { //logger.info("执行了setEhCacheCacheManager()方法..."); this.ehCacheCacheManager = ehCacheCacheManager; } } |
二、ehcache的相关配置
2.1、ehcache和spring整合时用到的相关类
此处列出了ehcache和spring整合时用到的相关类,及其关联。
(1)关于CacheManager
Ehcache Jar包中的实现:
net.sf.ehcache.CacheManager。 |
org.springframework:spring-context中的实现:
org.springframework.cache.ehcache.EhCacheCacheManager; Extends AbstractTransactionSupportingCacheManager; AbstractTransactionSupportingCacheManager class; Extends AbstractCacheManager; AbstractCacheManager class; Implements CacheManager, InitializingBean; org.springframework.cache.ehcache.EhCacheCacheManager class; //其内部引入了net sf.ehcache.CacheManager。 Private net sf.ehcache.CacheManager cacheManager; |
(2)关于Cache
Ehcache Jar包中的实现:
Net.sf.ehcache.Cache class; Implements InternalEhcache, StoreListener; net.sf.ehcache.terracotta.InternalEhcache interface; Extends Ehcache; net.sf.ehcache.Ehcache interface; Extends Cloneable; |
org.springframework:spring-context中的实现:
org.springframework.cache.ehcache.EhCacheCache class; Implements org.springframework.cache.Cache; org.springframework.cache.ehcache.EhCacheCache class; //其内部引入了net.sf.ehcache.Ehcache,实际上存储的是net.sf.ehcache.Cache对象。 Private final Ehcache cache; |
2.2、pom中引入
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> <version>${spring.boot.version}</version> </dependency>
<!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache --> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.10.9.2</version> </dependency> |
2.3、ehcache的使用
EhcacheService的代码:
package com.snail.spt4.basecommon.cache.ehcache.service;
import com.xcer.sptservice.utils.strprocess.Constants; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Ehcache; import net.sf.ehcache.Element; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cache.ehcache.EhCacheCacheManager; import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/** * ehcache服务类。 * @author cjw 2021/12/30 */ @Service public class EhcacheService { private static Logger logger= LoggerFactory.getLogger(EhcacheService.class); @Resource private EhCacheCacheManager ehCacheCacheManager; /** * 向ehcache_temp缓存区域中存入信息。 * @param timeToLive 存活时间 单位秒 * @params * @return * @author cjw 2021/12/31 */ public String putInfo(String key, Object value, int timeToLive) { CacheManager cacheManager= ehCacheCacheManager.getCacheManager(); Ehcache ehcache= cacheManager.getEhcache(EhcacheConstant.EHCACHE_TEMP); Element element= new Element(key, value, timeToLive, timeToLive); ehcache.put(element); return Constants.SUCCESS; } /** * 从ehcache_temp缓存区域中取信息。 * @params * @return * @author cjw 2022/1/3 */ public Object getInfo(String key) { CacheManager cacheManager= ehCacheCacheManager.getCacheManager(); Ehcache ehcache= cacheManager.getEhcache(EhcacheConstant.EHCACHE_TEMP); Element element= ehcache.get(key); if(element== null) { return null; } Object value= element.getObjectValue(); return value; }
} |
ContrEhcacheTest的代码:
package com.snail.spt4.basecommon.cache.ehcache.controller;
import com.snail.spt4.basecommon.cache.redis.utils.RedisConstant; import com.snail.spt4.modules.mcommon.utils.entity.RespStructCustom; import com.xcer.sptservice.utils.strprocess.ObjectParse; import com.xcer.sptservice.utils.strprocess.StrUtil; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Ehcache; import net.sf.ehcache.Element; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cache.Cache; import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.ehcache.EhCacheCacheManager; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import java.util.Map;
/** * @author cjw 2022/1/3 */ @RequestMapping(value = "/bc/ehcacheTest") @RestController public class ContrEhcacheTest { private static Logger logger= LoggerFactory.getLogger(ContrEhcacheTest.class); public static final String ClassName= "com.snail.spt4.basecommon.cache.ehcache.controller.ContrEhcacheTest"; @Resource private EhCacheCacheManager ehCacheCacheManager; /** * 测试缓存。 * @params * @return * @author cjw 2021/12/29 */ @Cacheable(value="ehcache_test", key="'"+ClassName+".testCache:map.uuid='+#map[\"uuid\"]") @RequestMapping(value = "/testCache") public RespStructCustom testCache(@RequestParam Map<String, Object> map) { StrUtil.prettyPrint("testCache().map", map); return RespStructCustom.success(); } /** * * @params * @return * @author cjw 2021/12/31 */ @Cacheable(value= RedisConstant.REDIS_HALFHOUR, key="'"+ClassName+".testCache2:map.uuid='+#map[\"uuid\"]") @RequestMapping(value = "/testCache2") public RespStructCustom testCache2(@RequestParam Map<String, Object> map) { StrUtil.prettyPrint("testCache2().map", map); return RespStructCustom.success(); } /** * * @params * @return * @author cjw 2021/12/31 */ @RequestMapping(value = "/testCache3") public RespStructCustom testCache3(@RequestParam Map<String, Object> map) { StrUtil.prettyPrintWithTime("testCache3().map", map); //Collection<String> cacheNames= ehCacheCacheManager.getCacheNames(); //StrUtil.prettyPrint("cacheNames", cacheNames); Cache cache= ehCacheCacheManager.getCache("ehcache_test"); cache.put("key_1", "value_1"); return RespStructCustom.success(); } /** * * @params * @return * @author cjw 2021/12/31 */ @RequestMapping(value = "/testCache4") public RespStructCustom testCache4(@RequestParam Map<String, Object> map) { StrUtil.prettyPrintWithTime("testCache4().map", map); Cache cache= ehCacheCacheManager.getCache("ehcache_test"); Cache.ValueWrapper valueWrapper= cache.get("key_1"); if(valueWrapper== null) { System.out.println("未找到key_1对应的值..."); } Object value= valueWrapper==null? null: valueWrapper.get(); System.out.println("key_1 value="+ value); return RespStructCustom.success(); } /** * * @params * @return * @author cjw 2021/12/31 */ @RequestMapping(value = "/testCache5") public RespStructCustom testCache5(@RequestParam Map<String, Object> map) { StrUtil.prettyPrintWithTime("testCache5().map", map); String key= ObjectParse.parse2Str(map.get("key")); String value= ObjectParse.parse2Str(map.get("value")); int timeToLive= ObjectParse.parse2Int(map.get("timeToLive")); CacheManager cacheManager= ehCacheCacheManager.getCacheManager(); Ehcache ehcache= cacheManager.getEhcache("ehcache_test"); Element element= new Element(key, value, timeToLive, timeToLive); ehcache.put(element); return RespStructCustom.success(); } /** * * @params * @return * @author cjw 2022/1/2 */ @RequestMapping(value = "/testCache6") public RespStructCustom testCache6(@RequestParam Map<String, Object> map) { StrUtil.prettyPrintWithTime("testCache6().map", map); String key= ObjectParse.parse2Str(map.get("key")); CacheManager cacheManager= ehCacheCacheManager.getCacheManager(); Ehcache ehcache= cacheManager.getEhcache("ehcache_test"); Element element= ehcache.get(key); StrUtil.prettyPrintWithTime("element", element); return RespStructCustom.success(); } /** * * @params * @return * @author cjw 2021/12/31 */ @RequestMapping(value = "/testCache7") public RespStructCustom testCache7(@RequestParam Map<String, Object> map) { StrUtil.prettyPrintWithTime("testCache7().map", map); String key= ObjectParse.parse2Str(map.get("key")); String value= ObjectParse.parse2Str(map.get("value")); //int timeToLive= ObjectParse.parse2Int(map.get("timeToLive")); CacheManager cacheManager= ehCacheCacheManager.getCacheManager(); Ehcache ehcache= cacheManager.getEhcache("ehcache_test"); Element element= new Element(key, value); ehcache.put(element); return RespStructCustom.success(); } /** * * @params * @return * @author cjw 2022/1/2 */ @RequestMapping(value = "/testCache8") public RespStructCustom testCache8(@RequestParam Map<String, Object> map) { StrUtil.prettyPrintWithTime("testCache8().map", map); String key= ObjectParse.parse2Str(map.get("key")); CacheManager cacheManager= ehCacheCacheManager.getCacheManager(); Ehcache ehcache= cacheManager.getEhcache("ehcache_test"); Element element= ehcache.get(key); StrUtil.prettyPrintWithTime("element", element); return RespStructCustom.success(); } } |
三、总结
至此,springboot项目整合ehcache和redis的过程中,ehcache部分的配置的介绍,就暂时结束了。