在使用struts2进行功能开发时,我们经常碰到的问题就是如果这个类有很多个参数,这里就需要有很多个get/set方法.如果你发现你的一个action中很上百行的set/get方法,那无疑让人抓狂,因此会让真正的业务方法隐藏其中,不管是开发还是维护都难以查找.
从业务开发的角度,action中的方法只能够表现于与业务的一一对应,如果没有相应的业务,则不相关的方法都不应该出现在当前这个类中.只不过,我们使用了struts2,这就表示必须有比业务方法数大得多的set/get充斥其中.
本文即通过一种代码生成(或称之为代码改写)使得我们在开发的时候不需要编写相应的set/get,而在运行时自动产生这些方法,相应的问题就可以解决了.具体结果可参考如下:
public class UserAction { /** 表示要操作的用户信息 */ @SetAndGet(set=true,get=true) private String user; @SetAndGet(get=false) private long idx; }
在工程进行启动时,就即会相应的处理器自动处理相应的action,然后根据这些注解信息自动生成相应的set/get,这样即可以满足struts2的规范要求,又可以避免代码海洋,同时进行维护时也可以直接查找到相应的业务,直接查看字段信息,即可以了解这些属性有什么用(如用于数据返回(只需要get,或参数传递(需要set/get)).
Action类标记
首先,我们需要对要处理的类进行标记,并不能将所有的类都进行处理,这个问题不大.从项目角度上讲,所有action都继承于一个baseAction或@Action注解,都不是大的问题.
类查找和处理
这里需要查找到要处理的类,需要注意的是,我们不能够在处理时将其实例化.因此我们要重新修改这个类,即reGeneration,否则一旦被jvm加载,而这个类是不再可被修改了.这里我们使用了reflections这个类处理框架,用于查找我们所需要处理的类信息.通过 Store.getSubTypesOf可以获取指定类的所有子类信息,并且这些通过字符串来进行表示,即这些类还没有被classLoader加载.
接着,我们就需要对这些类进行处理了,这里使用了javassist进行处理,通过这个工具可以为我们的action增加相应的方法.
具体处理 增加set/get方法
在进行处理时,我们只需要对所有的field进行遍历,同时查找其之上的注解,然后根据注解的内容进行生成即可.相应的实现参考如下:
CtClass ctClass = classPool.get(className); CtField[] ctFields = ctClass.getDeclaredFields(); //对每个字段遍历 for(CtField ctField : ctFields) { SetAndGet setAndGet = (SetAndGet) ctField.getAnnotation(SetAndGet.class); if(setAndGet == null)//没有注解,表示是内部使用,忽略之 continue; if(set && !hasMethod(ctClass, setMethodName)) {//生成set方法 ctClass.addMethod( CtNewMethod.make(generateSetMethod(setMethodName, fieldName, fieldType), ctClass));//产生相应的set方法 }
至此,整个技术完毕.实际上也很简单,就是使用javassist修改相应的类,来达到节省代码的目的.
转载请标明出处:i flym
本文地址:https://www.iflym.com/index.php/code/201310140002.html
能否提供完整代码