关闭 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

    上一篇返回首页 下一篇

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

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    技术热点

    商业智能成CIO优先关注点 技术落地方显成效(1)

    用linux安装MySQL时产生问题破解

    JAVA中关于Map的九大问题

    windows 7旗舰版无法使用远程登录如何开启telnet服务

    Android View 事件分发机制详解

    MySQL用户变量的用法

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

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