站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2EE 专题通过XDoclet定制模板进行快速开发

通过XDoclet定制模板进行快速开发

摘要: Java正在因为许多原因成为Web发展的障碍,其中一个问题是代码行(LOC)。做同一件事情,Java的某一些参数需要其他语言的2倍的代码量。或许你也正在手工的为你的构架XML定义所有的条目,以此来节约时间, 我承认, 我正是这样。
通过XDoclet定制模板进行快速开发

作者:Jason Lee

译者:ginger547


版权声明:任何获得Matrix授权的网站,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明
作者:Jason Lee;ginger547
原文地址:http://www.onjava.com/pub/a/onjava/2005/05/04/xdoclet.html
中文地址:http://www.matrix.org.cn/resource/article/43/43960_XDoclet_Rails.html
关键词: XDoclet,Rails

最近与同是开发者的朋友一起,谈论各种各样Java的之外的构架。似乎有一些现象表明, Java正在因为许多原因成为Web发展的障碍,其中一个问题是代码行(LOC)。做同一件事情,Java的某一些参数需要其他语言的2倍的代码量,我个人以为LOC仅仅是一个问题,它让你把一些本不该花的时间都花在你本不该去做的事情上。例如,象手工编写你所有的Bean一样。 或许你也正在手工的为你的构架XML定义所有的条目,以此来节约时间, 我承认, 我正是这样。

不久之前我使用RubyOnRails,一个让我喜欢用它们的原因就是他们能很容易产生完全的代码,从简单的script到复杂的代码。 这让我考虑我当前的工作和编码期间我的有效情况是怎么样的。 “我做好了多少工作VS我花费多少时间”的思想在过去的数星期内不停的在我脑子里萦绕。虽然有各种框架帮助我们使工作变的容易一些—--比喻说在使用的Spring—--它一些时候看起来很笨重,为一个web应用程序做一个页面或者一个模块就需要很长的时间。因此在一些思考以后, 我决定了做一些东西。

我多年前已经知道XDoclet,并且在它首次出现的时候试用了它。但是我没有进行长期的考虑, 所以当时我还不是一个在代码生成方面的大拿。我想要了解事情到底是怎么工作的, 因此我花了大量时间手工编写任何代码,包括config文件和deployment文件。

然而,我今天发现代码生成的两个主要的益处:

1.你在想学什么东西的时候,它将是很有帮助的。比喻说,去年我想学Hibernate 的时候,我已经有了存在的表,不想再反复的测试它是怎么工作的了,我也不想花大量的时间来填写文档。使用一个方便的叫做Middlegen的工具,我只要告诉它查看我的数据库并且为我生成代码就可以了。现在,写一个mapping文件对我来说已经很容易了,可是Middlegen的帮助节省了我大量的时间并为我指明了方向。

2.在对你的工程有一个清晰的概念和一个结构甚至一个框架已经搭建起来后,接下来的事情将变的十分的乏味,手工的创建beans,controllers, services 和 DAO,每次都会有一些新的需求要被创建。理想的做法是,你也许会调用一些Ant任务,比喻说, gencontrollers或者genmodules 来生成合适的controller代码或者一个整个的包含你的beans, controllers, services和DAO的模块.

使用XDoclet 来减轻痛苦
基于过去的一些经验,我不敢确信XDoclet对我有多大的帮助。我想要寻找一个工具让我可以花最少的时间来生成最多的代码。我在XDoclet网站上看到的大部分的示例都是针对于EJB的生成的,其实这也是XDoclet设计的初衷。但是,情况是这样的,我的工程不含有任何的EJB代码,事实上Spring全部是关于POJO的东西,所以EJB方面的工具不是我需要的。同时,XDoclet不含有任何的Spring标签,所以我一直在寻找一个不同平常的什么东西。

最后我把目光投上了模板。模板是一种继承XDoclet功能来更好的满足你的代码生成要求的方法。例如,你有一个特殊类型的类,与XDoclet所支持的任何一种都很不同(在我看来是一些客户化的控制类),你就可以用XML文件来把你自己的模板加进去。理想化的,我只想定义一个含有最小量的属性并不但产生我的控制器代码而且另外的Spring所要求的XML文件。在实验了几次以后,我对结果很满意。下面就是加标注的假设的代码测试控制器类。长代码行以\分开。

TestController.java

1.      package com.mytest.account.controller;
2.
3. /**
4. * @mytest.controller mapping="/acct.ctrl"
5. * @mytest.controller actionmethod="create"
6. * @mytest.controller actionmethod="read"
7. * @mytest.controller actionmethod="update"
8. * @mytest.controller actionmethod="delete"
9. */
10. public class TestController {
11.
12. /**
13. * @mytest.controller property="privateView" \
propertyValue="priv1" propertyMethod="PrivateView"\
propertyType="String"
14. */
15. private String privateView = null;
16.
17. /**
18. * @mytest.controller property="publicView" \
propertyValue="priv2" propertyMethod="PublicView" \
propertyType="String"
19. */
20. public String publicView = null;
21. }


你首先看到的可能是客户化的命名空间@mytest.controller标签。这个是在生成我们类的不同部分时,XDoclet如何知道去查找什么。标签的位置十分的重要。一些在类关键字的上面一些在属性定义的下面。XDoclet根据不同位置的标签来生成在我们的模板中使用的类和属性对象。这是一个很重要的区别,我们将在接下来研究。

看一下上面的代码,我们将做下面的操作:
1.为SimpleUrlHandlerMapping建立一个Spring mapping入口,它将在一个叫做mytest-servlet.xml 文件中被描述(是Spring中与Struts中的struts-config.xml 类似的东西).

2.actionmethod 属性允许我们为一个控制器指定一个方法名,它是从Srping的MultiActionController 继承而来 (在Struts, 对应的是 DispatchAction)。在我们的例子中,将会有 CRUD (Create, Read, Update, Delete)这么几个方法名。 XDoclet将会重复的进行不同参数的相同方法名的方法,所以允许我们的模板输出N个方法。

3.property 标签 让我们 定义一个典型的Bean属性,像你通常在XDoclet中做的一样,因为我们在这里使用了一个定制的模板,我们增加了更多的属性。propertyValue 是为mytest-servlet.xml 中对应的属性所指定的值。对我们的定制的标签来说,我们正在为控制器类设置private的和public的JSP页面显示,我通常管它们叫privateView和publicView—一个是针对签发者的另一是针对每一个人的。propertyMethod 将为我们提供一种简单的方法来类指定这个属性属于那一个方法,而不用去跳过bean-method-naming的约束。propertyType 属性指定了我们将要为这个方法get/set什么类型的属性。

很有争议的是,我可能把所有的属性定义发在类的层次上而不是Field的层次上。这也未尝不可,但是这将为在模板上增加额外的代码来确定在产生一个方法的时候我使用了正确的属性,方法,类型。我感觉使用XDoclet的Field 类比往我的模板里增加复杂的代码要容易和迅速。

模板
好了,现在让我们开始干活吧。正像我前面提到的那样,我选择XDoclet来生成代码的原因是我将定义一套定制的模板(不是一些定制的类或者更多的代码)并使用XDoclet的XML标签来为我填充这些空白。下面所列就是我们想要生成的模板相应的部分。长代码已经被\ 分开。

MultiController.xdt

1.      package ;
2. import javax.servlet.http.HttpServletRequest;
3. import javax.servlet.http.HttpServletResponse;
4.
5. import org.apache.commons.logging.Log;
6. import org.apache.commons.logging.LogFactory;
7. import org.springframework.validation.BindException;
8. import org.springframework.web.servlet.ModelAndView;
9.
10. import com.mytest.system.spring.BaseController;
11.
12. /**
13. * MultiAction controller class for \
.
14. *
15. * @author
16. * @since
17. * @version $Id$
18. */
19. public class \
extends BaseController {
20.
21. // CUT AND PASTE THIS INTO THE mytest-servlet.xml \
FILE
22. //
23. //