论坛首页 Java企业应用论坛

关于JAVA注解的一个梦想

浏览 8947 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-10-24   最后修改:2009-10-25
最近在做一个项目的时候,用到了业务自已的缓存,发现有很多这样的代码:
public List<User> findUsers(String userName){
Object result = getFromCache(createKey(userName));
if(result!=null){
     return result;
}
.....
result = userDAO.findData(userName);
putToCache(createKey(userName));
return result;
}

这几行是非常死的东西,除了key之外,到处都是一样,于是想到用SPRING的AOP注解来寻求解决方法,同时看了一些有关注解的文章,发现很难在AOP中取得所需要的KEY,因为生成KEY的方法基本都不一样,目标方法参数的个数和未知的类型也导致难以统一生成KEY。自定义注解也不能直接实现在方法的前后进行拦截,下面是我没有实现的想法:
private String createKey(String userName){
       return "user_List_Cache"+userName;
}

//注解的第一个参数是上面的方法,第二参数调用那个方法所需要的参数
//注解现在没有传递方法,也没法传递运行时的值--据我所知
@cache(keyMthod=createKey,keyPara=userName);
public List<User> findUsers(String userName){
//注解帮我在方法的前后进行调用注解类里的方法,我在注解类里写那死代码,
//这样这里就只需要写查询的逻辑,从数据库返回结果就行
......
return userDAO.findData(userName);
}


我的梦想:java注解类可以有方法实现,当上面的findUsers被执行时,注解类的某个方法会在方法执行前被调用,另一个方法会在之后被调用,且能方便的从当前运行环境中取得所需的对象和值。

提两个问题

1、我最上面的那段代码各位有什么更好的实现吗?请赐教
2、JAVA其实要支持这种注解也不难,为什么注解不做更强大一些,还是本来就可以,是我没发现?

补充一点,感谢很多朋友发表自已的意见,但有不少的朋友忽略我不能违背的一些条件:
1、使用SPRING的AOP意见,请考虑在类类内部调用时如何处理。
2、createKey方法的名字和参数不是固定的,每个业务类都可能不一样,而且有可能一个类有多个这样的方法。



欢迎讨论,但不要人身攻击......
   发表时间:2009-10-24  
更好的实现:
def find_users(name)
  cache[name] ||= User.find(name)
end

0 请登录后投票
   发表时间:2009-10-24  
一粒蛋 写道
更好的实现:
def find_users(name)
  cache[name] ||= User.find(name)
end


按你的说法,查询角色时,是不是也要这样?
def find_roles(name)  
  cache[name] ||= Role.find(name)  
end 
如果是这样,你只是少一两行代码,不是我想要的实现思路,我想法是在具实现中不出现这样的代码
0 请登录后投票
   发表时间:2009-10-24   最后修改:2009-10-24
你这个需要,可能用动态代理比 annotation 更容易 ……

继续跑题 …… 一次定义完所有 find_xxxs :(可能对于没接触过 ruby 的有点不好懂)
def method_missing(method, *params)
  if method.to_s =~ /find_(\w+)s/
    cache[params] ||= const_get($1.capitalize).find(*params) # params 可多个
  else
    raise 'method not found'
  end
end


或者
def self.cached *methods
  @old_m ||= {}
  methods.each {|m|
    @old_m[m] = method(m)
    define_method(m){|params|
      cache[params] ||= old_m[params]
    }
  }
end
# 现在可以方便的用一行定义哪些要 cache,哪些不要 cache:
cached :find_users, :find_roles
0 请登录后投票
   发表时间:2009-10-24  
一粒蛋 写道
一次定义完所有 find_xxxs :(可能对于没接触过 ruby 的有点不好懂)
def method_missing(method, name)
  if method.to_s =~ /find_(\w+)s/
    cache[name] ||= const_get($1.capitalize).find(name)
  else
    raise 'method not found'
  end
end

这就和JAVA代理是差不多吧,当参数不只一个,而且只是其中某一部份作为缓存的KEY时,每个方法是哪一部都不确定,用你的思路能实现吗?
0 请登录后投票
   发表时间:2009-10-24   最后修改:2009-10-24
因为出现的次数多,所以能省很多行。
老实说如果一共只省一两行,你改成 annotation 就是蛋疼。(啊!)

另外,万一写完发现更长更耗时间更不好改呢?……
我觉得批量替换更 KISS ……

/*xyz821*/Object result = getFromCache(key);  
if(result!=null){  
  return result;  
}


注:添上的注释 /*xyz821*/ 内容自定,作用是可以使批量替换不会误杀 …… 非常 stupid,不过很有效 ……

另外一个思路就是 AOP getFromCache(),(有时还能让编译器自动把 234 行的判断优化掉)。
不过我不喜欢 AOP,不想告诉你。
0 请登录后投票
   发表时间:2009-10-24  
一粒蛋 写道
因为出现的次数多,所以能省很多行。
老实说如果一共只省一两行,你改成 annotation 就是蛋疼。(啊!)

另外,万一写完发现更长更耗时间更不好改呢?……
我觉得批量替换更 KISS ……

/*xyz821*/Object result = getFromCache(key);  
if(result!=null){  
  return result;  
}


注:添上的注释 /*xyz821*/ 内容自定,作用是可以使批量替换不会误杀 …… 非常 stupid,不过很有效 ……

另外一个思路就是 AOP getFromCache(),(有时还能让编译器自动把 234 行的判断优化掉)。
不过我不喜欢 AOP,不想告诉你。

你建议我批量替换以前的代码?疯了...呵呵
AOP,这个我也用多了,呵呵,感觉你还不是很理解我想要的实现思路,始终说不到点子上。
0 请登录后投票
   发表时间:2009-10-24  
感觉…… 你已经打定主意了,并且认为自己的写法最好,发出来只是想寻求应声附和的……
0 请登录后投票
   发表时间:2009-10-24  
一粒蛋 写道
感觉…… 你已经打定主意了,并且认为自己的写法最好,发出来只是想寻求应声附和的……

其实我是想看到一些深入理JVM的人讲解一下,如果JDK要支持我这种做法,会不会很有难度,在方法连接时会不会有性能问题等,因为本人对JVM理解很浅薄。。。
0 请登录后投票
   发表时间:2009-10-24   最后修改:2009-10-24
撤哪去了。好好的JAVA主题,非要用个

def 

end
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics