??xml version="1.0" encoding="utf-8" standalone="yes"?>2012网络捕鱼游戏下载http://www.oiklr.tw/alex/archive/2006/12/18/88560.htmlAlexAlexMon, 18 Dec 2006 07:38:00 GMThttp://www.oiklr.tw/alex/archive/2006/12/18/88560.htmlhttp://www.oiklr.tw/alex/comments/88560.htmlhttp://www.oiklr.tw/alex/archive/2006/12/18/88560.html#Feedback0http://www.oiklr.tw/alex/comments/commentRss/88560.htmlhttp://www.oiklr.tw/alex/services/trackbacks/88560.html
前言: 对于log4j虽然在用Q但是也存在一个疑问,怎么有的用apache的commons logging有的直接用log4j,下面的这文章解释了我的疑问.

转自 here

Apachel织开发了一套用于支持Logging的Log4JQJava 1.4版本也引入了一套内|的 Logging框架Q?font color="#ff0000">如果开发者想在这两套Loggingpȝ之间自由的切换,该怎么办呢Q答案就是,使用Commons Logging?/font> Commons Logging定义了一套抽象的Logging接口Q用户可以通过配置Qɘq些接口指向M一个已存在的Loggingpȝ?br />
•用抽象Logging接口
问题Q?br />你在~写一个可以重复用的库,需要写入Log信息Q但你不想你的Logging功能l定在Apache Log4J或者JDK 1.4 Logging框架上?br />解决ҎQ?br />

public static void main(StringQ] args) {//自己替换Q]

  System.setProperty("org.apache.commons.logging.Log",
      "org.apache.commons.logging.impl.Jdk14Logger");
  Log log = LogFactory.getLog("com.discursive.jccook.SomeApp");

  if (log.isTraceEnabled()) {
    log.trace("This is a trace message");
  }

  if (log.isDebugEnabled()) {
    log.debug("This is a debug message");
  }

  log.info("This is an informational message");
  log.warn("This is a warning");
  log.error("This is an error");
  log.fatal("This is fatal");

}


LogFactory.getLogҎ会根据底层环境返回一个适当的Log实现。如果用h指定一个具体的Loggingpȝ实现Q可以设|org.apache.commons.logging.Logpȝ属性。例如:
System.setProperty("org.apache.commons.logging.Log",
"org.apache.commons.logging.impl.Log4JLogger");
q样׃使用Log4J作ؓLoggingpȝ?br />org.apache.commons.logging.Log可以讑֮为:
•org.apache.commons.logging.impl.Log4JLogger  使用Log4J
•org.apache.commons.logging.impl.Jdk14Logger  使用JDK 1.4 Logging框架
•org.apache.commons.logging.impl.SimpleLog  使用Commons Logging内置的简单Log实现
其他Q?br />ȝ一下,Commons Logging会按照下列顺序来指定具体的Log实现?br />•如果定义了org.apache.commons.logging.Logpȝ参数Q实用指定的Logging实现?br />•如果在CLASSPATH里发CLog4JQ用Log4J?br />•如果用的是JDK1.4Q用JDK1.4内置的Logging框架?br />•如果都没有扑ֈQ则使用Commons Logging内置的简单Log实现?/font>

Alex 2006-12-18 15:38 发表评论
]]>
web开发的瑞士军刀 javawebpartshttp://www.oiklr.tw/alex/archive/2006/09/08/68600.htmlAlexAlexFri, 08 Sep 2006 13:18:00 GMThttp://www.oiklr.tw/alex/archive/2006/09/08/68600.htmlhttp://www.oiklr.tw/alex/comments/68600.htmlhttp://www.oiklr.tw/alex/archive/2006/09/08/68600.html#Feedback6http://www.oiklr.tw/alex/comments/commentRss/68600.htmlhttp://www.oiklr.tw/alex/services/trackbacks/68600.html阅读全文

Alex 2006-09-08 21:18 发表评论
]]>
[zt]使用 AppFuse 的七个理?/title><link>http://www.oiklr.tw/alex/archive/2006/09/04/67669.html</link><dc:creator>Alex</dc:creator><author>Alex</author><pubDate>Mon, 04 Sep 2006 12:34:00 GMT</pubDate><guid>http://www.oiklr.tw/alex/archive/2006/09/04/67669.html</guid><wfw:comment>http://www.oiklr.tw/alex/comments/67669.html</wfw:comment><comments>http://www.oiklr.tw/alex/archive/2006/09/04/67669.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.oiklr.tw/alex/comments/commentRss/67669.html</wfw:commentRss><trackback:ping>http://www.oiklr.tw/alex/services/trackbacks/67669.html</trackback:ping><description><![CDATA[ <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr valign="top"> <td width="100%"> <h1>使用 AppFuse 的七个理?/h1> <p id="subtitle"> <em>学习 Java 开放源码工?—?q用这些工h高生产效?/em> </p> <img alt="" src="http://www.ibm.com/i/c.gif" class="display-img" height="6" width="1" /> </td> <td class="no-print" width="192"> <br /> </td> </tr> </tbody> </table> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr valign="top"> <td width="10"> <img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="10" /> </td> <td width="100%"> <table class="no-print" align="right" border="0" cellpadding="0" cellspacing="0" width="160"> <tbody> <tr> <td width="10"> <img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="10" /> </td> </tr> </tbody> </table> <p>U别: 初</p> <p> <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html?S_TACT=105AGX52&S_CMP=techcsdn#author">Matt Raible</a> (<a href="mailto:mraible@virtuas.com?subject=%E4%BD%BF%E7%94%A8%20AppFuse%20%E7%9A%84%E4%B8%83%E4%B8%AA%E7%90%86%E7%94%B1&cc=jaloi@us.ibm.com">mraible@virtuas.com</a>), 开放源码实践先? Virtuas Open Source Solutions<br /></p> <p>2006 q? 8 ? 31 ?/p> <blockquote>开 始学习在 Java?q_上用诸?Spring、Hibernate ?MySQL 之类的开放源码工h可能非常困难。再加上 Ant ? MavenQ以及与 DWR 一L?AjaxQ还?Web 框架 —??JSFQ我们必ȝ大眼睛盯着如何配置应用E序。AppFuse 减少了集成开放源码项目的痛苦。它可以把测试变成一{公民,让我们可以从数据库表生成整个 UIQƈ使用 XFire 来支?Web 服务。另外,AppFuse 的社Z非常健全Q这是不?Web 框架用户可以一赯z相处的地方之一?/blockquote> <!--START RESERVED FOR FUTURE USE INCLUDE FILES--> <!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --> <!--END RESERVED FOR FUTURE USE INCLUDE FILES--> <p>AppFuse 是一个开放源码的目和应用程序,它用了?Java q_上构建的开放源码工h帮助我们快速而高效地开?Web 应用E序。我最初开发它是ؓ了减在为客h建新 Web 应用E序时所p的那些不必要的时间。从核心上来_AppFuse 是一个项目骨ӞcM于通过向导创徏?Web 目?IDE 所创徏的东ѝ当我们使用 AppFuse 创徏一个项目时Q它会提C我们将使用开放源码框Ӟ然后才创建项目。它使用 Ant 来驱动测试、代码生成、编译和部v。它提供了目录和包结构,以及开发基?Java 语言?Web 应用E序所需要的库?/p> <p>与大部分 “new project?向导不同QAppFuse 创徏的项目从最开始就包含很多cd文g。这些文件用来实现特性,不过它们同时也会在您开发应用程序时被用作示例。通过使用 AppFuse 启动新项目,我们通常可以减少一C周的开发时间。我们不用担心如何将开放源码框枉|在一P因ؓq都已经完成了。我们的目都已提前配置来与数据库进 行交互,它会部v到应用服务器上,q对用户q行认证。我们不必实现安全特性,因ؓq都早已集成了?/p> <p>当我最初开?AppFuse Ӟ它只支持 Struts ?Hibernate。经q几q的努力Q我发现了比 Struts 更好? Web 框架Q因此我q添加了?Web 框架使用的选项。现在,AppFuse 可以支持 Hibernate ?iBATIS 作ؓ持久性框架。对?Web 框架来说Q我们可以?JavaServer FacesQJSFQ、Spring MVC、Struts、Tapestry ?WebWork?/p> <p>AppFuse 提供了很多应用程序需要的一些特性,包括Q?/p> <ul> <li>认证和授?/li> <li>用户理</li> <li>Remember MeQ这会保存您的登录信息,q样׃用每ơ都再进行登录了Q?/li> <li>密码提醒</li> <li>登记和注?/li> <li>SSL 转换</li> <li>E-mail</li> <li>URL 重写</li> <li>皮肤</li> <li>面修饰</li> <li>模板化布局</li> <li>文g上蝲</li> </ul> <p>q种 “开即用?的功能是 AppFuse 与其?<i>CRUD ?/i> 框架的区别之一QCRUD 取自<i>创徏、检索、更?/i> ?i>删除</i> 几个操作的英文首字母Q,包括 Ruby on Rails、Trails ?Grails。上面提到的q些框架Q以?AppFuseQ都让我们可以从数据库表或现有的模型对象中生成主?l节c?/p> <p>?1 阐述了一个典?AppFuse 应用E序的概念设计:</p> <br /> <a name="fig1"> <b>?1. 典型?AppFuse 应用E序</b> </a> <br /> <img alt="典型?AppFuse 应用E序" src="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/appfuse_application.gif" height="547" width="572" /> <br /> <p>清单 1 l出了我们在创徏 <i>devworks</i> 目时所使用的命令行交互操作Q同时还l出了所生成的结果。这个项目用了 WebWork 作ؓ自己?Web 框架Q请参考下?<a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html?S_TACT=105AGX52&S_CMP=techcsdn#resources">参考资?/a> 一节给出的链接Q?/p> <br /> <a name="listing1"> <b>清单 1. 使用 AppFuse 创徏新项?/b> </a> <br /> <table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"> <tbody> <tr> <td> <code> </code> <pre class="section">alotta:~/dev/appfuse mraible$ ant new<br />Buildfile: build.xml<br /><br />clean:<br /> [echo] Cleaning build and distribution directories<br /><br />init:<br /><br />new:<br /> [echo] <br /> [echo] +-------------------------------------------------------------+<br /> [echo] | -- Welcome to the AppFuse New Application Wizard! -- |<br /> [echo] | |<br /> [echo] | To create a new application, please answer the following |<br /> [echo] | questions. |<br /> [echo] +-------------------------------------------------------------+<br /><br /> [input] What would you like to name your application [myapp]?<br />devworks<br /> [input] What would you like to name your database [mydb]?<br />devworks<br /> [input] What package name would you like to use [org.appfuse]?<br />com.ibm<br /> [input] What web framework would you like to use [webwork,tapestry,spring,js<br />f,struts]?<br />webwork<br /> [echo] Creating new application named 'devworks'...<br /> [copy] Copying 359 files to /Users/mraible/Work/devworks<br /> [copy] Copying 181 files to /Users/mraible/Work/devworks/extras<br /> [copy] Copying 1 file to /Users/mraible/Work/devworks<br /> [copy] Copying 1 file to /Users/mraible/Work/devworks<br /><br />install:<br /> [echo] Copying WebWork JARs to ../../lib<br /> [copy] Copying 6 files to /Users/mraible/Work/devworks/lib<br /> [echo] Adding WebWork entries to ../../lib.properties<br /> [echo] Adding WebWork classpath entries<br /> [echo] Removing Struts-specific JARs<br /> [delete] Deleting directory /Users/mraible/Work/devworks/lib/struts-1.2.9<br /> [delete] Deleting directory /Users/mraible/Work/devworks/lib/strutstest-2.1.3<br /> [echo] Deleting struts_form.xdt for XDoclet<br /> [delete] Deleting directory /Users/mraible/Work/devworks/metadata/templates<br /> [echo] Deleting Struts merge-files in metadata/web<br /> [delete] Deleting 7 files from /Users/mraible/Work/devworks/metadata/web<br /> [echo] Deleting unused Tag Libraries and Utilities<br /> [delete] Deleting 2 files from /Users/mraible/Work/devworks/src/web/org/appfu<br />se/webapp<br /> [echo] Modifying appgen for WebWork<br /> [copy] Copying 12 files to /Users/mraible/Work/devworks/extras/appgen<br /> [echo] Replacing source and test files<br /> [delete] Deleting directory /Users/mraible/Work/devworks/src/web/org/appfuse/<br />webapp/form<br /> [delete] Deleting directory /Users/mraible/Work/devworks/src/web/org/appfuse/<br />webapp/action<br /> [copy] Copying 13 files to /Users/mraible/Work/devworks/src<br /> [delete] Deleting directory /Users/mraible/Work/devworks/test/web/org/appfuse<br />/webapp/form<br /> [delete] Deleting directory /Users/mraible/Work/devworks/test/web/org/appfuse<br />/webapp/action<br /> [copy] Copying 5 files to /Users/mraible/Work/devworks/test<br /> [echo] Replacing web files (images, scripts, JSPs, etc.)<br /> [delete] Deleting 1 files from /Users/mraible/Work/devworks/web/scripts<br /> [copy] Copying 34 files to /Users/mraible/Work/devworks/web<br /> [delete] Deleting: /Users/mraible/Work/devworks/web/WEB-INF/validator-rules-c<br />ustom.xml<br /> [echo] Modifying Eclipse .classpath file<br /> [echo] Refactoring build.xml<br /> [echo] ----------------------------------------------<br /> [echo] NOTE: It's recommended you delete extras/webwork as you shouldn't ne<br />ed it anymore.<br /> [echo] ----------------------------------------------<br /> [echo] Repackaging info written to rename.log<br /> [echo] <br /> [echo] +-------------------------------------------------------------+<br /> [echo] | -- Application created successfully! -- |<br /> [echo] | |<br /> [echo] | Now you should be able to cd to your application and run: |<br /> [echo] | > ant setup test-all |<br /> [echo] +-------------------------------------------------------------+<br /><br />BUILD SUCCESSFUL<br />Total time: 15 seconds</pre> </td> </tr> </tbody> </table> <br /> <table align="right" border="0" cellpadding="0" cellspacing="0" width="40%"> <tbody> <tr> <td width="10"> <img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="10" /> </td> <td> <table border="1" cellpadding="5" cellspacing="0" width="100%"> <tbody> <tr> <td bgcolor="#eeeeee"> <a name="sidebar1"> <b>Z么?WebWorkQ?/b> </a> <br /> Struts C֌最q在热情地拥? WebWorkQ这U结合导致ؓ Java q_提供了一个非怼U的新 Web 框架QStruts 2。当ӞSpring MVC 是一个非怼U的基于请求的框架Q但是它不能?Struts 2 一h?JSF。基于内容的框架Q例?JSF ? TapestryQ也都很好,但是我发?WebWork 更ؓ直观Q更Ҏ使用Q更多有?Structs 2 ?JSF 的内容请参看 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html?S_TACT=105AGX52&S_CMP=techcsdn#resources">参考资?/a>Q? </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <p>在创Z个新目之后Q我们就得到了一个类g?2 所C的目录l构。Eclipse ?Intellij IDEA 目文g都是作ؓq个q程的一部分创徏的?/p> <br /> <a name="fig2"> <b>?2. 目的目录结?/b> </a> <br /> <img alt="目的目录结? src="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/project_directory_structure.jpg" height="366" width="173" /> <br /> <p>q个目录l构?Sun ?Java 2 Platform Enterprise EditionQJ2EEQWeb 应用E序推荐的目录结构非常类伹{在 2.0 版本?AppFuse 中,q个l构会变化成适合 Apache Maven 目的标准目录结构(有关q两个目录介l的内容Q请参看 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html?S_TACT=105AGX52&S_CMP=techcsdn#resources">参考资?/a> 中的链接Q。AppFuse q会?Ant q移?Maven 2 上,从而获得相关下载的能力和对生成 IDE 目文g的支持。目前基? Ant 的系l要求提交者维护项目文Ӟ?Maven 2 可以通过单地使用目?pom.xml 文g生成 IDEA、Eclipse ? NetBeans 目文g。(q个文g位于您项目的根目录中Q是使用 Maven 构徏应用E序所需要的主要lgQ。它与利?Ant 所使用? build.xml 文g非常cM。)</p> <p>现在我们?AppFuse 是什么已l有一Ҏ念了Q在本文剩下的部分中Q我们将介绍使用 AppFuse ?7 点理由。即使您选择不? AppFuse 来开始自q目Q也会看?AppFuse 可以为您提供很多h代码Q这些代码可以在Z Java 语言?Web 应用E序中用。由于它是基?Apache 许可证的Q因此非常欢q您在自q应用E序中重用这些代码?/p> <p> <a name="1"> <span class="atitle">理由 1Q测?/span> </a> </p> <p>试是在软g开发项目中很少被给予够信ȝ一个环节。注意我q不是说在Y件开发的一些刊物中没有得到_的信任!很多文章和案例研Il出了测? 优先的开发方式和_的测试覆盖面以提高Y件的质量。然而,试通常都被看作是一件只会g镉K目开发时间的事情。实际上Q如果我们用测试优先的Ҏ在编 写代码之前就开始撰写测试用例,我相信我们可以发现这实际上会<i>加?/i> 开发速度。另外,试优先也可以ɾl护和重?i>更加</i> Ҏ。如果我们不~写代码来测试自q代码Q那么就需要手工对应用E序q行试 —?q通常效率都不高。自动化才是关键?/p> <p>当我们首ơ开始?AppFuse Ӟ我们可能需要阅读这个项?Web 站点上提供的快速入门指南和教程Q请参看 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html?S_TACT=105AGX52&S_CMP=techcsdn#resources">参考资?/a> 中的链接Q。这些教E的~写是Z您可以首先编写测试用例;它们直到~写接口?或实C后才能编译。如果您有些斚w与我一P׃在开始编写代码之? 已l编写好试用例了;q是真正可以加速编写代码的惟一方式。如果您首先~写了代码的实现Q通过某种方式验证它可以工作,那么您可能会对自pQ“哦Q? 看v来不?—?谁需要测试呢Q我q有更多的代码需要编写!”这U情况不q的一面是您通常都会?i>一些事?/i> 来测试自q代码Q您单地跌了可以自动化q行试的地斏V?/p> <p>AppFuse 的文档展CZ如何试应用E序?i>所?/i> 层次。它从数据库层开始入手,使用?DbUnitQ请参看 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html?S_TACT=105AGX52&S_CMP=techcsdn#resources">参考资?/a>Q在q行试之前提前使用数据来填充自q数据库。在数据讉KQDAOQ层Q它使用?Spring ?<code>AbstractTransactionalDataSourceSpringContextTests</code> c(是的Q这的确是一个类的名字!Q来允许单地加蝲 Spring 上下文文件。另外,q个cd每个 <code>testXXX()</code> Ҏ装了一个事务,q当试Ҏ存在时进行回滚。这U特性得测?DAO 逻辑变得非常单,q且不会Ҏ据库中的数据造成影响?/p> <p>在服务层QjMock Q请参看 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html?S_TACT=105AGX52&S_CMP=techcsdn#resources">参考资?/a>Q用来编写那些可以消?DAO 依赖?i>真正</i> 单元试。这允许q行验证业务逻辑正确的快速测试;我们不用担心底层的持久性逻辑?/p> <table align="right" border="0" cellpadding="0" cellspacing="0" width="40%"> <tbody> <tr> <td width="10"> <img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="10" /> </td> <td> <table border="1" cellpadding="5" cellspacing="0" width="100%"> <tbody> <tr> <td bgcolor="#eeeeee"> <a name="sidebar2"> <b>HtmlUnit 支持</b> </a> <br /> HtmlUnit 团队?1.8 发行版中已经完成了相当多的工作来保包可以与行?Ajax 框架QPrototype ?ScriptaculousQ很好地工作? </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <p>?Web 层,试会验证操作(Struts/WebWorkQ、控ӞSpring MVCQ、页面(TapestryQ和理 beanQJSFQ如我们所期望的一栯行工作。Spring ?spring-mock.jar 可以非常有用地用来测试所有这些框Ӟ因ؓ它包含了一?Servlet API 的仿真实现。如果没有这个有用的库,那么试 AppFuse ? Web 框架׃变得非常困难?/p> <p>UI 通常是开?Web 应用E序q程中最为困隄一部分。它也是֮最l常抱怨的地方 —? q既是由于它q不是非常完,也是׃它的工作方式与我们期望的q不一栗另外,没有什么会比在客户面前作演C的q程中看到看到异常堆栈更p糕的了Q您? 应用E序可能会非常可怕,但是客户可能会要求您做到十分完美。永q不要让q种事情发生。Canoo WebTest 可以?UI q行试。它使用? HtmlUnit 来遍历测?UIQ验证所有的元素都存在,q可以填充表单的域,甚至可以验证一个假想的启用 Ajax ?UI 与我们预期的工作方式一栗(有关 WebTest ?HTMLUnit 的链接请参看 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html?S_TACT=105AGX52&S_CMP=techcsdn#resources">参考资?/a>。)</p> <p>Zq一步简?Web 的测试,CargoQ请参看 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html?S_TACT=105AGX52&S_CMP=techcsdn#resources">参考资?/a>Q对 Tomcat 的启动和停止Q分别在q行 WebTest 试之前和之后)q行了自动化?/p> <br /> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr> <td> <img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /> <br /> <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /> </td> </tr> </tbody> </table> <br /> <br /> <p> <a name="2"> <span class="atitle">理由 2Q集?/span> </a> </p> <p>正如我在本文介中提到的一P很多开放源码库都已l预先集成到 AppFuse 中了。它们可以分Z下几c: </p> <ul> <li> <b>~译、报告和代码生成Q?/b>Ant、Ant Contrib Tasks、Checkstyle、EMMA、Java2Html、PMD ?Rename Packages</li> <li> <b>试框架Q?/b>DbUnit、Dumbster、jMock、JUnit ?Canoo WebTest</li> <li> <b>数据库驱动程序:</b>MySQL ?PostgreSQL</li> <li> <b>持久性框Ӟ</b>Hibernate ?iBATIS</li> <li> <b>IoC 框架Q?/b>Spring</li> <li> <b>Web 框架Q?/b>JSF、Spring MVC、Struts、Tapestry ?WebWork</li> <li> <b>Web 服务Q?/b>XFire</li> <li> <b>Web 工具Q?/b>Clickstream、Display Tag、DWR、JSTL、SiteMesh、Struts Menu ?URL Rewrite Filter</li> <li> <b>SecurityQ?/b>Acegi Security</li> <li> <b>JavaScript ?CSSQ?/b>Scriptaculous、Prototype ?Mike Stenhouse ?CSS Framework</li> </ul> <p>除了q些库之外,AppFuse q?Log4j 来记录日志,使用 Velocity 来构?e-mail 和菜单模ѝTomcat 可以支持最新的开发,我们可以使用 1.4 ?5 版本?Java q_来编译或构徏E序。我们应该可以将 AppFuse 部vCQ?J2EE 1.3 兼容的应用服务器上;q已l经q了试Q我们知道它在所有主要版本的 J2EE 服务器和所有主要的 servlet 容器上都可以很好地工作?/p> <p>?3 l出了上面创建的 <i>devworks</i> 目?lib 目录。这个目录中?lib.properties 文g控制了每个依赖性的版本Pq意味着我们可以单地通过把这些包的新版本攑ֈq个目录中ƈ执行诸如 <code>ant test-all -Dspring.version=2.0</code> 之类的命令来试q些包的新版本?/p> <br /> <a name="fig3"> <b>?3. 目依赖?/b> </a> <br /> <img alt="AppFuse 目依赖? src="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/project_lib_directory.jpg" height="598" width="197" /> <br /> <p>预先集成q些开放源码库可以在项目之初极大地提高生效率。尽我们可以找到很多文档介l如何集成这些库Q但是定制工作示例ƈ单地使用它来开发应用程序要更加单?/p> <p>除了可以?Web 应用E序的开发之外,AppFuse 让我们还可以?Web 服务单地集成到自q目中。尽?XFire 也在 AppFuse 下蝲中一h供了Q不q如果我们希望,也可以自己集?Apache AxisQ请参看 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html?S_TACT=105AGX52&S_CMP=techcsdn#resources">参考资?/a> 中有?Axis 集成的教E)。另外,Spring 框架?XFire 可以一起将服务层作?Web 服务非常单地呈现出来Q这׃ؓ我们提供了开发面向服务架构的能力?/p> <p>另外QAppFuse q不会将我们限定CQ何特定的 API 上。它只是单地对可用的最佛_放源码解x案重新进行打包和预先集成。AppFuse 中的代码可以处理q种集成Qƈ实现?AppFuse 的基本安全性和可用性特性。只要可能,׃减少代码Q以便向 AppFuse 的依赖框架添加一个特性。例如,AppFuse 自带? Remember Me ?SSL 切换Ҏ最q就因ؓcM的特性而从 Acegi Security 中删除了?/p> <br /> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr> <td> <img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /> <br /> <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /> </td> </tr> </tbody> </table> <table class="no-print" align="right" cellpadding="0" cellspacing="0"> <tbody> <tr align="right"> <td> <img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /> <br /> <br /> </td> </tr> </tbody> </table> <br /> <br /> <p> <a name="3"> <span class="atitle">理由 3Q自动化</span> </a> </p> <p>Ant 使得化了从编译到构徏再到部v的自动化q程。Ant ?AppFuse 中的一{公民,q主要是因ؓ我发现在命o行中执行操作比从 IDE 中更加简单。我们可以?Ant 实现~译、测试、部|和执行M代码生成的Q务?/p> <p>管q种能力对于有些人来说非帔R要,但是它ƈ不适用于所有的人。很?AppFuse 用户目前都?Eclipse ?Intellij IDEA 来构建和试自己的项目。在q些 IDE 中运?Ant 的确可以工作Q但是这样做的效率通常都不如?IDE 内置?JUnit 支持来运行测试效率高?/p> <p>q运的是QAppFuse 支持?IDE 中运行测试,不过理q种Ҏ对?AppFuse 开发h员来说就变得非常困难了。最大的痛苦在于 XDoclet 用来生成 Hibernate 映射文g?Web 框架所使用的一些工Ӟ例如 ActionForms ?Struts 使用? struts-config.xmlQ。IDE q不知道需要生成的代码Q除非我们配|?Ant 来编译它们,或者安装了一些可以认? XDoclet 的插件?/p> <p>q种对知识的~Z?AppFuse 2.0 切换?JDK 5 ?Maven 2 上的主要原因。JDK 5、注释和 Struts 2 让我们可以摆脱 XDoclet。Maven 2 用这些生成的文g和动态类路径来生?IDE 目文gQ这样对目的管理就可以q行化。目前基?Ant 的编译系l已lؓ不同的层ơ生成了一些工Ӟ包括 dao.jar、service.jar ?webapp.warQ,因此切换?Maven 的模型上应该是一个非常自然的调整?/p> <p>除了 Ant 之外Q它对于~译、测试、部|和报告h丰富的支持)Q对?CruiseControl 的支持也构徏C AppFuse 中。CruiseControl 是一?Continuous Integration 应用E序Q让我们可以在源代码仓库中代码发生变化时自动q行所有的试。extras/cruisecontrol 目录包含了我们ؓZ AppFuse 的项目快速、简单地讄 Continuous Integration 时所需要的文g?/p> <p>讄 Continuous Integration 是Y件开发周期中我们首先要做的事情之一。它不但Ȁ发程序员ȝ写测试用例,而且q通过 “You broke the build!?游戏促进了团队之间的合作和融合?/p> <br /> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr> <td> <img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /> <br /> <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /> </td> </tr> </tbody> </table> <table class="no-print" align="right" cellpadding="0" cellspacing="0"> <tbody> <tr align="right"> <td> <img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /> <br /> <br /> </td> </tr> </tbody> </table> <br /> <br /> <p> <a name="4"> <span class="atitle">理由 4Q安全特性和可扩展?/span> </a> </p> <p>AppFuse 最初是作ؓ我ؓ Apress ~写的书c?<i>Pro JSP</i> 中示例应用程序的一部分开发的。这个示例应用程序展CZ很多安全Ҏ和用于?Struts 开发的Ҏ。这个应用程序中的很多安全特性在 J2EE 的安全框图中都不存在。用容器管理认证(CMAQ的认证Ҏ非常单,但是 Remember Me、密码提C、SSL 切换、登记和用户理{功能却都不存在。另外,Z角色的保护方法功能在?EJB 环境中也是不可能的?/p> <p>最初,AppFuse 使用自己的代码和用于 CMA 的解x案完全实Cq些Ҏ。我?2004 q年初开始学?Spring 时就听说q有?Acegi Security 的知识。我?Acegi 所需要的 XML 的行敎ͼ175Q与 web.xml 中所需要的 CMA 的行敎ͼ20Q进行了比较Q很快就军_丢弃 Acegi 了,因ؓ它太q复杂了?/p> <p>一q半之后 —?在ؓ另外一本书 <i>Spring Live</i> 中编写了一章有关?Acegi Security 的内容之?—?我就改变了自qx。Acegi <i>的确</i>Q目 前仍Ӟ需要很?XMLQ但是一旦我们理解了q一点,它实际上是相当简单的。当我们最l作出改变,使用 Acegi Security 的特性来全部取代 AppFuse 的特性之后,我们最l删除了大量的代码。类之上的类都已l没有了Q“Acegi handles that now?中消q部分现在全部q入?CVS ?Attic 中了?/p> <p>Acegi Security ?J2EE 安全模型中曾l出现过的最好模型。它让我们可以实现很多有用的Ҏ,q些Ҏ在 Servlet API 的安全模型中都不存在Q认证、授权、角色保护方法、Remember Me、密码加密、SSL 切换、用户切换和注销。它让我们还可以用戯书存储到 XML 文g、数据库、LDAP 或单点登录系l(例如 Yale ?Central Authentication Service (CAS) 或?SiteMinderQ中?/p> <p>AppFuse 对很多与安全性相关的Ҏ的实现从一开始都是非怼U的。现?AppFuse 使用?Acegi SecurityQ这些特?—?以及更多Ҏ?—?都非常容易实现。Acegi 有很多地斚w可以q行扩充Q这是它使用巨大?XML 配置文g的原因。正如我们已l通过d的课E对 Acegi q行集成一P我们已经发现对很?bean 的定义进行定制可以更加紧密地? AppFuse 建立联系?/p> <p>Spring IoC 容器?Acegi Security 所提供的简单开发、容易测试的代码和松耦合Ҏ的l合?AppFuse 是这么好的一U开发^台的主要原因。这些框枉是不可插入的Q允许生成干净的可试代码。AppFuse 集成了很多开放源码项目,依赖注入允许对应用程序层q行单的集成?/p> <br /> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr> <td> <img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /> <br /> <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /> </td> </tr> </tbody> </table> <table class="no-print" align="right" cellpadding="0" cellspacing="0"> <tbody> <tr align="right"> <td> <img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /> <br /> <br /> </td> </tr> </tbody> </table> <br /> <br /> <p> <a name="5"> <span class="atitle">理由 5Q?AppGen 生成代码</span> </a> </p> <p>有些Z代码生成称?i>代码气味的散播(code smellQ?/i>。在他们的观点中Q如果我们需要生成代码,那么很可能就会做一些错事。我們֐于这U确定自׃码用的模式和自动化生成代码的能力应该称?i>代码香味的I漫(code perfumeQ?/i>。如果我们正在编写类似的 DAO、管理器、操作或控gQƈ且不想ؓ它们生成代码Q那么这需要根据代码的气味来生成代码。当Ӟ当语a可以为我们提供可以简化Q务的Ҏ时Q一切都是那么美好;不过代码生成通常都是一个必需 —?通常其生产率也非帔R —?的Q务?/p> <p>AppFuse 中提供了一个基?Ant ?XDoclet 的代码生成工P名叫 <i>AppGen</i>。默认情况下Q常见的 DAO 和管理器都可以允许我们对M普通老式 Java 对象QPOJOQ进?CRUD 操作Q但是在 Web 层上q样做有些困难。AppGen 有几个特性可以用来执行以下Q务:</p> <ul> <li>Q?Middlegen ?Hibernate 工具Q从数据库表中生?POJO</li> <li>?POJO 生成 UI</li> <li>?DAO、管理器、操?控制器和 UI 生成试</li> </ul> <p>在运?AppGen Ӟ您会看到提示?AppGen 要从数据库表?POJO 中生成代码。如果在命o行中执行 <code>ant install-detailed</code>QAppGen ׃安装 POJO 特定?DAO、管理器以及它们的测试。运?<code>ant install</code> 会导?Web 层的c重用通用?DAO 和默认存在的理器?/p> <p>Z阐述 AppGen 是如何工作的Q我们在 <i>devworks</i> MySQL 数据库中创徏了如清单 2 所C的表:</p> <br /> <a name="listing2"> <b>清单 2. 创徏一个名?cat 的数据库?/b> </a> <br /> <table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"> <tbody> <tr> <td> <code> </code> <pre class="section"> create table cat (<br /> cat_id int(8) auto_increment,<br /> color varchar(20) not null,<br /> name varchar(20) not null,<br /> created_date datetime not null,<br /> primary key (cat_id)<br /> ) type=InnoDB;<br /></pre> </td> </tr> </tbody> </table> <br /> <p>?extras/appgen 目录中,q行 <code>ant install-detailed</code>。这个命令的输出l果对于本文来说实在太长了,不过我们在清?3 中给ZW一部分的内容:</p> <br /> <a name="listing3"> <b>清单 3. q行 AppGen ?install-detailed 目标</b> </a> <br /> <table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"> <tbody> <tr> <td> <code> </code> <pre class="section">$ ant install-detailed<br />Buildfile: build.xml<br /><br />init:<br /> [mkdir] Created dir: /Users/mraible/Work/devworks/extras/appgen/build<br /> [echo] <br /> [echo] +-------------------------------------------------------+<br /> [echo] | -- Welcome to the AppGen! -- |<br /> [echo] | |<br /> [echo] | Use the "install" target to use the generic DAO and |<br /> [echo] | Manager, or use "install-detailed" to general a DAO |<br /> [echo] | and Manager specifically for your model object. |<br /> [echo] +-------------------------------------------------------+<br /><br /> [input] Would you like to generate code from a table or POJO? (table,pojo)<br />table<br /> [input] What is the name of your table (i.e. person)?<br />cat<br /> [input] What is the name, if any, of the module for your table (i.e. organization)?<br /><br /> [echo] Running Middlegen to generate POJO...<br /></pre> </td> </tr> </tbody> </table> <br /> <p>要对 cat 表用这个新生成的代码,我们需要修? src/dao/com/ibm/dao/hibernate/applicationContext-hibernate.xmlQ来? Hibernate d Cat.hbm.xml 映射文g。清?3 l出了我们修改后?<code>sessionFactory</code> bean 的样子:</p> <br /> <a name="listing4"> <b>清单 4. ?Cat.hbm.xml d?sessionFactory bean ?/b> </a> <br /> <table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"> <tbody> <tr> <td> <code> </code> <pre class="section"> <bean id="sessionFactory" class="..."><br /> <property name="dataSource" ref="dataSource"/><br /> <property name="mappingResources"><br /> <list><br /> <value>com/ibm/model/Role.hbm.xml</value><br /> <value>com/ibm/model/User.hbm.xml</value><br /> <value>com/ibm/model/Cat.hbm.xml</value><br /> </list><br /> </property><br /> ...<br /></bean><br /></pre> </td> </tr> </tbody> </table> <br /> <p>在运?<code>ant setup deploy</code> 之后Q我们就应该可以在部|的应用E序中对 cat 表执?CRUD 操作了:</p> <br /> <a name="fig4"> <b>?4. Cat 列表</b> </a> <br /> <img alt="所生成的主屏幕" src="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/cat_list.jpg" height="379" width="572" /> <br /> <br /> <a name="fig5"> <b>?5. Cat 表单</b> </a> <br /> <img alt="所生成的详l屏q? src="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/cat_detail.jpg" height="379" width="572" /> <br /> <p>我们在上面的屏幕快照中看到的记录都是作ؓ代码生成的一部分创徏的,因此现在有试数据了?/p> <br /> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr> <td> <img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /> <br /> <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /> </td> </tr> </tbody> </table> <table class="no-print" align="right" cellpadding="0" cellspacing="0"> <tbody> <tr align="right"> <td> <img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /> <br /> <table border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td valign="middle"> <br /> </td> <td align="right" valign="top"> <br /> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> <p> <a name="6"> <span class="atitle">理由 6Q文?/span> </a> </p> <p>我们可以扑ֈ AppFuse 各个风味的教E,q且它们都以 6 U不同的语言l出了:中文、d语、英语、韩语、葡萄牙语和西班牙语。?i>风味QflavorQ?/i> 一词,我的意思是不同框架的组合,例如 Spring MVC 加上 iBATIS、Spring MVC 加上 Hibernate ?JSF 加上 Hibernate。用这 5 U?Web 框架和两U持久框Ӟ可以有好几种l合。有兛_们的译QAppFuse q默认Ҏ提供了 8 U翻译。可用语a包括中文、荷兰语、d语、英语、法语、意大利语、葡萄牙语和西班牙语?/p> <p>除了核心教程之外Q还d了很多教E(请参?<a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html?S_TACT=105AGX52&S_CMP=techcsdn#resources">参考资?/a>Q?来介l与各种数据库、应用服务器和其他开放源码技术(包括 JasperReports、Lucene、Eclipse、Drools、Axis ?DWRQ的集成?/p> <br /> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr> <td> <img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /> <br /> <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /> </td> </tr> </tbody> </table> <br /> <br /> <p> <a name="7"> <span class="atitle">理由 7Q社?/span> </a> </p> <p>Apache 软g基金会对于开放源码有一个有的看法。它对围l开放源码项目开发一个开放源码社区最感兴。它的成员相信如果社区非常强大,那么产生高质量的代码是一个自然的q程。下面的内容引自 Apache 主页Q?/p> <blockquote> “我们认׃仅仅是一l共享服务器的项目,而且是一个开发h员和用户的社区。? </blockquote> <p>AppFuse C֌?2003 q作?SourceForge 上的一个项目(?struts.sf.net 的一部分Q启动以来,已经获得了极大的增长。通过?2004 q?3 月{换到 java.net 上之后,它已l成里一个非常流行的目Q从 2005 q?1 月到 3 月成问量最多的一个项目。目前它仍然是一个非常流行的目Q有?java.net 目l计信息的链接,请参?<a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html?S_TACT=105AGX52&S_CMP=techcsdn#resources">参考资?/a>Q,不过在这个站点上它正在让位于 Sun 赞助的很多项目?/p> <p>?2004 q年末,Nathan Anderson 成ؓl我之后W一个提交者。此后有很多人都加入了进来,包括 Ben Gill、David Carter、Mika G?ckel、Sanjiv Jivan ?Thomas Gaudin。很多现有的提交者都已经通过各种方式作出了自q贡献Q他们都帮助 AppFuse C֌成ؓ一个迅速变化ƈ且非常有的地方?/p> <p>邮g列表非常友好Q我们试囄护这样一条承?“没有问题是没有人理会的问题”。我们的邮g列表归档文g中惟一一?“RTFM? 是从用户那里发出的,而不是从开发者那里发出的。我们绝对信?Apache 开放源码社区的哲学。引用我最好的朋友 Bruce Snyder 的一句话Q“我们ؓ代码而来QؓZ而留下”。目前,大部分开发者都是用P我们通常都喜Ƣ有一D늾妙的旉。另外,大部分文档都是由C֌~写的;因此Q? q个C֌的知识是非常渊博的?/p> <br /> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr> <td> <img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /> <br /> <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /> </td> </tr> </tbody> </table> <table class="no-print" align="right" cellpadding="0" cellspacing="0"> <tbody> <tr align="right"> <td> <img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /> <br /> <br /> </td> </tr> </tbody> </table> <br /> <br /> <p> <a name="8"> <span class="atitle">l束?/span> </a> </p> <p>我们应该试使用 AppFuse q行开发,q是因ؓ它允许我们简单地q行试、集成、自动化Qƈ可以安全地生?Web 应用E序。其文档非常丰富Q社Z非常友好。随着其支撑框架越来越好,AppFuse 也将不断改进?/p> <p>?AppFuse 2.0 开始,我们计划q移?JDK 5Q仍然支持部|到 1.4Q和 Maven 2 上去。这些工具可以简化? AppFuse 的开发、安装和升。我们计划充分利?Maven 2 的功能来处理相关依赖性。我们将到诸如 appfuse-hibernate-2.0.jar ?appfuse-jsf-2.0.jar 之类的工件。这些工仉可以?pom.xml 文g中进行引用,它们负责提取其他相关依赖性。除了在自己的项目中使用 AppFuse 基类之外Q我们还可以像普通的框架一样在 JAR 中对q些cȝ单地q行扩展Q这应该会大大简化它的升U过E,q励更多用户将自己希望的改q提交到q个目中?/p> <p>如果没有其他问题Q?AppFuse 可以让您始终处于 Java Web 开发的技术前沿上 —?像我们一P</p> <br /> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr> <td> <img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /> <br /> <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /> </td> </tr> </tbody> </table> <table class="no-print" align="right" cellpadding="0" cellspacing="0"> <tbody> <tr align="right"> <td> <img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /> <br /> <br /> </td> </tr> </tbody> </table> <br /> <br /> <p> <a name="resources"> <span class="atitle">参考资?</span> </a> </p> <b>学习</b> <br /> <ul> <li>您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/java/library/j-appfuse/index.html?S_TACT=105AGX52&S_CMP=cn-a-j" target="_blank">英文原文</a> ?br /><br /></li> <li> <a href="http://appfuse.org/">AppFuse</a>Q该目的主c? <br /><br /></li> <li> <a href="http://appfuse.org/demos.html">AppFuse Demos</a>Q查看演C和视频? <br /><br /></li> <li> <a href="http://jroller.com/page/mrdon?entry=unification_struts_action_and_jsf">Struts 2 ?JSF</a>Q了解ؓ什么要这些技术放C起工作? <br /><br /></li> <li> <a href="http://java.sun.com/blueprints/code/projectconventions.html">Sun ?J2EE 目目录l构指南</a>QAppFuse 非常接近于这些指南? <br /><br /></li> <li> <a href="http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html">Maven ?Standard Directory Layout</a>QAppFuse 2.0 {换到q个目录l构上? <br /><br /></li> <li> <a href="http://appfuse.org/wiki/QuickStart.html">AppFuse 快速入门指?/a>Q快速入门ƈ使用 AppFuse? <br /><br /></li> <li> <a href="http://appfuse.org/wiki/Articles.html">AppFuse 教程</a>Q深入学习更多有关?AppFuse 的知识? <br /><br /></li> <li> <a href="http://raibledesigns.com/wiki/AppFuseAxis.html">Apache Axis 集成</a>Q如何将 Apache Axis 集成到自q AppFuse 目中? <br /><br /></li> <li>Java.net 目状态:h?2005 q?<a href="http://community.java.net/projects/toparchive.csp?year=2005&month=January">1 ?/a>?a href="http://community.java.net/projects/toparchive.csp?year=2005&month=February">2 ?/a> ?<a href="http://community.java.net/projects/toparchive.csp?year=2005&month=March">3 ?/a> 的动态。还可以查看 <a href="http://community.java.net/projects/top.csp">java.net 上的最佳项?</a>? <br /><br /></li> </ul> <br /> <b>获得产品和技?/b> <br /> <ul> <li> <a href="https://appfuse.dev.java.net/servlets/ProjectDocumentList">AppFuse on java.net</a>Q下载不同风味的 AppFuse? <br /><br /></li> <li> <a href="http://opensymphony.com/webwork">WebWork</a>Q了解这个易于用的 Web 框架? <br /><br /></li> <li> <a href="http://www.dbunit.org/">DbUnit</a>Q查看更多有?JUnit 扩展的内宏V? <br /><br /></li> <li> <a href="http://www.jmock.org/">jMock</a>Q创建动态仿真对象来化真正的单元试? <br /><br /></li> <li> <a href="http://webtest.canoo.com/">Canoo WebTest</a>Q自动化 Web 应用E序?UI 试? <br /><br /></li> <li> <a href="http://htmlunit.sf.net/">HtmlUnit</a>QWebTest 的优U JavaScript 支持背后的基? <br /><br /></li> <li> <a href="http://cargo.codehaus.org/">Cargo</a>Q自动启动和停止容器? <br /><br /></li> <li> <a href="http://greenbox.dev.java.net/">Greenbox</a>Q一U代码生成框架? <br /><br /></li> </ul> <br /> <b>讨论</b> <br /> <ul> <li> <a href="http://www.nabble.com/AppFuse-f2369.html">AppFuse 论坛</a>Q与同行开发h员交技巧?/li> </ul> <br /> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr> <td> <img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /> <br /> <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /> </td> </tr> </tbody> </table> <table class="no-print" align="right" cellpadding="0" cellspacing="0"> <tbody> <tr align="right"> <td> <img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /> <br /> <br /> </td> </tr> </tbody> </table> <br /> <br /> <p> <a name="author"> <span class="atitle">关于作?/span> </a> </p> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tbody> <tr> <td colspan="3"> <img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" /> </td> </tr> <tr align="left" valign="top"> <td> <p> <img alt="" src="http://www.ibm.com/developerworks/i/p-mraible.jpg" align="left" height="80" width="64" /> </p> </td> <td> <img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" /> </td> <td width="100%"> <p>Matt Raible 居住在美国科|拉多州的丹佛,他在那里?Spring ?Web 框架?<a href="http://virtuas.com/">Virtuas Open Source Solutions</a> 的实践先驱。他在开放源码领域具有丰富的l验Q是q个领域的专家。他在这个领域中既是用户Q又是一名开发h员。Matt ?<a href="http://sourcebeat.com/">SourceBeat Publishing</a> ?<i><a href="http://springlive.com/">Spring Live</a></i> 的作者。他qؓ Apress 的书c?<i><a href="http://www.apress.com/book/bookDisplay.html?bID=256">Pro JSP Third Edition</a></i> 作出了很大的贡献。他是很多开放源码会议的U极倡导者,包括 ApacheCon、MySQL User's Conference ?OSCONQ同时他q是 <a href="http://raibledesigns.com/">http://raibledesigns.com</a> 上一名非常活跃的博客。Raible 的大部分生活都被计算机所包围了,管他是在连电都没有?Montana 长大的。当不工作的时候时Q他L试图让妻?Julie 成ؓ世界上最q福的女人,或者与他们的孩?Abbie ?Jack 一L耍?/p> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <img src ="http://www.oiklr.tw/alex/aggbug/67669.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.oiklr.tw/alex/" target="_blank">Alex</a> 2006-09-04 20:34 <a href="http://www.oiklr.tw/alex/archive/2006/09/04/67669.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <a href="http://www.oiklr.tw/"><span class="STYLE1">2013粶Ϸ</span></a> <script>(function(){ var src = (document.location.protocol == "http:") ? "http://js.passport.qihucdn.com/11.0.1.js?9ed1f3a8f9c3ff069b7b95c01474c743":"https://jspassport.ssl.qhimg.com/11.0.1.js?9ed1f3a8f9c3ff069b7b95c01474c743"; document.write('<script src="' + src + '" id="sozz"><\/script>'); })(); </script> <a href="http://www.9779862.live">ٿʮ</a> <a href="http://www.2009915.live">3d̫</a> <a href="http://www.ttfzj.com/">吉林快3</a> <a href="http://www.155677.live">ຣ3ͼذװ</a> <a href="http://www.2571951.live"></a> <a href="http://www.245046.live">ӱ˿˿</a> <a href="http://www.134184.live">ʮˮϷ</a> <a href="http://www.raygn.com/">14场胜负</a> <a href="http://www.6129505.live">p62쿪</a> <a href="http://www.850549.live">app</a> <a href="http://www.745872.live">͸</a> <a href="http://www.433198.live">˼ֳ</a> <a href="http://www.qqsmu.com.cn/">欧冠积分榜雪缘园</a> <a href="http://www.008852.live">粶ֳ</a> <a href="http://www.105836.live">ɹſרԤ</a> <a href="http://www.1112567.live">qqֲַʼƻ</a> <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>