View Javadoc
1   /**
2    * Copyright By Grandsoft Company Limited.  
3    * 2012-6-5 上午09:52:32
4    */
5   package gboat2.base.cache;
6   
7   import gboat2.base.bridge.GboatAppContext;
8   
9   import java.io.FileInputStream;
10  import java.io.IOException;
11  import java.io.InputStream;
12  import java.util.Properties;
13  
14  import org.apache.commons.io.IOUtils;
15  import org.slf4j.Logger;
16  import org.slf4j.LoggerFactory;
17  
18  import com.opensymphony.oscache.base.CacheEntry;
19  import com.opensymphony.oscache.base.NeedsRefreshException;
20  import com.opensymphony.oscache.general.GeneralCacheAdministrator;
21  
22  /**
23   * 
24   * gboat2 平台中缓存对象基类,目前封装的方法不包含集群功能。包含:添加、删除和读取。请不要在程序中手动调用 {@link #destroy()}
25   * 方法,因为该方法是为 oscache bundle 停止时预留的<br>
26   * 注意:缓存中目前放的对象是永远不过期的,往缓存中放的时候要注意,用过之后,记得清掉,不然会造成内存泄露,如果是长久不变参数,可以长久驻留内存.
27   * 
28   * @author zhangxj-a
29   * @since 1.0
30   * @date 2012-6-5
31   */
32  public class BaseCache {
33  
34      private static Logger logger = LoggerFactory.getLogger(BaseCache.class);
35  
36      /** 获得 webapproot */
37      public final static String WEB_APP_ROOT = GboatAppContext.getWebRootPath();
38  
39      /** OSCache 配置文件相对路径 GBOAT2_OSCHACHE_LOCATION */
40      public final static String GBOAT2_OSCHACHE_LOCATION = "WEB-INF/config/oscache.properties";
41  
42      public final static String LOCAL_OSCHACHE_LOCATION = "properties/oscache.properties";
43  
44      public static final String DEFAULT_KEY_PREFIX = "Gboat2";
45      
46      private GeneralCacheAdministrator generalCacheAdministrator;
47  
48      private int refreshPeriod;
49  
50      private String keyPrefix;
51      
52      protected BaseCache() {
53          this(CacheEntry.INDEFINITE_EXPIRY);
54      }
55      
56      protected BaseCache(int refreshPeriod) {
57          this(refreshPeriod, DEFAULT_KEY_PREFIX);
58      }
59      
60      /**
61       * 构造方法
62       * 
63       * @param refreshPeriod
64       * @param keyPrefix
65       */
66      protected BaseCache(int refreshPeriod, String keyPrefix) {
67          this.refreshPeriod = refreshPeriod;
68          this.keyPrefix = keyPrefix;
69          Properties oscache = this.loadProperties(getCachePropertiesPath());
70          generalCacheAdministrator = new GeneralCacheAdministrator(oscache);
71      }
72  
73      /**
74       * 添加被缓存的对象
75       * 
76       * @param catalog
77       * @param key
78       * @param value
79       */
80      public void put(String catalog, String key, Object value) {
81          this.generalCacheAdministrator.putInCache(this.keyPrefix + "_" + catalog + "_" + key, value);
82      }
83  
84      /**
85       * 删除被缓存对象
86       * 
87       * @param catalog
88       * @param key
89       */
90      public void remove(String catalog, String key) {
91          this.generalCacheAdministrator.removeEntry(this.keyPrefix + "_" + catalog + "_" + key);
92      }
93  
94      /**
95       * 获得被缓存的对象
96       * 
97       * @param catalog
98       * @param key
99       * @return
100      * @throws RuntimeException 如果在缓存中不再此key,则抛出一个运行时异常提醒用户
101      */
102     public Object get(String catalog, String key) {
103         try {
104             return this.generalCacheAdministrator.getFromCache(this.keyPrefix + "_" + catalog + "_" + key, refreshPeriod);
105         } catch (NeedsRefreshException e) {
106             this.generalCacheAdministrator.cancelUpdate(this.keyPrefix + "_" + catalog + "_" + key);
107             // logger.error("key为:"+key+"的对象不存在,请检查",e);
108             return null;
109         }
110     }
111 
112     /**
113      * Shuts down the cache administrator.
114      */
115     public void destroy() {
116         this.generalCacheAdministrator.destroy();
117     }
118 
119     private String getCachePropertiesPath() {
120         return WEB_APP_ROOT + GBOAT2_OSCHACHE_LOCATION;
121     }
122 
123     /**
124      * 采取两步策略:<br>
125      * 首先去 WEB-INF/config/ 目录下查找 oscache.properties 文件,<br>
126      * 如果不存在,尝试加载 bundle 内部的 oscache.properties 属性文件
127      * 
128      * @param path 路径
129      * @return 读取文件内容
130      * @throws IOException io异常
131      */
132     private Properties loadProperties(String path) {
133         Properties props = new Properties();
134         InputStream logStream = null;
135         try {
136             logStream = new FileInputStream(path);
137             props.load(logStream);
138       
139             logger.info("OSCache: Gboat2 uses Global oscache. properties file is {}", path);
140         } catch (IOException e) {
141             try {
142                 logStream = this.getClass().getClassLoader().getResourceAsStream(LOCAL_OSCHACHE_LOCATION);
143                 props.load(logStream);
144                 logger.info("OSCache: Gboat2 uses Part oscache.properties file in the directory of properties/ in Gboa2.cache bundle as OSCache default config");
145             } catch (IOException e2) {
146                 logger.warn(" Gboat2 OSCache: No properties file found in the classpath by filename : oscache.properties."
147                         + " Gboat2 will use OSCache default properties, to change this, please add oscache.properties file in the directory of WEB-INF/config/");
148             }
149         } finally {
150             IOUtils.closeQuietly(logStream);
151         }
152         return props;
153     }
154 
155 }