锁定老帖子 主题:关于JAVA注解的一个梦想
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-10-24
引用 这几行是非常死的东西,除了key之外,到处都是一样,于是想到用SPRING的AOP注解来寻求解决方法,同时看了一些有关注解的文章,发现很难在 AOP中取得所需要的KEY,因为生成KEY的方法基本都不一样,目标方法参数的个数和未知的类型也导致难以统一生成KEY。自定义注解也不能直接实现在方法的前后进行拦截
其实楼主的这个想法蛮不错的,不过有几个必须的前提,第一是生成key的行为描述(也就是方法)是已知的,包括参数个数、类型以及更重要的数据源(也就是每个参数的实际值是如何获取)等。如果上述问题解决(比如通过静态的键值生成方法或者当前服务类实现某个特殊的接口,并且参数可以识别,比如是对象类型加上对象id,每个对象有自己唯一识别的id等),那么完全可以结合annotation以及Aop在加上一点反射的应用,可以实现楼上的想法的。 |
|
返回顶楼 | |
发表时间:2009-10-24
最后修改:2009-10-24
楼主这个梦想,是可以在Spring里用AspectJ来实现滴。
而且基本上是无侵入的 |
|
返回顶楼 | |
发表时间:2009-10-24
我在前几天写程序是遇到了这样一种情况,JVM内存不足的异常,我用了大概五个线程读取一个40M左右的文件时报的错,在网上查了一下,说JVM默认的内存空间是64M,俺对这个JVM也是不太了解,哪位仁兄给推荐一本专门针对JVM的书看看也好啊
|
|
返回顶楼 | |
发表时间: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; } } |
|
返回顶楼 | |
发表时间: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,还不如直接在本方法里面写了,对吧? |
|
返回顶楼 | |
发表时间:2009-10-24
引用 凤舞凰扬 说得不错,我就是生成KEY的方法不确定,方法名和所需要的参数都不是确定的,所以才想将方法名和参数传到注解中... sword.cai 说的意思是不同的方法要用不能的代理来拦截吧,这样不太好,如果为每一个差异都做一个这样的AOP,还不如直接在本方法里面写了,对吧? 上面没有说清楚,这里不是为每个dao做一个aop,应该 是为每个dao生成策略做一个aop, 可以通过ProceedingJoinPoint pjp.getTarget()不同来做key,这个target对为个dao应该肯定不同吧,而key生成策略就是根据传过来的username以及Target的通过何种方式处理了。这个方式有几个,就有几个advice |
|
返回顶楼 | |
发表时间: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 的类型判断了,感觉有些乱。 |
|
返回顶楼 | |
发表时间:2009-10-25
wxq276 写道 我在前几天写程序是遇到了这样一种情况,JVM内存不足的异常,我用了大概五个线程读取一个40M左右的文件时报的错,在网上查了一下,说JVM默认的内存空间是64M,俺对这个JVM也是不太了解,哪位仁兄给推荐一本专门针对JVM的书看看也好啊
英文的话可以直接到sun网站看,中文:深入java虚拟机第二版,这个我才看了几章,东西比较老,不过有不少的东西还是有用的,翻译还算可以吧,文中把父类叫双亲,好久才缓过神来。中文更新的没找到。 |
|
返回顶楼 | |
发表时间:2009-10-25
如果只有一个类只有一个这样的方法的话可以用
模板方法来处理可以吧。 父类 public List<T> find(Object... params){ beforeFind(); doFind(); afterFind(); } //子类实现即可 public List<T> doFind(Object... params){} |
|
返回顶楼 | |
发表时间:2009-10-25
那个注解特性也算是一个难得的好改进了
|
|
返回顶楼 | |