zoukankan      html  css  js  c++  java
  • 面向接口编程——整合多缓存实例

      在企业级JavaWeb框架中,面对业务的复杂性和变化性,往往一种企业级功能需要开发多套技术以便灵活使用,本文通过Redis和Ehcache的整合,来介绍面向接口编程的方便性。

    • 第一步根据缓存的共性,抽象出接口类:
     1 public interface ICacheManager {
     2     
     3     <T extends Object> T get(String cacheName, Object key);
     4 
     5     void put(String cacheName, Object key, Object value);
     6 
     7     void remove(String cacheName, Object key);
     8 
     9     void removeAll(String cacheName);
    10     
    11 }
    • 第二步分别对Redis和Ehcache做具体实现:
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     3     xmlns:context="http://www.springframework.org/schema/context" xmlns="http://www.springframework.org/schema/beans"
     4     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
     5                         http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-4.0.xsd">
     6 
     7     <description>Jedis Configuration</description>
     8 
     9     <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    10         <!-- 最大连接数 -->
    11         <property name="maxTotal" value="${redis.pool.maxTotal}"/>
    12         <!-- 最大空闲 -->
    13         <property name="maxIdle" value="${redis.pool.maxIdle}"/>
    14         <!-- 每次最大连接数 -->
    15         <property name="numTestsPerEvictionRun" value="${redis.pool.numTestsPerEvictionRun}"/>
    16         <!-- 释放扫描的扫描间隔 -->
    17         <property name="timeBetweenEvictionRunsMillis" value="${redis.pool.timeBetweenEvictionRunsMillis}"/>
    18         <!-- 连接的最小空闲时间 -->
    19         <property name="minEvictableIdleTimeMillis" value="${redis.pool.minEvictableIdleTimeMillis}"/>
    20         <!-- 连接控歘按时间多久后释放,当空闲时间>该值且空闲连接>最大空闲连接数时直接释放 -->
    21         <property name="softMinEvictableIdleTimeMillis" value="${redis.pool.softMinEvictableIdleTimeMillis}"/>
    22         <!-- 获得链接时的最大等待毫秒数,小于0:阻塞不确定时间,默认-1 -->
    23         <property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}"/>
    24         <!-- 在获得链接的时候检查有效性,默认false -->
    25         <property name="testOnBorrow" value="${redis.pool.testOnBorrow}"/>
    26         <!-- 在空闲时检查有效性,默认false -->
    27         <property name="testWhileIdle" value="${redis.pool.testWhileIdle}"/>
    28         <!-- 连接耗尽时是否阻塞,false报异常,true阻塞超时 默认:true-->
    29         <property name="blockWhenExhausted" value="${redis.pool.blockWhenExhausted}"/>
    30     </bean>
    31     
    32     <bean id="redisConnectionFactory"
    33         class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
    34         <constructor-arg index="0" ref="jedisPoolConfig" />
    35         <property name="hostName" value="${redis.ip}" />
    36         <property name="port" value="${redis.port}" />
    37         <property name="password" value="${redis.password}" />
    38         <property name="timeout" value="${redis.timeout}" />
    39     </bean>
    40 
    41     <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
    42         <property name="connectionFactory" ref="redisConnectionFactory" />
    43     </bean>
    44 
    45     <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
    46         <constructor-arg index="0" ref="redisTemplate" />
    47     </bean>
    48 </beans>
     1 public class RedisCacheManagerImpl implements ICacheManager {
     2 
     3     public final static RedisCacheManager redisCacheManager = SpringContextHolder.getBean("redisCacheManager");
     4 
     5     protected static CacheManager getCacheManager() {
     6         return redisCacheManager;
     7     }
     8 
     9     @Override
    10     @SuppressWarnings("unchecked")
    11     public <T extends Object> T get(String cacheName, Object key) {
    12         Cache cache = getCacheManager().getCache(cacheName);
    13         Cache.ValueWrapper valueWrapper = cache.get(cacheName + "." + key);
    14         return (T) valueWrapper.get();
    15     }
    16 
    17     @Override
    18     public void put(String cacheName, Object key, Object value) {
    19         Cache cache = getCacheManager().getCache(cacheName);
    20         cache.put(cacheName + "." + key, value);
    21     }
    22 
    23     @Override
    24     public void remove(String cacheName, Object key) {
    25         Cache cache = getCacheManager().getCache(cacheName);
    26         cache.evict(cacheName + "." + key);
    27     }
    28 
    29     @Override
    30     public void removeAll(String cacheName) {
    31         Cache cache = getCacheManager().getCache(cacheName);
    32         cache.clear();
    33     }
    34 }
    
    
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <ehcache updateCheck="false" name="defaultCache">
     3 
     4     <!-- 
     5         磁盘存储:将缓存中暂时不使用的对象,转移到硬盘,类似于Windows系统的虚拟内存
     6         path:指定在硬盘上存储对象的路径
     7     -->
     8     <diskStore path="java.io.tmpdir/otc"/>
     9 
    10     <!-- 默认缓存配置. -->
    11     <defaultCache maxEntriesLocalHeap="100" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600"
    12                   overflowToDisk="true" maxEntriesLocalDisk="100000"/>
    13     
    14 </ehcache>
    
    
    

    1
    public class EhCacheManagerImpl implements ICacheManager { 2 3 public final static CacheManager cacheManager = SpringContextHolder.getBean("cacheManager"); 4 5 protected static CacheManager getCacheManager() { 6 return cacheManager; 7 } 8 9 /** 10 * 获得一个Cache,没有则创建一个。 11 * @param cacheName 12 * @return 13 */ 14 private static synchronized Cache getCache(String cacheName) { 15 Cache cache = getCacheManager().getCache(cacheName); 16 if (cache == null) { 17 getCacheManager().addCache(cacheName); 18 cache = getCacheManager().getCache(cacheName); 19 cache.getCacheConfiguration().setEternal(true); 20 } 21 return cache; 22 } 23 24 @Override 25 @SuppressWarnings("unchecked") 26 public <T extends Object> T get(String cacheName, Object key) { 27 Element element = getCache(cacheName).get(key); 28 return element == null ? null : (T) element.getObjectValue(); 29 } 30 31 @Override 32 public void put(String cacheName, Object key, Object value) { 33 Element element = new Element(key, value); 34 getCache(cacheName).put(element); 35 } 36 37 @Override 38 public void remove(String cacheName, Object key) { 39 getCache(cacheName).remove(key); 40 } 41 42 @Override 43 public void removeAll(String cacheName) { 44 Cache cache = getCacheManager().getCache(cacheName); 45 cache.removeAll(true); 46 } 47 }
    • 第三步:创建枚举类和工厂类用于生成对应的缓存类
     1 public enum CacheEnum{
     2     
     3     ehcache("ehCacheManagerImpl", "ehcache 实现"),
     4     redis("redisCacheManagerImpl", "redis 实现");
     5 
     6     private String cacheType;
     7     
     8     private String cacheDesc;
     9 
    10     CacheEnum(String cacheType, String cacheDesc) {
    11         this.cacheType = cacheType;
    12         this.cacheDesc = cacheDesc;
    13     }
    14 
    15     public String getCacheType() {
    16         return cacheType;
    17     }
    18 
    19     public String getCacheDesc() {
    20         return cacheDesc;
    21     }
    22 }
     1 public final class CacheFactory {
     2     
     3     /**
     4      * 获取默认缓存对象
     5      * @return
     6      */
     7     public static ICacheManager getCache(){
     8         return getCache(CacheEnum.ehcache);
     9     }
    10     
    11     /**
    12      * 根据类型获取缓存对象
    13      * @param cacheType
    14      * @return
    15      */
    16     public static ICacheManager getCache(CacheEnum cacheType){
    17         if(cacheType == null)
    18             cacheType = CacheEnum.ehcache;
    19         return SpringContextHolder.getBean(cacheType.getCacheType());
    20     }
    21 }

    第四步:使用缓存类

      1 @Service
      2 public class DictContextService {
      3     private ICacheManager cacheManager = CacheFactory.getCache();
      4     @Autowired
      5     private DictionaryMapper dictionaryMapper;
      6     @Autowired
      7     private DictionaryItemMapper dictionaryItemMapper;
      8     @Autowired
      9     private JdbcTemplate jdbcTemplate;
     10     
     11     private final String DICTIONARYS_CACHE_KEY = "dictionarys_cache_key";
     12     private final String DICTIONARY_ITEMS_CACKE_KEY = "dictionary_items_cacke";
     13     
     14     /**
     15      * 获取    完整对应后的 有效字典
     16      * @return
     17      */
     18     public Map<String,Dictionary> getMapDictionary(){
     19         List<Dictionary> dictionarys = getValidDictionarys();
     20         Map<String, Dictionary> rltDictMap = new HashMap<String, Dictionary>();
     21         for (Dictionary dictionary : dictionarys) {
     22             if(dictionary.getDictType() == Constant.NUMBER_INTEGER_1 && 
     23                     dictionary.getIsCache() == Constant.NUMBER_INTEGER_1) { //(内部字典)开启缓存的字典
     24                 List<DictionaryItem> dictItems = getDictResponseItems(dictionary.getDictCode()); //获取字典对应的字典项
     25                 dictionary.setDictItems(dictItems);
     26                 rltDictMap.put(dictionary.getDictCode(), dictionary);
     27             }else{
     28                 rltDictMap.put(dictionary.getDictCode(), dictionary);
     29             }
     30         }
     31         return rltDictMap;
     32     }
     33     
     34     /**
     35      * 获取字典项(内部字典项、外部字典项)
     36      * @param dictionary
     37      * @return
     38      */
     39     public List<DictionaryItem> getDictItems(final Dictionary dictionary){
     40         Object[] params = new Object[] {dictionary.getDictCode()};
     41         String querySql = "select dict_item_id dictItemId, dict_code dictCode, item_code itemCode, "
     42                 + " item_name itemName from ct_dictionary_item a where a.DICT_CODE = ?";
     43         
     44         if(dictionary.getDictType() == Constant.NUMBER_INTEGER_2) {
     45             querySql = dictionary.gettSource();
     46             params = null;
     47             String tParam = dictionary.gettParams() == null ? "" : dictionary.gettParams();
     48             Object[] _param = tParam.split(",");
     49             if(_param.length > 0 && StringUtil.isNotEmpty(String.valueOf(_param[0]))) {
     50                 params = _param;
     51             }
     52         }
     53         
     54         List<DictionaryItem> rItemList = jdbcTemplate.query(querySql, params, new RowMapper<DictionaryItem>() {
     55             @Override
     56             public DictionaryItem mapRow(ResultSet rs, int rowNum) throws SQLException {
     57                 DictionaryItem dictItem = new DictionaryItem();
     58                 if(dictionary.getDictType() == Constant.NUMBER_INTEGER_1) {
     59                     dictItem.setDictItemId(rs.getString("dictItemId"));
     60                     dictItem.setDictCode(rs.getString("dictCode"));
     61                     dictItem.setItemCode(rs.getString("itemCode"));
     62                     dictItem.setItemName(rs.getString("itemName"));
     63                 }else {
     64                     dictItem.setDictCode(dictionary.getDictCode());
     65                     dictItem.setItemCode(rs.getString(dictionary.getfCode()));
     66                     dictItem.setItemName(rs.getString(dictionary.getfName()));
     67                 }
     68                 return dictItem;
     69             }
     70             
     71         });
     72         
     73         return rItemList;
     74         
     75     }
     76     
     77     /**
     78      * 获取    字典对应的字典项
     79      * @return
     80      */
     81     public List<DictionaryItem> getDictResponseItems(String dictCode){
     82         if(StringUtil.isEmpty(dictCode))
     83             return null;
     84         List<DictionaryItem> dictionaryItems = getValidDictionaryItems();
     85         List<DictionaryItem> rltItems = new ArrayList<DictionaryItem>();
     86         for (DictionaryItem dictionaryItem : dictionaryItems) {
     87             if(dictCode.equals(dictionaryItem.getDictCode())) {
     88                 rltItems.add(dictionaryItem);
     89             }
     90         }
     91         return rltItems;
     92     }
     93     
     94     /**
     95      * 获取    所有有效的字典
     96      * @return
     97      */
     98     public List<Dictionary> getValidDictionarys(){
     99         List<Dictionary> dictionarys = cacheManager.get(Dictionary.class.getName(), DICTIONARYS_CACHE_KEY);
    100         if(dictionarys == null) {
    101             dictionarys = dictionaryMapper.getValidDictionarys();
    102             cacheManager.put(Dictionary.class.getName(), DICTIONARYS_CACHE_KEY, dictionarys);
    103         }
    104         return dictionarys;
    105     }
    106     
    107     /**
    108      * 获取    所有有效的字典项
    109      * @return
    110      */
    111     public List<DictionaryItem> getValidDictionaryItems(){
    112         List<DictionaryItem> dictionaryItems = cacheManager.get(DictionaryItem.class.getName(), DICTIONARY_ITEMS_CACKE_KEY);
    113         if(dictionaryItems == null) {
    114             dictionaryItems = dictionaryItemMapper.getValidDictionaryItems();
    115             cacheManager.put(DictionaryItem.class.getName(), DICTIONARY_ITEMS_CACKE_KEY, dictionaryItems);
    116         }
    117         return dictionaryItems;
    118     }
    119 }
  • 相关阅读:
    在WPF中应用弱事件模式
    MSTest DeploymentItemAttribute
    delegate, event
    zookeeper 开机启动197
    centos 7 安装solr7.3.0 配置mysql197
    solr7.4 centos7安装197
    centos 查看mysql数据库命令197
    bootstrapValidator验证197
    idea快捷键197
    sun.misc.Unsafe.park(Native Method)197
  • 原文地址:https://www.cnblogs.com/king-brook/p/9492337.html
Copyright © 2011-2022 走看看