首页 > 其他分享 >使用 AppFuse 的七个理由

使用 AppFuse 的七个理由

时间:2023-07-27 23:04:19浏览次数:35  
标签:七个 Web devworks echo 理由 mraible 测试 AppFuse


[url]http://www.ibm.com/developerworks/cn/java/j-appfuse/[/url]

使用 AppFuse 快速构建 J2EE 应用 [url]http://www.ibm.com/developerworks/cn/java/j-lo-appfuse/[/url]

AppFuse 是一个开放源码的项目和应用程序,它使用了在 Java 平台上构建的开放源码工具来帮助我们快速而高效地开发 Web 应用程序。我最初开发它是为了减少在为客户构建新 Web 应用程序时所花费的那些不必要的时间。从核心上来说,AppFuse 是一个项目骨架,类似于通过向导创建新 Web 项目时 IDE 所创建的东西。当我们使用 AppFuse 创建一个项目时,它会提示我们将使用开放源码框架,然后才创建项目。它使用 Ant 来驱动测试、代码生成、编译和部署。它提供了目录和包结构,以及开发基于 Java 语言的 Web 应用程序所需要的库。
与大部分 “new project” 向导不同,AppFuse 创建的项目从最开始就包含很多类和文件。这些文件用来实现特性,不过它们同时也会在您开发应用程序时被用作示例。通过使用 AppFuse 启动新项目,我们通常可以减少一到两周的开发时间。我们不用担心如何将开放源码框架配置在一起,因为这都已经完成了。我们的项目都已提前配置来与数据库进行交互,它会部署到应用服务器上,并对用户进行认证。我们不必实现安全特性,因为这都早已集成了。
当我最初开发 AppFuse 时,它只支持 Struts 和 Hibernate。经过几年的努力,我发现了比 Struts 更好的 Web 框架,因此我还添加了为这些 Web 框架使用的选项。现在,AppFuse 可以支持 Hibernate 或 iBATIS 作为持久性框架。对于 Web 框架来说,我们可以使用 JavaServer Faces(JSF)、Spring MVC、Struts、Tapestry 或 WebWork。
AppFuse 提供了很多应用程序需要的一些特性,包括:
认证和授权
用户管理
Remember Me(这会保存您的登录信息,这样就不用每次都再进行登录了)
密码提醒
登记和注册
SSL 转换
E-mail
URL 重写
皮肤
页面修饰
模板化布局
文件上载
这种 “开箱即用” 的功能是 AppFuse 与其他 CRUD 代 框架的区别之一(CRUD 取自创建、检索、更新 和删除 几个操作的英文首字母),包括 Ruby on Rails、Trails 和 Grails。上面提到的这些框架,以及 AppFuse,都让我们可以从数据库表或现有的模型对象中生成主页/细节页。
图 1 阐述了一个典型 AppFuse 应用程序的概念设计:

图 1. 典型的 AppFuse 应用程序
[img]http://www.ibm.com/developerworks/cn/java/j-appfuse/appfuse_application.gif[/img]

清单 1 给出了我们在创建 devworks 项目时所使用的命令行交互操作,同时还给出了所生成的结果。这个项目使用了 WebWork 作为自己的 Web 框架(请参考下面 参考资料 一节给出的链接)。

清单 1. 使用 AppFuse 创建新项目

alotta:~/dev/appfuse mraible$ ant new

Buildfile: build.xml

clean:

 [echo] Cleaning build and distribution directories


init:

new:

 [echo] 

 [echo] +-------------------------------------------------------------+

 [echo] | -- Welcome to the AppFuse New Application Wizard! -- |

 [echo] | |

 [echo] | To create a new application, please answer the following |

 [echo] | questions. |

 [echo] +-------------------------------------------------------------+


 [input] What would you like to name your application [myapp]?

devworks

 [input] What would you like to name your database [mydb]?

devworks

 [input] What package name would you like to use [org.appfuse]?

com.ibm

 [input] What web framework would you like to use [webwork,tapestry,spring,js

f,struts]?

webwork

 [echo] Creating new application named 'devworks'...

 [copy] Copying 359 files to /Users/mraible/Work/devworks

 [copy] Copying 181 files to /Users/mraible/Work/devworks/extras

 [copy] Copying 1 file to /Users/mraible/Work/devworks

 [copy] Copying 1 file to /Users/mraible/Work/devworks


install:

 [echo] Copying WebWork JARs to ../../lib

 [copy] Copying 6 files to /Users/mraible/Work/devworks/lib

 [echo] Adding WebWork entries to ../../lib.properties

 [echo] Adding WebWork classpath entries

 [echo] Removing Struts-specific JARs

 [delete] Deleting directory /Users/mraible/Work/devworks/lib/struts-1.2.9

 [delete] Deleting directory /Users/mraible/Work/devworks/lib/strutstest-2.1.3

 [echo] Deleting struts_form.xdt for XDoclet

 [delete] Deleting directory /Users/mraible/Work/devworks/metadata/templates

 [echo] Deleting Struts merge-files in metadata/web

 [delete] Deleting 7 files from /Users/mraible/Work/devworks/metadata/web

 [echo] Deleting unused Tag Libraries and Utilities

 [delete] Deleting 2 files from /Users/mraible/Work/devworks/src/web/org/appfu

se/webapp

 [echo] Modifying appgen for WebWork

 [copy] Copying 12 files to /Users/mraible/Work/devworks/extras/appgen

 [echo] Replacing source and test files

 [delete] Deleting directory /Users/mraible/Work/devworks/src/web/org/appfuse/

webapp/form

 [delete] Deleting directory /Users/mraible/Work/devworks/src/web/org/appfuse/

webapp/action

 [copy] Copying 13 files to /Users/mraible/Work/devworks/src

 [delete] Deleting directory /Users/mraible/Work/devworks/test/web/org/appfuse

/webapp/form

 [delete] Deleting directory /Users/mraible/Work/devworks/test/web/org/appfuse

/webapp/action

 [copy] Copying 5 files to /Users/mraible/Work/devworks/test

 [echo] Replacing web files (images, scripts, JSPs, etc.)

 [delete] Deleting 1 files from /Users/mraible/Work/devworks/web/scripts

 [copy] Copying 34 files to /Users/mraible/Work/devworks/web

 [delete] Deleting: /Users/mraible/Work/devworks/web/WEB-INF/validator-rules-c

ustom.xml

 [echo] Modifying Eclipse .classpath file

 [echo] Refactoring build.xml

 [echo] ----------------------------------------------

 [echo] NOTE: It's recommended you delete extras/webwork as you shouldn't ne

ed it anymore.

 [echo] ----------------------------------------------

 [echo] Repackaging info written to rename.log

 [echo] 

 [echo] +-------------------------------------------------------------+

 [echo] | -- Application created successfully! -- |

 [echo] | |

 [echo] | Now you should be able to cd to your application and run: |

 [echo] | > ant setup test-all |

 [echo] +-------------------------------------------------------------+


BUILD SUCCESSFUL

Total time: 15 seconds


在创建一个新项目之后,我们就得到了一个类似于图 2 所示的目录结构。Eclipse 和 Intellij IDEA 项目文件都是作为这个过程的一部分创建的。

图 2. 项目的目录结构
[img]http://www.ibm.com/developerworks/cn/java/j-appfuse/project_directory_structure.jpg[/img]

这个目录结构与 Sun 为 Java 2 Platform Enterprise Edition(J2EE)Web 应用程序推荐的目录结构非常类似。在 2.0 版本的 AppFuse 中,这个结构会变化成适合 Apache Maven 项目的标准目录结构(有关这两个目录介绍的内容,请参看 参考资料 中的链接)。AppFuse 还会从 Ant 迁移到 Maven 2 上,从而获得相关下载的能力和对生成 IDE 项目文件的支持。目前基于 Ant 的系统要求提交者维护项目文件,而 Maven 2 可以通过简单地使用项目的 pom.xml 文件生成 IDEA、Eclipse 和 NetBeans 项目文件。(这个文件位于您项目的根目录中,是使用 Maven 构建应用程序所需要的主要组件)。它与利用 Ant 所使用的 build.xml 文件非常类似。)
现在我们对 AppFuse 是什么已经有一点概念了,在本文剩下的部分中,我们将介绍使用 AppFuse 的 7 点理由。即使您选择不使用 AppFuse 来开始自己的项目,也会看到 AppFuse 可以为您提供很多样板代码,这些代码可以在基于 Java 语言的 Web 应用程序中使用。由于它是基于 Apache 许可证的,因此非常欢迎您在自己的应用程序中重用这些代码。


[color=red][b]理由 1:测试[/b][/color]
测试是在软件开发项目中很少被给予足够信任的一个环节。注意我并不是说在软件开发的一些刊物中没有得到足够的信任!很多文章和案例研究都给出了测试优先的开发方式和足够的测试覆盖面以提高软件的质量。然而,测试通常都被看作是一件只会延长项目开发时间的事情。实际上,如果我们使用测试优先的方法在编写代码之前就开始撰写测试用例,我相信我们可以发现这实际上会加速 开发速度。另外,测试优先也可以使维护和重用更加 容易。如果我们不编写代码来测试自己的代码,那么就需要手工对应用程序进行测试 —— 这通常效率都不高。自动化才是关键。
当我们首次开始使用 AppFuse 时,我们可能需要阅读这个项目 Web 站点上提供的快速入门指南和教程(请参看 参考资料 中的链接)。这些教程的编写就是为了您可以首先编写测试用例;它们直到编写接口和/或实现之后才能编译。如果您有些方面与我一样,就会在开始编写代码之前就已经编写好测试用例了;这是真正可以加速编写代码的惟一方式。如果您首先编写了代码的实现,通过某种方式验证它可以工作,那么您可能会对自己说,“哦,看起来不错 —— 谁需要测试呢?我还有更多的代码需要编写!”这种情况不幸的一面是您通常都会做一些事情 来测试自己的代码;您简单地跳过了可以自动化进行测试的地方。
AppFuse 的文档展示了如何测试应用程序的所有 层次。它从数据库层开始入手,使用了 DbUnit(请参看 参考资料)在运行测试之前提前使用数据来填充自己的数据库。在数据访问(DAO)层,它使用了 Spring 的 AbstractTransactionalDataSourceSpringContextTests 类(是的,这的确是一个类的名字!)来允许简单地加载 Spring 上下文文件。另外,这个类对每个 testXXX() 方法封装了一个事务,并当测试方法存在时进行回滚。这种特性使得测试 DAO 逻辑变得非常简单,并且不会对数据库中的数据造成影响。
在服务层,jMock (请参看 参考资料)用来编写那些可以消除 DAO 依赖的真正 单元测试。这允许进行验证业务逻辑正确的快速测试;我们不用担心底层的持久性逻辑。

在 Web 层,测试会验证操作(Struts/WebWork)、控件(Spring MVC)、页面(Tapestry)和管理 bean(JSF)如我们所期望的一样进行工作。Spring 的 spring-mock.jar 可以非常有用地用来测试所有这些框架,因为它包含了一个 Servlet API 的仿真实现。如果没有这个有用的库,那么测试 AppFuse 的 Web 框架就会变得非常困难。
UI 通常是开发 Web 应用程序过程中最为困难的一部分。它也是顾客最经常抱怨的地方 —— 这既是由于它并不是非常完美,也是由于它的工作方式与我们期望的并不一样。另外,没有什么会比在客户面前作演示的过程中看到看到异常堆栈更糟糕的了!您的应用程序可能会非常可怕,但是客户可能会要求您做到十分完美。永远不要让这种事情发生。Canoo WebTest 可以对 UI 进行测试。它使用了 HtmlUnit 来遍历测试 UI,验证所有的元素都存在,并可以填充表单的域,甚至可以验证一个假想的启用 Ajax 的 UI 与我们预期的工作方式一样。(有关 WebTest 和 HTMLUnit 的链接请参看 参考资料。)
为了进一步简化 Web 的测试,Cargo(请参看 参考资料)对 Tomcat 的启动和停止(分别在运行 WebTest 测试之前和之后)进行了自动化。

[color=red][b]理由 2:集成[/b][/color]
正如我在本文简介中提到的一样,很多开放源码库都已经预先集成到 AppFuse 中了。它们可以分为以下几类:
编译、报告和代码生成:Ant、Ant Contrib Tasks、Checkstyle、EMMA、Java2Html、PMD 和 Rename Packages
测试框架:DbUnit、Dumbster、jMock、JUnit 和 Canoo WebTest
数据库驱动程序:MySQL 和 PostgreSQL
持久性框架:Hibernate 和 iBATIS
IoC 框架:Spring
Web 框架:JSF、Spring MVC、Struts、Tapestry 和 WebWork
Web 服务:XFire
Web 工具:Clickstream、Display Tag、DWR、JSTL、SiteMesh、Struts Menu 和 URL Rewrite Filter
Security:Acegi Security
JavaScript 和 CSS:Scriptaculous、Prototype 和 Mike Stenhouse 的 CSS Framework
除了这些库之外,AppFuse 还使用 Log4j 来记录日志,使用 Velocity 来构建 e-mail 和菜单模板。Tomcat 可以支持最新的开发,我们可以使用 1.4 或 5 版本的 Java 平台来编译或构建程序。我们应该可以将 AppFuse 部署到任何 J2EE 1.3 兼容的应用服务器上;这已经经过了测试,我们知道它在所有主要版本的 J2EE 服务器和所有主要的 servlet 容器上都可以很好地工作。
图 3 给出了上面创建的 devworks 项目的 lib 目录。这个目录中的 lib.properties 文件控制了每个依赖性的版本号,这意味着我们可以简单地通过把这些包的新版本放到这个目录中并执行诸如 ant test-all -Dspring.version=2.0 之类的命令来测试这些包的新版本。

图 3. 项目依赖性
[img]http://www.ibm.com/developerworks/cn/java/j-appfuse/project_lib_directory.jpg[/img]

预先集成这些开放源码库可以在项目之初极大地提高生产效率。尽管我们可以找到很多文档介绍如何集成这些库,但是定制工作示例并简单地使用它来开发应用程序要更加简单。
除了可以简化 Web 应用程序的开发之外,AppFuse 让我们还可以将 Web 服务简单地集成到自己的项目中。尽管 XFire 也在 AppFuse 下载中一起提供了,不过如果我们希望,也可以自己集成 Apache Axis(请参看 参考资料 中有关 Axis 集成的教程)。另外,Spring 框架和 XFire 可以一起将服务层作为 Web 服务非常简单地呈现出来,这就为我们提供了开发面向服务架构的能力。
另外,AppFuse 并不会将我们限定到任何特定的 API 上。它只是简单地对可用的最佳开放源码解决方案重新进行打包和预先集成。AppFuse 中的代码可以处理这种集成,并实现了 AppFuse 的基本安全性和可用性特性。只要可能,就会减少代码,以便向 AppFuse 的依赖框架添加一个特性。例如,AppFuse 自带的 Remember Me 和 SSL 切换特性最近就因为类似的特性而从 Acegi Security 中删除了。

[color=red][b]理由 3:自动化[/b][/color]
Ant 使得简化了从编译到构建再到部署的自动化过程。Ant 是 AppFuse 中的一等公民,这主要是因为我发现在命令行中执行操作比从 IDE 中更加简单。我们可以使用 Ant 实现编译、测试、部署和执行任何代码生成的任务。
尽管这种能力对于有些人来说非常重要,但是它并不适用于所有的人。很多 AppFuse 用户目前都使用 Eclipse 或 Intellij IDEA 来构建和测试自己的项目。在这些 IDE 中运行 Ant 的确可以工作,但是这样做的效率通常都不如使用 IDE 内置的 JUnit 支持来运行测试效率高。
幸运的是,AppFuse 支持在 IDE 中运行测试,不过管理这种特性对于 AppFuse 开发人员来说就变得非常困难了。最大的痛苦在于 XDoclet 用来生成 Hibernate 映射文件和 Web 框架所使用的一些工件(例如 ActionForms 和 Struts 使用的 struts-config.xml)。IDE 并不知道需要生成的代码,除非我们配置使用 Ant 来编译它们,或者安装了一些可以认识 XDoclet 的插件。
这种对知识的缺乏是 AppFuse 2.0 切换到 JDK 5 和 Maven 2 上的主要原因。JDK 5、注释和 Struts 2 将让我们可以摆脱 XDoclet。Maven 2 将使用这些生成的文件和动态类路径来生成 IDE 项目文件,这样对项目的管理就可以进行简化。目前基于 Ant 的编译系统已经为不同的层次生成了一些工件(包括 dao.jar、service.jar 和 webapp.war),因此切换到 Maven 的模型上应该是一个非常自然的调整。
除了 Ant 之外(它对于编译、测试、部署和报告具有丰富的支持),对于 CruiseControl 的支持也构建到了 AppFuse 中。CruiseControl 是一个 Continuous Integration 应用程序,让我们可以在源代码仓库中代码发生变化时自动运行所有的测试。extras/cruisecontrol 目录包含了我们为基于 AppFuse 的项目快速、简单地设置 Continuous Integration 时所需要的文件。
设置 Continuous Integration 是软件开发周期中我们首先要做的事情之一。它不但激发程序员去编写测试用例,而且还通过 “You broke the build!” 游戏促进了团队之间的合作和融合。


[color=red][b]理由 4:安全特性和可扩展性[/b][/color]
AppFuse 最初是作为我为 Apress 编写的书籍 Pro JSP 中示例应用程序的一部分开发的。这个示例应用程序展示了很多安全特性和用于简化 Struts 开发的特性。这个应用程序中的很多安全特性在 J2EE 的安全框图中都不存在。使用容器管理认证(CMA)的认证方法非常简单,但是 Remember Me、密码提示、SSL 切换、登记和用户管理等功能却都不存在。另外,基于角色的保护方法功能在非 EJB 环境中也是不可能的。
最初,AppFuse 使用自己的代码和用于 CMA 的解决方案完全实现了这些特性。我在 2004 年年初开始学习 Spring 时就听说过有关 Acegi Security 的知识。我对 Acegi 所需要的 XML 的行数(175)与 web.xml 中所需要的 CMA 的行数(20)进行了比较,很快就决定丢弃 Acegi 了,因为它太过复杂了。
一年半之后 —— 在为另外一本书 Spring Live 中编写了一章有关使用 Acegi Security 的内容之后 —— 我就改变了自己的想法。Acegi 的确(目前仍然)需要很多 XML,但是一旦我们理解了这一点,它实际上是相当简单的。当我们最终作出改变,使用 Acegi Security 的特性来全部取代 AppFuse 的特性之后,我们最终删除了大量的代码。类之上的类都已经没有了,“Acegi handles that now” 中消失的部分现在全部进入了 CVS 的 Attic 中了。
Acegi Security 是 J2EE 安全模型中曾经出现过的最好模型。它让我们可以实现很多有用的特性,这些特性在 Servlet API 的安全模型中都不存在:认证、授权、角色保护方法、Remember Me、密码加密、SSL 切换、用户切换和注销。它让我们还可以将用户证书存储到 XML 文件、数据库、LDAP 或单点登录系统(例如 Yale 的 Central Authentication Service (CAS) 或者 SiteMinder)中。
AppFuse 对很多与安全性相关的特性的实现从一开始都是非常优秀的。现在 AppFuse 使用了 Acegi Security,这些特性 —— 以及更多特性 —— 都非常容易实现。Acegi 有很多地方都可以进行扩充:这是它使用巨大的 XML 配置文件的原因。正如我们已经通过去年的课程对 Acegi 进行集成一样,我们已经发现对很多 bean 的定义进行定制可以更加紧密地与 AppFuse 建立联系。
Spring IoC 容器和 Acegi Security 所提供的简单开发、容易测试的代码和松耦合特性的组合是 AppFuse 是这么好的一种开发平台的主要原因。这些框架都是不可插入的,允许生成干净的可测试代码。AppFuse 集成了很多开放源码项目,依赖注入允许对应用程序层进行简单的集成。


[color=red][b]理由 5:使用 AppGen 生成代码[/b][/color]
有些人会将代码生成称为代码气味的散播(code smell)。在他们的观点中,如果我们需要生成代码,那么很可能就会做一些错事。我倾向于这种确定自己代码使用的模式和自动化生成代码的能力应该称为代码香味的弥漫(code perfume)。如果我们正在编写类似的 DAO、管理器、操作或控件,并且不想为它们生成代码,那么这就需要根据代码的气味来生成代码。当然,当语言可以为我们提供可以简化任务的特性时,一切都是那么美好;不过代码生成通常都是一个必需 —— 通常其生产率也非常高 —— 的任务。
AppFuse 中提供了一个基于 Ant 和 XDoclet 的代码生成工具,名叫 AppGen。默认情况下,常见的 DAO 和管理器都可以允许我们对任何普通老式 Java 对象(POJO)进行 CRUD 操作,但是在 Web 层上这样做有些困难。AppGen 有几个特性可以用来执行以下任务:
(使用 Middlegen 和 Hibernate 工具)从数据库表中生成 POJO
从 POJO 生成 UI
为 DAO、管理器、操作/控制器和 UI 生成测试
在运行 AppGen 时,您会看到提示说 AppGen 要从数据库表或 POJO 中生成代码。如果在命令行中执行 ant install-detailed,AppGen 就会安装 POJO 特定的 DAO、管理器以及它们的测试。运行 ant install 会导致 Web 层的类重用通用的 DAO 和默认存在的管理器。
为了阐述 AppGen 是如何工作的,我们在 devworks MySQL 数据库中创建了如清单 2 所示的表:

清单 2. 创建一个名为 cat 的数据库表

create table cat (
cat_id int(8) auto_increment,
color varchar(20) not null,
name varchar(20) not null,
created_date datetime not null,
primary key (cat_id)
) type=InnoDB;

在 extras/appgen 目录中,运行 ant install-detailed。这个命令的输出结果对于本文来说实在太长了,不过我们在清单 3 中给出了第一部分的内容:

清单 3. 运行 AppGen 的 install-detailed 目标

$ ant install-detailed

Buildfile: build.xml


init:

 [mkdir] Created dir: /Users/mraible/Work/devworks/extras/appgen/build

 [echo] 

 [echo] +-------------------------------------------------------+

 [echo] | -- Welcome to the AppGen! -- |

 [echo] | |

 [echo] | Use the "install" target to use the generic DAO and |

 [echo] | Manager, or use "install-detailed" to general a DAO |

 [echo] | and Manager specifically for your model object. |

 [echo] +-------------------------------------------------------+


 [input] Would you like to generate code from a table or POJO? (table,pojo)

table

 [input] What is the name of your table (i.e. person)?

cat

 [input] What is the name, if any, of the module for your table (i.e. organization)?


 [echo] Running Middlegen to generate POJO...



要对 cat 表使用这个新生成的代码,我们需要修改 src/dao/com/ibm/dao/hibernate/applicationContext-hibernate.xml,来为 Hibernate 添加 Cat.hbm.xml 映射文件。清单 3 给出了我们修改后的 sessionFactory bean 的样子:

清单 4. 将 Cat.hbm.xml 添加到 sessionFactory bean 中

<bean id="sessionFactory" class="...">

 <property name="dataSource" ref="dataSource"/>

 <property name="mappingResources">

 <list>

 <value>com/ibm/model/Role.hbm.xml</value>

 <value>com/ibm/model/User.hbm.xml</value>

 <value>com/ibm/model/Cat.hbm.xml</value>

 </list>

 </property>

 ...

</bean>



在运行 ant setup deploy 之后,我们就应该可以在部署的应用程序中对 cat 表执行 CRUD 操作了:

图 4. Cat 列表
[img]http://www.ibm.com/developerworks/cn/java/j-appfuse/cat_list.jpg[/img]


图 5. Cat 表单
[img]http://www.ibm.com/developerworks/cn/java/j-appfuse/cat_detail.jpg[/img]

我们在上面的屏幕快照中看到的记录都是作为代码生成的一部分创建的,因此现在就有测试数据了。


[color=red][b]理由 6:文档[/b][/color]
我们可以找到 AppFuse 各个风味的教程,并且它们都以 6 种不同的语言给出了:中文、德语、英语、韩语、葡萄牙语和西班牙语。使用风味(flavor) 一词,我的意思是不同框架的组合,例如 Spring MVC 加上 iBATIS、Spring MVC 加上 Hibernate 或 JSF 加上 Hibernate。使用这 5 种 Web 框架和两种持久框架,可以有好几种组合。有关它们的翻译,AppFuse 为自己的默认特性提供了 8 种翻译。可用语言包括中文、荷兰语、德语、英语、法语、意大利语、葡萄牙语和西班牙语。
除了核心教程之外,还添加了很多教程(请参看 参考资料) 来介绍与各种数据库、应用服务器和其他开放源码技术(包括 JasperReports、Lucene、Eclipse、Drools、Axis 和 DWR)的集成。


[color=red][b]理由 7:社区[/b][/color]
Apache 软件基金会对于开放源码有一个有趣的看法。它对围绕开放源码项目开发一个开放源码社区最感兴趣。它的成员相信如果社区非常强大,那么产生高质量的代码就是一个自然的过程。下面的内容引自 Apache 主页:
“我们认为自己不仅仅是一组共享服务器的项目,而且是一个开发人员和用户的社区。”
AppFuse 社区从 2003 年作为 SourceForge 上的一个项目(是 struts.sf.net 的一部分)启动以来,已经获得了极大的增长。通过在 2004 年 3 月转换到 java.net 上之后,它已经成为这里一个非常流行的项目,从 2005 年 1 月到 3 月成为访问量最多的一个项目。目前它仍然是一个非常流行的项目(有关 java.net 项目统计信息的链接,请参看 参考资料),不过在这个站点上它正在让位于 Sun 赞助的很多项目。
在 2004 年年末,Nathan Anderson 成为继我之后第一个提交者。此后有很多人都加入了进来,包括 Ben Gill、David Carter、Mika G?ckel、Sanjiv Jivan 和 Thomas Gaudin。很多现有的提交者都已经通过各种方式作出了自己的贡献,他们都帮助 AppFuse 社区成为一个迅速变化并且非常有趣的地方。
邮件列表非常友好,我们试图维护这样一条承诺 “没有问题是没有人理会的问题”。我们的邮件列表归档文件中惟一一条 “RTFM” 是从用户那里发出的,而不是从开发者那里发出的。我们绝对信奉 Apache 开放源码社区的哲学。引用我最好的朋友 Bruce Snyder 的一句话,“我们为代码而来,为人们而留下”。目前,大部分开发者都是用户,我们通常都喜欢有一段美妙的时间。另外,大部分文档都是由社区编写的;因此,这个社区的知识是非常渊博的。


[color=red][b]结束语[/b][/color]
我们应该尝试使用 AppFuse 进行开发,这是因为它允许我们简单地进行测试、集成、自动化,并可以安全地生成 Web 应用程序。其文档非常丰富,社区也非常友好。随着其支撑框架越来越好,AppFuse 也将不断改进。
从 AppFuse 2.0 开始,我们计划迁移到 JDK 5(仍然支持部署到 1.4)和 Maven 2 上去。这些工具可以简化使用 AppFuse 的开发、安装和升级。我们计划充分利用 Maven 2 的功能来处理相关依赖性。我们将碰到诸如 appfuse-hibernate-2.0.jar 和 appfuse-jsf-2.0.jar 之类的工件。这些工件都可以在 pom.xml 文件中进行引用,它们负责提取其他相关依赖性。除了在自己的项目中使用 AppFuse 基类之外,我们还可以像普通的框架一样在 JAR 中对这些类简单地进行扩展,这应该会大大简化它的升级过程,并鼓励更多用户将自己希望的改进提交到这个项目中。
如果没有其他问题,使用 AppFuse 可以让您始终处于 Java Web 开发的技术前沿上 —— 就像我们一样!

标签:七个,Web,devworks,echo,理由,mraible,测试,AppFuse
From: https://blog.51cto.com/u_3871599/6875198

相关文章

  • 最高法-实际控制人确认债权的,若相对人有理由相信其系公司职务行为,则可以参照表见代理
    (2021)最高法民申4920号  清涧县华阳鸿基置地有限责任公司、湖南鹏华装饰设计工程有限责任公司等建设工程施工合同纠纷其他民事民事裁定书本院认为:本院认为,本案系当事人申请再审案件,应当围绕华阳公司主张的再审事由能否成立进行审查。根据华阳公司的再审申请理由,本案主要审查了......
  • 放弃使用forEach的理由
    js中Array的forEach有如下缺点1.不支持异步,内部用await无效2.无法中断,不支持break,continue3.跳过已删除和未初始化的项4.不能修改数组项替代方案1.map()、filter()、reduce()支持异步,for循环和forof都支持异步constpromises=arr.map(async(num)=>{constres......
  • 使用近10年,说说向大家推荐Linux系统的理由
    使用近10年,说说向大家推荐Linux系统的理由使用linux已经快十年了,一直想推荐身边的使用linux,但是一直没有分享。但是现在我想分享推荐了。下面我们一起聊聊为什么我向大家推荐linux。为什么现在我想推荐了呢?是因为我自认为相对于同龄人来说,我使用桌面版的时间算是挺长的了,而且我也......
  • 使用近10年,说说向大家推荐Linux系统的理由
    使用linux已经快十年了,一直想推荐身边的使用linux,但是一直没有分享。但是现在我想分享推荐了。下面我们一起聊聊为什么我向大家推荐linux。为什么现在我想推荐了呢?是因为我自认为相对于同龄人来说,我使用桌面版的时间算是挺长的了,而且我也想纠正一部分人不看好linux桌面版的这么......
  • 使用近10年,说说向大家推荐Linux系统的理由
    使用linux已经快十年了,一直想推荐身边的使用linux,但是一直没有分享。但是现在我想分享推荐了。下面我们一起聊聊为什么我向大家推荐linux。为什么现在我想推荐了呢?是因为我自认为相对于同龄人来说,我使用桌面版的时间算是挺长的了,而且我也想纠正一部分人不看好linux桌面版的这么......
  • 使用近10年,说说向大家推荐Linux系统的理由
    使用linux已经快十年了,一直想推荐身边的使用linux,但是一直没有分享。但是现在我想分享推荐了。下面我们一起聊聊为什么我向大家推荐linux。为什么现在我想推荐了呢?是因为我自认为相对于同龄人来说,我使用桌面版的时间算是挺长的了,而且我也想纠正一部分人不看好linux桌面版的这么......
  • 京东太狠:100W数据去重,用distinct还是group by,说说理由?
    文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录博客园版为您奉上珍贵的学习资源:免费赠送:《尼恩Java面试宝典》持续更新+史上最全+面试必备2000页+面试必备+大厂必备+涨薪必备免费赠送:《尼恩技术圣经+高并发系列PDF》,帮你实现技术自由,完成职业升级,薪......
  • linux 关于for循环七个实验
    1.  2.   3.      4. 5.    6.   7.  ......
  • 13-1 udp和internet层协议 13-2IP地址组成和分类13-4 网卡配置文件和命令 13-5 网络理
    一、查看当前机器广播的地址和mac[root@centos8~]#arp-n查看当前机器的广播地址[root@centos8~]#tcpdump-ieth0arp-nn抓包[root@centos8~]#ipaa10.0.0.100/24deveth0添加多网卡命令[root@centos8~]#arping10.0.0.100查看IP有没有被占用二、查看相关包有......
  • 一个人至少拥有一个梦想,有一个理由去坚强
     人生中总会有一段艰难的路,需要自己独自走完,没人帮助,没人陪伴,不必畏惧,昂头走过去就是了,经历所有的挫折与磨难,你会发现,自己远比想象中要强大得多。多走弯路,才会找到捷径,经历也是人生,修炼一颗强大的内心,做更好的自己!人生最遗憾的莫过于轻易地放弃了不该放弃的,固执地坚持了不该......