springboot同时整合redis和ehcache

[源]:https://blog.csdn.net/caiwufei/article/details/78863804

springboot同时整合redis和ehcache,redis和ehcache各种工作,互补干扰。

1.maven依赖

  1. <!– 本地缓存依赖 –>  
  2. <dependency>  
  3.     <groupId>org.springframework.boot</groupId>  
  4.     <artifactId>spring-boot-starter-cache</artifactId>  
  5. </dependency>  
  6. <dependency>    
  7.             <groupId>org.ehcache</groupId>    
  8.             <artifactId>ehcache</artifactId>    
  9. </dependency>    
  10. <dependency>    
  11.             <groupId>javax.cache</groupId>    
  12.             <artifactId>cache-api</artifactId>    
  13. </dependency>    
  14.   
  15.   
  16.       <!– redis   –>  
  17.       <dependency>  
  18.           <groupId>org.springframework.boot</groupId>  
  19.           <artifactId>spring-boot-starter-data-redis</artifactId>  
  20.       </dependency>  
       <!-- 本地缓存依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <dependency>  
            <groupId>org.ehcache</groupId>  
            <artifactId>ehcache</artifactId>  
        </dependency>  
        <dependency>  
            <groupId>javax.cache</groupId>  
            <artifactId>cache-api</artifactId>  
        </dependency>  


        <!-- redis   -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

同时把ehcache的版本设置下,我设置的3.4.0。在maven的属性中添加<ehcache3.version>3.4.0</ehcache3.version>,即可以覆盖父依赖的。

2.在application.properties中添加相关配置。主要是ehcache和redis的

  1. #——————-ehcache———————-  
  2. spring.cache.type=jcache  
  3. spring.cache.jcache.config=classpath:/config/ehcache.xml  
  4. spring.cache.jcache.provider=org.ehcache.jsr107.EhcacheCachingProvider  
  5.   
  6. #——————-redis————————  
  7. spring.redis.host=ip  
  8. spring.redis.port=port  
  9. spring.redis.password=pwd  
  10. spring.redis.pool.max-active=10  
  11. spring.redis.pool.max-wait=-1  
  12. spring.redis.pool.max-idle=5  
  13. spring.redis.pool.min-idle=0  
  14. spring.redis.timeout=50  
  15. spring.redis.ssl=false  
#-------------------ehcache----------------------
spring.cache.type=jcache
spring.cache.jcache.config=classpath:/config/ehcache.xml
spring.cache.jcache.provider=org.ehcache.jsr107.EhcacheCachingProvider





——————-redis————————

spring.redis.host=ip
spring.redis.port=port
spring.redis.password=pwd
spring.redis.pool.max-active=10
spring.redis.pool.max-wait=-1
spring.redis.pool.max-idle=5
spring.redis.pool.min-idle=0
spring.redis.timeout=50
spring.redis.ssl=false
3.在添加stater和配置属性后,系统启动的时候两种缓存都会加载。jecache默认为ehcache。

但是我想要的是,我使用缓存注解的时候,指定缓存一处,要么是本地,要么是redis。spring提供了自己的一套缓存管理器来管理其他第三方的缓存。集成接口实现自己的即可。

添加redis的starter的时候,redistemplate已经被注入了,但是是<k,v>泛型的。

  1. package com.caiwufei.springboot;  
  2.   
  3. import java.net.URISyntaxException;  
  4. import javax.cache.Caching;  
  5. import javax.cache.spi.CachingProvider;  
  6. import org.springframework.beans.factory.annotation.Qualifier;  
  7. import org.springframework.cache.CacheManager;  
  8. import org.springframework.cache.annotation.EnableCaching;  
  9. import org.springframework.cache.jcache.JCacheCacheManager;  
  10. import org.springframework.context.annotation.Bean;  
  11. import org.springframework.context.annotation.Primary;  
  12. import org.springframework.data.redis.cache.RedisCacheManager;  
  13. import org.springframework.data.redis.core.RedisTemplate;  
  14. import org.springframework.data.redis.serializer.StringRedisSerializer;  
  15. import com.caiwufei.common.cache.AppCacheManager;  
  16. import com.caiwufei.entity.base.BaseEntity;  
  17.   
  18. @EnableCaching  
  19. @SuppressWarnings({ “rawtypes”“unchecked” })  
  20. public class CacheConfig{  
  21.   
  22. /*  @Autowired 
  23.     private RedisConnectionFactory factory;*/  
  24.       
  25.       
  26.     @Bean(“redisCacheManager”)  
  27.     public RedisCacheManager redisCacheManager(@Qualifier(“redisTemplate”)RedisTemplate redisTemplate) {    
  28.         //设置数据存入 redis 的序列化方式  
  29.         redisTemplate.setKeySerializer(new StringRedisSerializer());  
  30.         redisTemplate.setHashKeySerializer(new StringRedisSerializer());  
  31.         redisTemplate.setHashValueSerializer(new BaseEntity<>());  
  32.         redisTemplate.setValueSerializer(new BaseEntity<>());  
  33.         return new RedisCacheManager(redisTemplate);    
  34.     }   
  35.       
  36.     @Bean(“jCacheCacheManager”)  
  37.     public JCacheCacheManager jCacheCacheManager() throws URISyntaxException {  
  38.         CachingProvider provider = Caching.getCachingProvider();  
  39.         JCacheCacheManager jCacheCacheManager = new JCacheCacheManager();   
  40.         javax.cache.CacheManager eh107CacheManager = provider.getCacheManager(getClass().getResource(”/config/ehcache.xml”).toURI(), getClass().getClassLoader());  
  41.         jCacheCacheManager.setCacheManager(eh107CacheManager);  
  42.         return jCacheCacheManager;  
  43.     }  
  44.       
  45.     @Bean(“cacheManager”)  
  46.     @Primary  
  47.     public CacheManager initMixCacheManager(RedisCacheManager redisCacheManager, JCacheCacheManager ehCacheManager) {  
  48.         AppCacheManager cacheManager = new AppCacheManager();  
  49.         cacheManager.setRedisCacheManager(redisCacheManager);  
  50.         cacheManager.setEhCacheCacheManager(ehCacheManager);  
  51.         return cacheManager;  
  52.     }  
  53.   
  54.            
  55.       
  56.     /** 
  57.      * 实例化 HashOperations 对象,可以使用 Hash 类型操作 
  58.      */  
  59.       
  60.     /** 
  61.      * 实例化 ValueOperations 对象,可以使用 String 操作 
  62.      */  
  63.       
  64.     /** 
  65.      * 实例化 ListOperations 对象,可以使用 List 操作 
  66.      */   
  67.       
  68.     /** 
  69.      * 实例化 SetOperations 对象,可以使用 Set 操作 
  70.      */  
  71.      
  72.     /** 
  73.      * 实例化 ZSetOperations 对象,可以使用 ZSet 操作 
  74.      */  
  75. }  
package com.caiwufei.springboot;

import java.net.URISyntaxException;
import javax.cache.Caching;
import javax.cache.spi.CachingProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.jcache.JCacheCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.caiwufei.common.cache.AppCacheManager;
import com.caiwufei.entity.base.BaseEntity;

@EnableCaching
@SuppressWarnings({ "rawtypes", "unchecked" })
public class CacheConfig{

/*  @Autowired
    private RedisConnectionFactory factory;*/


    @Bean("redisCacheManager")
    public RedisCacheManager redisCacheManager(@Qualifier("redisTemplate")RedisTemplate redisTemplate) {  
        //设置数据存入 redis 的序列化方式
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new BaseEntity<>());
        redisTemplate.setValueSerializer(new BaseEntity<>());
        return new RedisCacheManager(redisTemplate);  
    } 

    @Bean("jCacheCacheManager")
    public JCacheCacheManager jCacheCacheManager() throws URISyntaxException {
        CachingProvider provider = Caching.getCachingProvider();
        JCacheCacheManager jCacheCacheManager = new JCacheCacheManager(); 
        javax.cache.CacheManager eh107CacheManager = provider.getCacheManager(getClass().getResource("/config/ehcache.xml").toURI(), getClass().getClassLoader());
        jCacheCacheManager.setCacheManager(eh107CacheManager);
        return jCacheCacheManager;
    }

    @Bean("cacheManager")
    @Primary
    public CacheManager initMixCacheManager(RedisCacheManager redisCacheManager, JCacheCacheManager ehCacheManager) {
        AppCacheManager cacheManager = new AppCacheManager();
        cacheManager.setRedisCacheManager(redisCacheManager);
        cacheManager.setEhCacheCacheManager(ehCacheManager);
        return cacheManager;
    }



    /**
     * 实例化 HashOperations 对象,可以使用 Hash 类型操作
     */

    /**
     * 实例化 ValueOperations 对象,可以使用 String 操作
     */

    /**
     * 实例化 ListOperations 对象,可以使用 List 操作
     */ 

    /**
     * 实例化 SetOperations 对象,可以使用 Set 操作
     */

    /**
     * 实例化 ZSetOperations 对象,可以使用 ZSet 操作
     */
}

下面是appcachemanger的实现

  1. package com.caiwufei.common.cache;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Collection;  
  5. import org.springframework.cache.Cache;  
  6. import org.springframework.cache.CacheManager;  
  7.   
  8. public class AppCacheManager implements CacheManager{  
  9.       
  10.     private CacheManager redisCacheManager;    
  11.     private CacheManager ehCacheManager;   
  12.       
  13.     private final static String redisPrefix = “redis”;  
  14.   
  15.     @Override  
  16.     public Cache getCache(String name) {  
  17.         if (name.startsWith(redisPrefix))  {  
  18.              return redisCacheManager.getCache(name);    
  19.         } else {  
  20.             return ehCacheManager.getCache(name);    
  21.         }  
  22.     }  
  23.   
  24.     @Override  
  25.     public Collection<String> getCacheNames() {  
  26.         Collection<String> cacheNames = new ArrayList<String>();            
  27.         if (redisCacheManager != null) {    
  28.             cacheNames.addAll(redisCacheManager.getCacheNames());    
  29.         }    
  30.         if (ehCacheManager != null) {    
  31.             cacheNames.addAll(ehCacheManager.getCacheNames());    
  32.         }           
  33.         return cacheNames;    
  34.     }  
  35.   
  36.     public CacheManager getRedisCacheManager() {  
  37.         return redisCacheManager;  
  38.     }  
  39.   
  40.     public void setRedisCacheManager(CacheManager redisCacheManager) {  
  41.         this.redisCacheManager = redisCacheManager;  
  42.     }  
  43.   
  44.     public CacheManager getEhCacheCacheManager() {  
  45.         return ehCacheManager;  
  46.     }  
  47.   
  48.     public void setEhCacheCacheManager(CacheManager ehcacheCacheManager) {  
  49.         this.ehCacheManager = ehcacheCacheManager;  
  50.     }  
  51.   
  52.       
  53.       
  54. }  
package com.caiwufei.common.cache;

import java.util.ArrayList;
import java.util.Collection;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;

public class AppCacheManager implements CacheManager{

    private CacheManager redisCacheManager;  
    private CacheManager ehCacheManager; 

    private final static String redisPrefix = "redis";

    @Override
    public Cache getCache(String name) {
        if (name.startsWith(redisPrefix))  {
             return redisCacheManager.getCache(name);  
        } else {
            return ehCacheManager.getCache(name);  
        }
    }

    @Override
    public Collection<String> getCacheNames() {
        Collection<String> cacheNames = new ArrayList<String>();          
        if (redisCacheManager != null) {  
            cacheNames.addAll(redisCacheManager.getCacheNames());  
        }  
        if (ehCacheManager != null) {  
            cacheNames.addAll(ehCacheManager.getCacheNames());  
        }         
        return cacheNames;  
    }

    public CacheManager getRedisCacheManager() {
        return redisCacheManager;
    }

    public void setRedisCacheManager(CacheManager redisCacheManager) {
        this.redisCacheManager = redisCacheManager;
    }

    public CacheManager getEhCacheCacheManager() {
        return ehCacheManager;
    }

    public void setEhCacheCacheManager(CacheManager ehcacheCacheManager) {
        this.ehCacheManager = ehcacheCacheManager;
    }



}

4此时容器中有三个缓存管理器,一个是jcache,一个是redis的,还有一个是我们自己实现的,但是我们设置我们自己为primary即可。

5测试

dao层的

  1. public interface SSAccountInfoDao extends BaseMapper<SSAccountInfo>{  
  2.       
  3.     @Cacheable(cacheNames=“redis-SSAccountInfo”, key=“‘SSAccountInfo_’ + #root.args[0].accountId”, unless=“#result==null”)  
  4.     public SSAccountInfo queryByAccountIdForTestRedis(SSAccountInfo account);  
  5.       
  6.     @Cacheable(cacheNames=“SSAccountInfo”,  key=“‘SSAccountInfo_’ + #root.args[0].accountId”, unless=“#result==null”//ehcache.xml需要配置  
  7.     public SSAccountInfo queryByAccountIdForTestEhcache(SSAccountInfo a);  
  8. }  
public interface SSAccountInfoDao extends BaseMapper<SSAccountInfo>{

@Cacheable(cacheNames="redis-SSAccountInfo", key="'SSAccountInfo_' + #root.args[0].accountId", unless="#result==null")
public SSAccountInfo queryByAccountIdForTestRedis(SSAccountInfo account);

@Cacheable(cacheNames="SSAccountInfo",  key="'SSAccountInfo_' + #root.args[0].accountId", unless="#result==null") //ehcache.xml需要配置
public SSAccountInfo queryByAccountIdForTestEhcache(SSAccountInfo a);

}

controller层的

  1. @GetMapping(“/testcache”)  
  2.     public Object testcache() {  
  3.         SSAccountInfo param = new SSAccountInfo();  
  4.         param.setAccountId(”F54045545”);  
  5.           
  6.         long t = System.currentTimeMillis();  
  7.         ssAccountInfoService.queryByAccountIdForTestEhcache(param);  
  8.         System.out.println(”TestEhcache第一次查询耗时:” + (System.currentTimeMillis()-t));  
  9.           
  10.         t = System.currentTimeMillis();  
  11.         ssAccountInfoService.queryByAccountIdForTestEhcache(param);  
  12.         System.out.println(”TestEhcache第二次查询耗时:” + (System.currentTimeMillis()-t));  
  13.           
  14.         JCacheCache jCache = (JCacheCache) cacheManager.getCache(”SSAccountInfo”);  
  15.         if(jCache.getNativeCache().containsKey((“SSAccountInfo_” + param.getAccountId()))){  
  16.             System.out.println(”————–ehcache存在————-“);  
  17.             SSAccountInfo ehcache = (SSAccountInfo) jCache.getNativeCache().get(”SSAccountInfo_” + param.getAccountId());  
  18.             System.out.println(”ehcache__” + ehcache.getAccountId() +  + ehcache.getAccountName());  
  19.         }else {  
  20.             System.out.println(”————–ehcache不存在————-“);  
  21.         }  
  22.           
  23.         t = System.currentTimeMillis();  
  24.         ssAccountInfoService.queryByAccountIdForTestRedis(param);  
  25.         System.out.println(”TestRedis第一次查询耗时:” + (System.currentTimeMillis()-t));  
  26.           
  27.         t = System.currentTimeMillis();  
  28.         ssAccountInfoService.queryByAccountIdForTestRedis(param);  
  29.         System.out.println(”TestRedis第二次查询耗时:” + (System.currentTimeMillis()-t));  
  30.           
  31.         if(RedisTemplate.hasKey(“SSAccountInfo” + param.getAccountId())) {  
  32.             System.out.println(”————–redis存在————-“);  
  33.             SSAccountInfo redis = (SSAccountInfo) RedisTemplate.get(”SSAccountInfo_” + param.getAccountId());  
  34.             System.out.println(”redis” + redis.getAccountId() + _ + redis.getAccountName());  
  35.         }else {  
  36.             System.out.println(”————–redis不存在————-“);  
  37.         }  
  38.           
  39.         return “YES”;  
  40.     }  
@GetMapping("/testcache") 
public Object testcache() {
SSAccountInfo param = new SSAccountInfo();
param.setAccountId("F54045545");
    long t = System.currentTimeMillis();
    ssAccountInfoService.queryByAccountIdForTestEhcache(param);
    System.out.println("TestEhcache第一次查询耗时:" + (System.currentTimeMillis()-t));

    t = System.currentTimeMillis();
    ssAccountInfoService.queryByAccountIdForTestEhcache(param);
    System.out.println("TestEhcache第二次查询耗时:" + (System.currentTimeMillis()-t));

    JCacheCache jCache = (JCacheCache) cacheManager.getCache("SSAccountInfo");
    if(jCache.getNativeCache().containsKey(("SSAccountInfo_" + param.getAccountId()))){
        System.out.println("--------------ehcache存在-------------");
        SSAccountInfo ehcache = (SSAccountInfo) jCache.getNativeCache().get("SSAccountInfo_" + param.getAccountId());
        System.out.println("ehcache__" + ehcache.getAccountId() + "___" + ehcache.getAccountName());
    }else {
        System.out.println("--------------ehcache不存在-------------");
    }

    t = System.currentTimeMillis();
    ssAccountInfoService.queryByAccountIdForTestRedis(param);
    System.out.println("TestRedis第一次查询耗时:" + (System.currentTimeMillis()-t));

    t = System.currentTimeMillis();
    ssAccountInfoService.queryByAccountIdForTestRedis(param);
    System.out.println("TestRedis第二次查询耗时:" + (System.currentTimeMillis()-t));

    if(RedisTemplate.hasKey("SSAccountInfo_" + param.getAccountId())) {
        System.out.println("--------------redis存在-------------");
        SSAccountInfo redis = (SSAccountInfo) RedisTemplate.get("SSAccountInfo_" + param.getAccountId());
        System.out.println("redis__" + redis.getAccountId() + "___" + redis.getAccountName());
    }else {
        System.out.println("--------------redis不存在-------------");
    }

    return "YES";
}</pre>service层的省略,下面是结果

  1. TestEhcache第一次查询耗时:3760  
  2. TestEhcache第二次查询耗时:7  
  3. ————–ehcache存在————-  
  4. ehcache__F54045545___null  
  5. TestRedis第一次查询耗时:126  
  6. TestRedis第二次查询耗时:12  
  7. ————–redis存在————-  
  8. redis__F54045545___null  
TestEhcache第一次查询耗时:3760 
TestEhcache第二次查询耗时:7
--------------ehcache存在-------------
ehcache__F54045545___null
TestRedis第一次查询耗时:126
TestRedis第二次查询耗时:12
--------------redis存在-------------
redis__F54045545___null

很明显,it works!

这种方法也可以使用来隔离使用注解的时候不缓存到redis,redis缓存可以使用模板操作。当然也可以直接使用注解,看个人喜欢。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值