本文不得转载。
一.AppFuse简介
Appfuse是一个开放源码的项目和应用程序,它由Matt Raible 开发,它继承了流行的Spring、Hibernate、ibatis、struts、Xdcolet、junit等基础框架,并提供了对Taperstry和JSF等的支持。在用AppFuse开发时,用户可以自由选择Struts、Spring MVC、Webwork、Taperstry和JSF这几个MVC框架。它采用测试驱动(TDD)的开发方式,使用JUnit测试各层。
它使用Ant来驱动测试、代码生成、编译和部署。在用AppFuse创建一个项目时,与大部分IDE提供的“new project”向导不同,它创建的项目最开始就包含很多的类和文件,这些文件用来实现特性。用AppFuse创建项目,减少了我们编写繁琐而枯燥的CRUD代码所需的大部分时间,提高了我们的编码效率。并且它提供了很多应用程序的一些特性:认证和授权、用户管理、密码提醒、登记和注册、URL重写、模块化布局等功能,进一步提高了我们的效率。
二.AppFuse安装
1. JDK的安装
下载并安装JDK1.5,并设定如下环境变量:
JAVA_HOME:jdk安装的路径,eg. C:\Program Files\Java\jdk 1.5.0
CLASSPATH:.;%JAVA_HOME%\lib
Path:在该变量中增加项:%JAVA_HOME%\bin
测试安装是否成功的方法:在命令行中输入:java –version,将输出JDK的版本信息。
2. ANT的安装
下载Ant并将其解压到某目录,eg. E:\apache-ant- 1.6.5 ,设置如下环境变量:
ANT_HOME:Ant的安装路径,eg. E:\apache-ant- 1.6.5
Path:在该变量中增加项:%ANT_HOME%\bin
测试安装是否成功的方法:在命令行中输入:ant –version,将输出Ant的版本信息。
注意:为了AppFuse的正常工作,还需要将junit.jar包拷贝到%ANT_HOME%/lib目录下。
3. Tomcat的安装
下载并安装Tomcat 5.0.28 到某目录,eg. E:\Tomcat5.0.28,设置如下的环境变量:
CATALINA_HOME:E:\Tomcat 5.0.28
Path:在该变量中增加项:%CATALINA_HOME %\bin
测试安装是否成功的方法:启动Tomcat后,在浏览器中输入如下地址:http://localhost:8080,将显示Tomcat页面。
4. mysql的安装
安装MySQL Server 5.0,设置字符集为UTF-8,设置如下环境变量:
MYSQL_HOME:MySQL的安装路径,eg. C:\Program Files\MySQL\MySQL Server 5.0
Path:在该变量中增加项:%MYSQL_HOME %\bin
5. AppFuse的安装
在https://appfuse.dev.java.net/下载Appfuse。笔者下载的是 1.9.4 版本。将其解压到某目录,eg. E:\appfuse。
修改文件database.properties.reference为database.properties,并去掉你不用的数据库的设置,保留你所使用的数据库,并设置连接地址,用户名和密码等信息。
三.用AppFuse构建项目
1. 建立新的项目(ant new)
在命令行中进入appfuse所在目录,输入ant new命令,系统显示如下信息:
E:\appfuse>ant new
Buildfile: build.xml
Trying to override old definition of datatype resources
……
[input] What would you like to name your application [myapp]? [myapp]
命令行提示输入应用程序的名称,例如输入testAppfuse,要注意项目名称不能使用"test"或者包含"appfuse"或者以数字开头,命令行显示如下语句提示输入数据库的名称:
[input] What would you like to name your database [mydb]? [mydb]
输入数据库名appfuse,命令行显示如下语句提示输入包名:
[input] What package name would you like to use [org.appfuse]? [org.appfuse]
输入包名org.amigo,命令行显示选择Web MVC框架:
[input] What web framework would you like to use [webwork,tapestry,spring,jsf,struts]? [struts]
输入选择的Web MVC框架struts,命令行显示如下:
[echo] Creating new application named 'testAppFuse'...
[copy] Copying 358 files to E:\testAppFuse
……
BUILD SUCCESSFUL
Total time: 10 minutes 12 seconds
在末尾可看到BUILD SUCCESSFUL字样,显示操作成功。在appfuse同级目录E:下,可看到新建的项目testAppFuse,在该目录下生成了项目源码。
2. 建立数据库与编译源码(ant setup)
进入在1中建立的项目目录E:\testAppFuse,运行ant setup,这一命令将会在MySql中创建前面指定的名称的数据库,并编译源码,打包发布到Tomcat中。
注意:AppFuse默认情况下认为数据库的root帐号密码为空,如果你给数据库设置了密码,需要修改根目录下的properties.xml文件。搜索属性名为database.admin.password的标签,将value改写为实际的数据库密码。
输入ant setup后,显示操作信息,末尾显示“BUILD SUCCESSFUL”表示操作成功。该操作成功后,将会看到数据库中新增了数据库appfuse,包含app_user,role和user_role三个表。在CATALINA_HOME\webapps下新增了一个项目:testAppFuse。启动Tomcat后,在浏览器中输入:http://localhost:8080/testAppFuse,可看到登录页面。
3.使用 AppGen生成CRUD相关代码(install-detailed)
AppGen 是AppFuse 中提供的一个基于 Ant 和 XDoclet 的代码生成工具。默认情况下,常见的 DAO 和管理器都可以允许我们对任何普通老式 Java 对象(POJO)进行 CRUD 操作,但是在 Web 层上这样做有些困难。
下面让我们看看AppGen是如何工作的。
1)首先在第二步中创建的数据库appfuse中创建friends表,建表语句如下:
create table friends ( address varchar(100) null, |
2)进入E:\testAppFuse\extras\appgen 目录,运行ant install-detailed,显示如下:
E:\testAppFuse\extras\appgen>ant install-detailed
Buildfile: build.xml
clean:
init:
[mkdir] Created dir: E:\testAppFuse\extras\appgen\build
……
[input] Would you like to generate code from a table or POJO? (table, pojo)
3)提示是从table还是从POJO产生代码,输入table,选择从table生成代码,屏幕输出如下:
[input] What is the name of your table (i.e. person)?
4)提示输入表名,输入刚才创建的表的名字friends,输出如下:
[input] What is the name, if any, of the module for your table (i.e. organiz
ation)?
5)提示输入表的模块的名字,若无,按Enter键,开始生成代码。操作成功后可看到项目下已经生成对friends表的CRUD代码。
6)要查看页面来观察结果,还需做如下操作:为 Hibernate 添加 Friend.hbm.xml 映射文件。方法如下:
将 Friend.hbm.xml 添加到E:\testAppFuse\src\dao\org\amigo\dao\hibernate下的applicationContext-hibernate.xml文件中,需修改sessionFactory bean:
< property name ="dataSource" ref ="dataSource" />
< property name ="mappingResources" >
< list >
< value > org/amigo/model/Friend.hbm.xml </ value > < value > org/amigo/model/Role.hbm.xml </ value >
< value > org/amigo/model/User.hbm.xml </ value >
</ list >
</ property >
……
</ bean >
7)运行 ant setup deploy
之后,我们可以在部署的应用程序中对 friends表执行 CRUD 操作,并且在friends表中,AppFuse已经为我们插入了测试数据。
四.AppFuse中的xdoclet
Xdoclet是一个自动生成代码的工具。它的任务就是Ant的自定义任务。Xdoclet与Ant紧密关联。它有两个重要的组件:即进行特殊标记的Java 源文件和预先定义的模板。
Apache Ant 在运行的时候控制着 XDoclet 的配置和操作。XDoclet 解析输入的 Java 源代码,并在内存中生成结构模型。模板引擎通过处理一组模板和标签处理器,生成输出文件。
1.进行特殊标记的Java源文件
AppGen生成的文件缺少hbm.xml、Action Form Bean、web.xml、struts-config.xml和validation.xml等文件,那这些文件是怎么生成的呢?
原来,这些文件都是在我们执行ant setup命令时build.xml使用xdoclet自动生成的。 甚至连数据库和表、表里的数据也可以自动生成。
XDoclet 对包含嵌入式 XDoclet 标签的输入 Java 源代码进行解析,并为代码建立非常详细的结构模型。结构模型中的每个元素都代表源代码中的一个 Java 结构。
查看User.java、Role.java以及Address.java发现,这些POJO文件中有很多注释,有@hibernate开头的,@struts开头的,这些都是xdoctlet的标签。AppFuse中主要用到的xdoclet标签如下:
1)@struts.form:用来生成Form Bean。
include-all="true":表示该POJO中每一个属性在Form Bean中都要有;
extends="BaseForm":表示生成的Form Bean文件要继承BaseForm;@struts.form-field:表示该属性要在FormBean中生成。如果我们要在FormBean中添加一些POJO没有的属性或方法怎么做呢?打开metadata\web文件夹,可以看到有一个xdoclet-UserForm.java文件,里面是User.java在生成Form Bean时新加入的代码,我们同样可以把我们自己在FormBean中增加的代码新建到一个xdoclet-POJOFrom.java文件中就好了。
2)@struts.validator:用来生成validation.xml文件。
type="required":表示该属性在表单中需要有必填的验证。validation还有一项配置是自定义的校验规则,使用正则表达式表示。metadata\web中有一个文件validation-global.xml,里面就有邮编等规则的配置。
3)@hibernate:用来生成hbm.xml文件。内容与hbm.xml基本一致。
4)@struts.action/@struts.action-forward:POJO不能生成struts-config.xml,这个标签是要写到Action中的。如果使用AppGen生成Action,你会看到@struts.action已经写好了,这个标签的作用就是生成当前Action在struts-config.xml中的映射代码,写法与struts-config.xml中一致,其实就是把xml中的配置移植到Action中。还有一个问题,如果我们要在struts-config.xml中进行与Action无关的全局的配置,如global-forwards呢?浏览metadata\web文件夹你会发现里面有多个xml文件,其中以global和struts开头的文件就是写这些配置的。build.xml在setup时会自动将这些文件联合Action中的注释生成一个完整的struts-config.xml文件。
接下来还有web.xml文件,它需要在metadata\web中配置。除了刚才提到的那些xml文件,剩下的基本都是用于配置web.xml的了。我们自定义的filter和listener是有具体类的,所以我们同样可以在这些filter和listener类中添加注释。
进行了所有配置后,运行ant setup,build.xml会生成对应的xml文件和form bean等,并在数据库中创建相应的表。
2.预先定义的模版
XDoclet使用代码模板来生成代码。模板(template)是你想生成文件的原型。模板里使用一些XML标签来指导模板引擎如何根据输入类以及它们的元数据来调整代码的生成。
模板包含文件和XML标签,生成输出文件时XML标签会被解析,然后生成文本并显示在XML标签所处的位置上。除了以xdt为命名空间打头的XML标签会被XDoclet引擎解析以外,其余的XML标签XDoclet会忽略不管。
AppFuse中用到很多预先定义的模版,例如,AppFuse中生成Action类的XDoclet模板,部分内容如下所示:
public ActionForward delete(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
throws Exception {
if (log.isDebugEnabled()) {
log.debug("Entering 'delete' method");
}
ActionMessages messages = new ActionMessages();
<XDtClass:className/>Form <XDtForm:classNameLower/>Form = (<XDtClass:className/>Form) form;
// Exceptions are caught by ActionExceptionHandler
Manager mgr = (Manager) getBean("manager");
mgr.removeObject(<XDtClass:className/>.class, new Long(<XDtForm:classNameLower/>Form.getId()));
messages.add(ActionMessages.GLOBAL_MESSAGE,
new ActionMessage("<XDtForm:classNameLower/>.deleted"));
// save messages in session, so they'll survive the redirect
saveMessages(request.getSession(), messages);
return search(mapping, form, request, response);
}
… …
}
在如上的模版中,可看到<XDtClass:className/>、<XDtForm:classNameLower/>等标签,在生成代码的时候,这些标签会被解析,解析后在这些位置会填上对应的代码。
五.总结
AppFuse是个大杂烩,在它里面有很多开源库,主要分类如下:
编译相关:Ant、Ant Contrib Tasks、Checkstyle、Java2Html、PMD 等
测试框架:DbUnit、jMock、JUnit 等
数据库驱动程序:MySQL 和 PostgreSQL
持久层框架:Hibernate 和 iBATIS
IoC、AOP 框架:Spring
Web MVC框架:JSF、Spring MVC、Struts、Tapestry 和 WebWork
安全:Acegi Security
除了这些库之外,AppFuse 还使用 Log4j 来记录日志,使用 Velocity 来构建 e-mail 和菜单模板等。
另外,AppFuse 并不会将我们限定到任何特定的 API 上。它只是简单地对可用的最佳开放源码解决方案重新进行打包和预先集成。AppFuse 中的代码可以处理这种集成,并实现了 AppFuse 的基本安全性和可用性特性。只要可能,就会减少代码,以便向 AppFuse 的依赖框架添加一个特性。
从本文可以看来,AppFuse通过减少编写CRUD代码的时间,大大提高了我们编码的效率,是我们开发项目时的好帮手。