关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » JAVA »吐槽一下J2Cache

    吐槽一下J2Cache

    2015-03-24 00:00:00 出处:张志敏的技术专栏
    分享

    槽点一:集成方式采用ANT

    工程还是传统的工程,集成还在用的ant,当然ant来做没有什么不可以,但是作为OSC这么高大上的作者拿出的作品能不能槽点高一些?已经采用了Maven了,用Maven无法独立完成的意思么?

    槽点二:提交内容的不审慎

    居然把Eclipse的工程文件提交到配置库,难道不知道有N多种开发工具么?不知道Eclipse工程文件中有一些东西是与本机相关的么?这样冲突如何解决呢?难不成所有作者的工程环境全是一样的?

    槽点三:文件治理不够严谨

    在src/main/java中赫然有xml和properties文件存在,OMG,我们的节操还可以再低一点么?测试性的代码放在了main/java中。

    槽点四:架构设计比较乱

    在我看来,不管是Ehcache或者redis都是缓存的一个扩展,但是这些东西都被结结实实的依赖在框架的main主干中,Hibernate只是应用缓冲的一种应用场景,但是也赫然在工程结构当中,如果把J2Cache的缓冲实现扩展N种,再把J2Cache的应用推广M种,我们就欣然看到在J2Cache当中信赖了n+m种的依赖包们,我们的使用者应该怎么办呢?要么忍受利用J2Cache时带来的N多用不着的包,要么就要辛苦的去强制不依赖这些包,而这都要拜J2Cache所赐。

    槽点五:程序实现也有一些问题简单列列如下

    在RedisCacheProvider这个实现类中,就有如下问题(当然,如果非说它不是个问题,我也没有办法):

    	private static String host;
    	private static int port;
    	private static int timeout;
    	private static String password;
    	private static int database;

    这里声明了一堆的静态变量

    结果这些变量都仅在start方法中一个里面有用到,那又变成静态变量是什么意思?

    private static JedisPool pool;

    这里定义了JedisPool是个静态变量,也就意味着只能有一个实例,也就意味着如果你要开两个独立的Redis缓冲是不可行的了,如果你想在一个工程里连接两个Redis服务器–OMG,你还是死了这条心吧,除非你重写这个类。

    if(key instanceof Number)
    			return region + ":I:" + key;
    		else{
    			Class keyClass = key.getClass();
    			if(String.class.equals(keyClass) || StringBuffer.class.equals(keyClass) || StringBuilder.class.equals(keyClass))
    				return region + ":S:" + key;
    		}
    		return region + ":O:" + key;

    这里不断的有字符串相“+”,而且还是连加……..

    	public static void main(String[] args) {
    		RedisCache cache = new RedisCache("User");
    		System.out.println(cache.getKeyName("Hello"));
    		System.out.println(cache.getKeyName(2));
    		System.out.println(cache.getKeyName((byte)2));
    		System.out.println(cache.getKeyName(2L));
    	}

    这里还有这个,还能再任性一点么?

    	public Object get(Object key) throws CacheException {
    		Object obj = null;
    		boolean broken = false;
    		Jedis cache = RedisCacheProvider.getResource();
    		try {
    			if (null == key)
    				return null;
    			byte[] b = cache.get(getKeyName(key).getBytes());
    			if(b != null)
    				obj = SerializationUtils.deserialize(b);
    		} catch (Exception e) {
    			log.error("Error occured when get data from L2 cache", e);
    			broken = true;
    			if(e instanceof IOException || e instanceof NullPointerException)
    				evict(key);
    		} finally {
    			RedisCacheProvider.returnResource(cache, broken);
    		}
    		return obj;
    	}
    
    	@Override
    	public void put(Object key, Object value) throws CacheException {
    		if (value == null)
    			evict(key);
    		else {
    			boolean broken = false;
    			Jedis cache = RedisCacheProvider.getResource();
    			try {
    				cache.set(getKeyName(key).getBytes(), SerializationUtils.serialize(value));
    			} catch (Exception e) {
    				broken = true;
    				throw new CacheException(e);
    			} finally {
    				RedisCacheProvider.returnResource(cache, broken);
    			}
    		}
    	}

    这里是啥意思?当你拿到一个Cache对象,你每次添加或返回一个缓冲的值,用的居然不一定是一个Redis实例,好吧,我知道Redis的连接池还是比较快的?还是比较快就不花时间了么?

    if (value == null)
    			evict(key);

    Ok,这里表示,如果设置的值是null,就把这个值干掉,

    public void evict(List keys) throws CacheException {
    		if(keys == null || keys.size() == 0)
    			return ;
    		boolean broken = false;
    		Jedis cache = RedisCacheProvider.getResource();
    		try {
    			String[] okeys = new String[keys.size()];
    			for(int i=0;i<okeys.length;i++){
    				okeys[i] = getKeyName(keys.get(i));
    			}
    			cache.del(okeys);
    		} catch (Exception e) {
    			broken = true;
    			throw new CacheException(e);
    		} finally {
    			RedisCacheProvider.returnResource(cache, broken);
    		}
    	}

    但是关键是这个方法里面又去获得了一个新的Redis对象。

       public EhCache buildCache(String name, boolean autoCreate, CacheExpiredListener listener) throws CacheException {
        	EhCache ehcache = _CacheManager.get(name);
        	if(ehcache == null && autoCreate){
    		    try {
    	            synchronized(_CacheManager){
    	            	ehcache = _CacheManager.get(name);
    	            	if(ehcache == null){
    			            net.sf.ehcache.Cache cache = manager.getCache(name);
    			            if (cache == null) {
    			                log.warn("Could not find configuration [" + name + "]; using defaults.");
    			                manager.addCache(name);
    			                cache = manager.getCache(name);
    			                log.debug("started EHCache region: " + name);                
    			            }
    			            ehcache = new EhCache(cache, listener);
    			            _CacheManager.put(name, ehcache);
    	            	}
    	            }
    		    }
    	        catch (net.sf.ehcache.CacheException e) {
    	            throw new CacheException(e);
    	        }
        	}
            return ehcache;
        }

    这个方法写得实在是醉了,呵呵,太难看了。

    这里关键在于:如果autoCreate是个false,你永远拿到的是null。那么问题来了,如果autoCreate只能是true,这个参数还有意义么?

    再一个问题,如果返回一个null,让使用的同学们如何用?写成下面这个样子么??

    if(xxx!=null){

    doSomeThing….

    }

    忽然在net.oschina.j2cache中又发现一个类CacheTester.java

    总结一下:

    J2Cache比我想像中要小许多,简单易用,当然再注重一下细节就更好了。

    附:Tiny成员会出现请客的情况:

    System.out.print用在不应该出现的地方 不适当的使用main方法。 方法函数行数太长 圈复杂度太大–超过10 异常处理处理不好:应该有没有,不应该有有了,抓到异常没有说明也没有任何处理 造成Maven循环依赖了 已经测试完成的代码,出现导致整个系统崩溃的问题了 提交了编译通不过的代码到配置库的 提交了不应该提交的内容到配置库的 已修正Issue但是不在git上关闭的。 Sonar规则检查通过率85%以下的 悠然判定认为需要请客的

    Tiny的开源工路径在:http://git.oschina.net/tinyframework/tiny/ 欢迎前来点评吐槽

    文档路径:http://www.tinygroup.org/ 然后传送门-》Document

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    Edge浏览器百度被劫持/篡改怎么办,地址后边跟着尾巴#tn=68018901_7_oem_dg

    Google Chrome 在 iPhone 上新增了 Safari 数据导入选项

    Windows 11专业版 KMS工具激活产品密钥的方法

    DEDECMS安全策略官方出品

    Microsoft Text Input Application 可以关闭吗?

    新版本QQ如何关闭自带的浏览器?

    C++编程语言中continue的用法和功能,附举例示范代码

    c++ map 的数据结构、基本操作以及其在实际应用中的使用。

    C语言如何避免内存泄漏、缓冲区溢出、空指针解引用等常见的安全问题

    C语言中的break语句详解

    IT头条

    马斯克2026最新采访总结:2040年,全球机器人数量将突破100亿台

    23:52

    专家解读|规范人工智能前沿业态健康发展的新探索:解读《人工智能拟人化互动服务管理暂行办法》

    00:54

    用至强 6高存力搞定MoE卸载!

    17:53

    美国将允许英伟达向中国“经批准的客户”出售H200 GPU

    02:08

    苹果与微信就15%手续费达成一致?腾讯未置可否

    22:00

    技术热点

    PHP 和 Node.js 的10项对比挑战

    Javascript闭包深入解析及实现方法

    windows 7、windows 8.1手动增加右键菜单功能技巧

    MYSQL出错代码大汇总

    windows 7假死机怎么办 windows 7系统假死机的原因以及解决方法

    Ubuntu(Linux)下配置IP地址的方法

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。