论坛首页 Java企业应用论坛

关于JAVA注解的一个梦想

浏览 9038 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-10-24  
引用
这几行是非常死的东西,除了key之外,到处都是一样,于是想到用SPRING的AOP注解来寻求解决方法,同时看了一些有关注解的文章,发现很难在 AOP中取得所需要的KEY,因为生成KEY的方法基本都不一样,目标方法参数的个数和未知的类型也导致难以统一生成KEY。自定义注解也不能直接实现在方法的前后进行拦截

   其实楼主的这个想法蛮不错的,不过有几个必须的前提,第一是生成key的行为描述(也就是方法)是已知的,包括参数个数、类型以及更重要的数据源(也就是每个参数的实际值是如何获取)等。如果上述问题解决(比如通过静态的键值生成方法或者当前服务类实现某个特殊的接口,并且参数可以识别,比如是对象类型加上对象id,每个对象有自己唯一识别的id等),那么完全可以结合annotation以及Aop在加上一点反射的应用,可以实现楼上的想法的。
0 请登录后投票
   发表时间:2009-10-24   最后修改:2009-10-24
楼主这个梦想,是可以在Spring里用AspectJ来实现滴。
而且基本上是无侵入的
0 请登录后投票
   发表时间:2009-10-24  
我在前几天写程序是遇到了这样一种情况,JVM内存不足的异常,我用了大概五个线程读取一个40M左右的文件时报的错,在网上查了一下,说JVM默认的内存空间是64M,俺对这个JVM也是不太了解,哪位仁兄给推荐一本专门针对JVM的书看看也好啊
0 请登录后投票
   发表时间:2009-10-24   最后修改:2009-10-24
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);  
}  

这个在spring 2.5里是可以实现的
简单实现:(英文不乍样,一些类名,及方法名拼写可能有错,相当于伪码吧)

先根据createKey方法不同,定义N个不同的annotation, 如:cacheAnnotation1, cacheAnnotation2....

新建N个aspect
@aspect
@component
class Advice{
@Resource *** cache  
@around("@annotation(anno) && args(username)")
public Object daoAroundAspect(ProceedJoinPoint pjp, String username, cacheAnnotation1 anno){
          //这里根据 anno不同,以及username生成一个key
        object = cache.get(key)
        if(object == null) object = pjp.proceed();
         
        if(object != null) cache.save(object);
        return object;
  }
}

0 请登录后投票
   发表时间:2009-10-24  
sword.cai 写道
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);  
}  

这个在spring 2.5里是可以实现的
简单实现:(英文不乍样,一些类名,及方法名拼写可能有错,相当于伪码吧)

先根据createKey方法不同,定义N个不同的annotation, 如:cacheAnnotation1, cacheAnnotation2....

新建N个aspect
@aspect
@component
class Advice{
@Resource *** cache  
@around("@annotation(anno) && args(username)")
public Object daoAroundAspect(ProceedJoinPoint pjp, String username, cacheAnnotation1 anno){
          //这里根据 anno不同,以及username生成一个key
        object = cache.get(key)
        if(object == null) object = pjp.proceed();
         
        if(object != null) cache.save(object);
        return object;
  }
}


凤舞凰扬 说得不错,我就是生成KEY的方法不确定,方法名和所需要的参数都不是确定的,所以才想将方法名和参数传到注解中...
sword.cai 说的意思是不同的方法要用不能的代理来拦截吧,这样不太好,如果为每一个差异都做一个这样的AOP,还不如直接在本方法里面写了,对吧?
0 请登录后投票
   发表时间:2009-10-24  
引用

凤舞凰扬 说得不错,我就是生成KEY的方法不确定,方法名和所需要的参数都不是确定的,所以才想将方法名和参数传到注解中...
sword.cai 说的意思是不同的方法要用不能的代理来拦截吧,这样不太好,如果为每一个差异都做一个这样的AOP,还不如直接在本方法里面写了,对吧?


上面没有说清楚,这里不是为每个dao做一个aop,应该 是为每个dao生成策略做一个aop,

可以通过ProceedingJoinPoint pjp.getTarget()不同来做key,这个target对为个dao应该肯定不同吧,而key生成策略就是根据传过来的username以及Target的通过何种方式处理了。这个方式有几个,就有几个advice
0 请登录后投票
   发表时间:2009-10-24  
sword.cai 写道
引用

凤舞凰扬 说得不错,我就是生成KEY的方法不确定,方法名和所需要的参数都不是确定的,所以才想将方法名和参数传到注解中...
sword.cai 说的意思是不同的方法要用不能的代理来拦截吧,这样不太好,如果为每一个差异都做一个这样的AOP,还不如直接在本方法里面写了,对吧?


上面没有说清楚,这里不是为每个dao做一个aop,应该 是为每个dao生成策略做一个aop,

可以通过ProceedingJoinPoint pjp.getTarget()不同来做key,这个target对为个dao应该肯定不同吧,而key生成策略就是根据传过来的username以及Target的通过何种方式处理了。这个方式有几个,就有几个advice

sword.cai说的办法还是比较可行的,可以通过给所有需要缓存操作的业务类定义一个统一的生成KEY的接口,参数是可变数组,如createKey(Object ...),这样在AOP中将所在参数传回给target.createKey()方法即可,但为什么我说比较可行呢,因为我考虑到不是所有的调用都来自于类外部,有一些可能来自于类内部方法的直接调用,这时AOP感觉不到了,这是其一;还有,有些业务类比较复杂,内部需要那几种缓存的KEY,这时代码可能就是首先一堆的if else 的类型判断了,感觉有些乱。
0 请登录后投票
   发表时间:2009-10-25  
wxq276 写道
我在前几天写程序是遇到了这样一种情况,JVM内存不足的异常,我用了大概五个线程读取一个40M左右的文件时报的错,在网上查了一下,说JVM默认的内存空间是64M,俺对这个JVM也是不太了解,哪位仁兄给推荐一本专门针对JVM的书看看也好啊

英文的话可以直接到sun网站看,中文:深入java虚拟机第二版,这个我才看了几章,东西比较老,不过有不少的东西还是有用的,翻译还算可以吧,文中把父类叫双亲,好久才缓过神来。中文更新的没找到。
0 请登录后投票
   发表时间:2009-10-25  
如果只有一个类只有一个这样的方法的话可以用
模板方法来处理可以吧。

父类

public List<T> find(Object... params){
       beforeFind();
       doFind();
       afterFind();
}
//子类实现即可
public List<T> doFind(Object... params){}

0 请登录后投票
   发表时间:2009-10-25  
那个注解特性也算是一个难得的好改进了
0 请登录后投票
论坛首页 Java企业应用版

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