EhCache实现OSGi缓存bundle

1888人阅读 评论(1) 收藏 举报

代码获取地址:我的github项目,MyCodes/OSGi_Ehcache_bundle目录

        本文以开源的EhCahe实现了一个简单的通用缓存bundle。

        虽然之前我有几篇博客设计到了OSGi框架,但是缺少一个详细的介绍,所以关于OSGi的相关资料,请参考链接 http://blog.csdn.net/abram163/article/details/2534646 里面搜集的资料还是比较好的。

         在准备缓存bundle的时候,我简单在网上搜了下JAVA缓存的开源实现,见 http://www.open-open.com/13.htm 。其中ehcache是一个纯Java的过程中缓存实现Hibernate2.1,Spring都支持EHcache嵌入。这里,我没有用到Hibernate或者Spring等框架,而是在Equinox这个OSGi框架中直接嵌入EhcacheAPI,提供出一个能调用put(key, value)和get(key)的服务bundle。当然,在测试的时候,你完全可以用纯java的形式写一下Ehcache的工程,再进行少量重构,改写成bundle形式。

         简单介绍下EhCache吧。其实除了作为bundle,我还为我们软件工程课上做论坛的组推荐用ehcache为热门帖子做缓存,因为ehcache很好上手。Ehcache是纯java的轻量级缓存,支持内存和硬盘缓存(在.xml配置),LFU,LRU的缓存实现方式也只要写在配置文件里即可。他的整体结构如下:


CacheManager


Cache                                          Cache

  

Element   Element    Element         Element    Element    Element


以下是.xml具体配置,defaultCache是默认cache,.xml文件允许用户配置自己需要的不同cache

        

    <ehcache>  
      
                    <diskStore path="java.io.tmpdir"/>  
      
                    <defaultCache  
                            maxElementsInMemory="10000"  
                            eternal="false"  
                            timeToIdleSeconds="120"  
                            timeToLiveSeconds="120"  
                            overflowToDisk="true"  
                            diskPersistent="false"  
                            diskExpiryThreadIntervalSeconds="120"  
                            memoryStoreEvictionPolicy="LRU"  
                            />  
      
                    <cache name="mycache"  
                           maxElementsInMemory="10000"  
                           eternal="false"      maxElementsOnDisk="1000"  
                           overflowToDisk="true"  
                           timeToIdleSeconds="300"  
                           timeToLiveSeconds="600"  
                           memoryStoreEvictionPolicy="LFU"  
                            />  
                              
    </ehcache>  

然后由配置好的.xml创建CacheManager,然后由CacheManager创建xml内的不同种类的cache,最后新建Element(存着键值对)添加到相应的cache内,即完成了最简单的get,put功能的缓存。比如:

 

     // 读取.xml配置文件,创建cachemanager
     CacheManager manager = new CacheManager(“XmlStringPath”);

     // 得到配置文件里的cache名字
     String names[] = manager.getCacheNames();

     // 创建你想要的cache
     Cache cache = manager.getCache(name[0]);

     // 以键值对的形式存入cache
     Element element = new Element(key, value); // Object, Object
     cache.put(element);

     // 从cache取出
     cache.get(key);

对xml中配置参数的几点说明:

·   Cache配置

·           name:Cache的唯一标识

·           maxElementsInMemory:内存中最大缓存对象数。

·           maxElementsOnDisk:磁盘中最大缓存对象数,若是0表示无穷大。

·           eternal:Element是否永久有效,一但设置了,timeout将不起作用。

·           overflowToDisk:配置此属性,当内存中Element数量达到maxElementsInMemory时,Ehcache将会Element写到磁盘中。

·           timeToIdleSeconds:设置Element在失效前的允许闲置时间。仅当element不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。

·           timeToLiveSeconds:设置Element在失效前允许存活时间。最大时间介于创建时间和失效时间之间。仅当element不是永久有效时使用,默认是0.,也就是element存活时间无穷大。

·           diskPersistent:是否缓存虚拟机重启期数据。(这个虚拟机是指什么虚拟机一直没看明白是什么,有高人还希望能指点一二)。

·           diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。

·           diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。

·           memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。这里比较遗憾,Ehcache并没有提供一个用户定制策略的接口,仅仅支持三种指定策略,感觉做的不够理想。


最后EhCache官网详细API:http://www.ehcache.org/documentation/apis/index

并附上我的bundle,测试运行正常(图片上传不了= =):



鉴于上传有问题,我还是附上关键代码:

CacheActivator.java

public class CacheActivator implements BundleActivator {

	private ServiceRegistration sr = null;
	
	
	public void start(BundleContext bundleContext) throws Exception {
		
//		CacheServiceImpl cs = new CacheServiceImpl();
//		cs.put("k1", null);
//		
		sr = bundleContext.registerService(CacheService.class.getName(), 
				new CacheServiceImpl(), null);
		
		System.out.println("Cache service starts...");
	}

	
	public void stop(BundleContext bundleContext) throws Exception {
		sr.unregister();
		System.out.println("Cache service stopped...");
	}

}

CacheService.java
public interface CacheService {
	
	// 以图书服务为例,存入书名和byte流信息
	void put(String resname, byte[] content);
	
	// 传入书名,获得byte流信息
	byte[] get(String resname);
}

CacheServiceImpl.java

public class CacheServiceImpl implements CacheService {
	
	// String fileName = "src/cache/mycache.xml";
	String fileName = "";

	
	CacheServiceImpl() throws IOException {
		// TODO Auto-generated constructor stub
//		this.copyConfigFileOut("mycache.xml"); // 构造时,在指定路径生成.xml,提供给CacheManager作配置文件
		fileName = "./src/cache/mycache.xml";

	}
	
	
	// .xml里除了default的cache, 还有一个自己配置的mycache
	
	
//	public static void copyConfigFileOut(String configFileName) throws IOException 
//	{   		
//		InputStream is = CacheServiceImpl.class.getResourceAsStream(configFileName);//"mycache.xml"); //要读取的文件		
//		
//		File file = new File("E:\\cacheXML");
//		file.mkdir();
//		
//		File localFile = new File("E:\\cacheXML\\"+configFileName);//要写入的文件
//		
//		if(!localFile.exists())
//			localFile.createNewFile();               
//		FileOutputStream fos = new FileOutputStream(localFile);   
//		DataOutputStream dos = new DataOutputStream (fos);			
//			
//		int c;//表示成功读了多少字节,下面这种while方法是读完剩余的整个文件,生成的文件会很大,不可采用,应采用 dest.write(value,0,valueLen);
//	  	while((c=is.read())!=-1)
//	  		dos.write(c);
//	  	
//		dos.close();
//		is.close();
//	}
	
	@Override
	public void put(String resname, byte[] content) {
		
		CacheManager manager = new CacheManager(fileName);
		String names[] = manager.getCacheNames();
		Cache cache = manager.getCache(names[0]);
		// 存入cache
		cache.put(new Element(resname, content));
		
		int disksize = cache.getDiskStoreSize();
		long memsize = cache.getMemoryStoreSize();
		
		manager.shutdown();
		System.out.println("Store into cache successfully...");
		
		System.out.println("The DiskStoreSize is " + disksize);
		System.out.println("The MemoryStoreSize is " + memsize);
	}

	@Override
	public byte[] get(String resname) {
		CacheManager manager = new CacheManager(fileName);
		String names[] = manager.getCacheNames();
		Cache cache = manager.getCache(names[0]);
		
		Element element = cache.get(resname);
		
		System.out.println("Get the cache data successfully...");
		
		manager.shutdown();
		return (byte[]) element.getValue();
		

	}
//	public static void main(String[] args) throws IOException {
//		// TODO Auto-generated method stub
//		CacheServiceImpl cs = new CacheServiceImpl();
//		byte[] b1 = null;
//		cs.put("k1", b1);
//		
//		
//	}
}

mycache.xml(同上)

    <ehcache>  
      
                    <diskStore path="java.io.tmpdir"/>  
      
                    <defaultCache  
                            maxElementsInMemory="10000"  
                            eternal="false"  
                            timeToIdleSeconds="120"  
                            timeToLiveSeconds="120"  
                            overflowToDisk="true"  
                            diskPersistent="false"  
                            diskExpiryThreadIntervalSeconds="120"  
                            memoryStoreEvictionPolicy="LRU"  
                            />  
      
                    <cache name="mycache"  
                           maxElementsInMemory="10000"  
                           eternal="false"      maxElementsOnDisk="1000"  
                           overflowToDisk="true"  
                           timeToIdleSeconds="300"  
                           timeToLiveSeconds="600"  
                           memoryStoreEvictionPolicy="LFU"  
                            />  
                              
    </ehcache>  

很简单,很好用吧~

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:711969次
    • 积分:9109
    • 等级:
    • 排名:第2030名
    • 原创:158篇
    • 转载:1篇
    • 译文:5篇
    • 评论:237条