﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-架构师之家</title><link>http://Architects.blogjava.net/</link><description>专注于软件设计，特别是架构设计，交流架构设计经验。
&lt;script src="http://www.google-analytics.com/urchin.js" type="text/javascript"&gt;
&lt;/script&gt;
&lt;script type="text/javascript"&gt;
_uacct = "UA-424529-2";
urchinTracker();
&lt;/script&gt;
</description><language>zh-cn</language><lastBuildDate>Sat, 17 May 2008 22:56:17 GMT</lastBuildDate><pubDate>Sat, 17 May 2008 22:56:17 GMT</pubDate><ttl>60</ttl><item><title>将Spring用于高并发环境的隐忧</title><link>http://www.blogjava.net/security/archive/2008/04/19/spring_bug.html</link><dc:creator>david.turing</dc:creator><author>david.turing</author><pubDate>Sat, 19 Apr 2008 01:47:00 GMT</pubDate><guid>http://www.blogjava.net/security/archive/2008/04/19/spring_bug.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Spring一个关于Lock Contention的Bug引起我对Spring代码质量的忧虑&nbsp;&nbsp;<a href='http://www.blogjava.net/security/archive/2008/04/19/spring_bug.html'>阅读全文</a><img src ="http://Architects.blogjava.net/aggbug/194145.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/security/" target="_blank">david.turing</a> 2008-04-19 09:47 <a href="http://www.blogjava.net/security/archive/2008/04/19/spring_bug.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java NIO: selector 机制分析</title><link>http://www.blogjava.net/wfeng007/archive/2008/04/06/191112.html</link><dc:creator>wfeng007</dc:creator><author>wfeng007</author><pubDate>Sun, 06 Apr 2008 13:03:00 GMT</pubDate><guid>http://www.blogjava.net/wfeng007/archive/2008/04/06/191112.html</guid><description><![CDATA[<br />
在学习IBM的那个NIO教程时发现，异步IO这部分的代码居然有个严重问题。<br />
即client突然中断 tcp连接时。服务端会进入一个令人崩溃的无限循环。<br />
<br />
后来发现其实是因为selector在tcp连接已经断开时，还是能够select()出OP_READ状态的SocketChannel的SelectedKey。<br />
这时需要通过Channel读取数据到buffer的过程时的返回值来判断。<br />
这个反回值其实就是读取的字节数。该数字为0时说明就是一般的没有数据可读取，而当为-1时其实表示底层tcp已经断开了。(但IE的连接有点不同,read时直接给出Exception,反正这些情况都要判断了.)<br />
<br />
<br />
之后又想到，那如何注销selector与SocketChannel之间的关联呢？selector内部基本的运作是怎么样的呢？ javadoc中写的是key.cancel()方法。socket的close()在windows似乎也有一样的功能。<br />
<br />
<br />
这里可以用两张图来表示。<br />
<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/wfeng007/DSC00693.JPG" height="800" width="600" /><br />
<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/wfeng007/DSC00698.JPG" height="800" width="600" /><br />
<img src ="http://Architects.blogjava.net/aggbug/191112.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wfeng007/" target="_blank">wfeng007</a> 2008-04-06 21:03 <a href="http://www.blogjava.net/wfeng007/archive/2008/04/06/191112.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>再读“向依赖关系宣战”后的一些质疑。。。</title><link>http://www.blogjava.net/wfeng007/archive/2008/03/17/186765.html</link><dc:creator>wfeng007</dc:creator><author>wfeng007</author><pubDate>Mon, 17 Mar 2008 07:14:00 GMT</pubDate><guid>http://www.blogjava.net/wfeng007/archive/2008/03/17/186765.html</guid><description><![CDATA[<br />
最早看到&#8220;向依赖关系宣战&#8221;这篇文章是在《程序员》杂志上的。当时流行讨论ioc di等概念，这篇文章一出，似乎已经将这些混乱的东西讲清楚了。我就是从这篇文章开始理解IoC阿、DI的概念的。<br />
<br />
现在看来这篇文章确实比较详细，但是反复看的话似乎感觉比较罗嗦。而且通过这两年的实践过后，我发现其实这几个概念在描述时还是有偏差的。<br />
下面有些质疑之处：<br />
1。 IoC与DI，马丁同学提出的依赖注入。。这个名词表面上怎么看都和控制反转扯不上关系。但是他又说&#8220;。。。。应该叫DI&#8221;。结果所有人就把DI与IoC等同，甚至就把DI当作IoC的一个别名来用。。。<br />
我到感觉DI与IoC是指同以概念的不同方面。DI强调的是&#8220;依赖的形成&#8221;即，框架或容器如何得到需要运行的&#8220;实现（implements）&#8221;的。而IoC本身概念是强调整体主控权与&#8220;库&#8221;调用方式相反。即由框架或容器主导主控权。或者说依赖于控制权相反。<br />
<br />
2。IoC与依赖倒置。<br />
文中似乎没有就两者关系进行详细说明。<br />
个人感觉IoC其实就是以依赖倒置为基础的。IoC是在特定环境中的DI特例，并且关注到了&#8220;实现&#8221;与&#8220;使用者&#8221;依赖关系产生的问题，（因为事实上调用时还是存在依赖关系的。）所以需要有&#8220;注册&#8221;这个过程。但是IoC并没有强调&#8220;注册&#8221;。<br />
<img src ="http://Architects.blogjava.net/aggbug/186765.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wfeng007/" target="_blank">wfeng007</a> 2008-03-17 15:14 <a href="http://www.blogjava.net/wfeng007/archive/2008/03/17/186765.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何理解嵌套事务(Nested Transaction)</title><link>http://www.blogjava.net/security/archive/2008/03/04/nested_transaction.html</link><dc:creator>david.turing</dc:creator><author>david.turing</author><pubDate>Tue, 04 Mar 2008 04:38:00 GMT</pubDate><guid>http://www.blogjava.net/security/archive/2008/03/04/nested_transaction.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 介绍nested transaction的概念&nbsp;&nbsp;<a href='http://www.blogjava.net/security/archive/2008/03/04/nested_transaction.html'>阅读全文</a><img src ="http://Architects.blogjava.net/aggbug/183606.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/security/" target="_blank">david.turing</a> 2008-03-04 12:38 <a href="http://www.blogjava.net/security/archive/2008/03/04/nested_transaction.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WebMVC之前世.今生</title><link>http://www.blogjava.net/canonical/archive/2008/02/18/180551.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Mon, 18 Feb 2008 14:02:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2008/02/18/180551.html</guid><description><![CDATA[&nbsp;&nbsp; 所谓WebMVC即Model2模型是目前Web开发领域的主流模型，Struts/Struts2框架是其典型实现。在概念层面上，这种程序组织模型是怎样建立起来的?与其他Web开发模型(如面向对象模型)具有怎样的联系? 它未来可能的发展方向在哪里? 结合Witrix开发平台的具体实践，基于级列设计理论我们可以看到一条概念发展的脉络。<a href="http://canonical.javaeye.com/blog/33824">http://canonical.javaeye.com/blog/33824</a><br />
<img src="http://www.blogjava.net/images/blogjava_net/canonical/web_app_structure.jpg" alt="" border="0" height="992" width="747" /><br />
&nbsp;&nbsp; 1. 外部视角：原始的servlet规范提供了一个简单的面向IO的程序响应模型。一次前台访问由一个特定的servlet负责响应，它从request中读取输入流，在全局session中保持临时状态，向response中写入输出流。在此基础上，JSP提供的模板概念翻转了程序和输出文本之间的相对地位，简化了文本输出过程。至此，这种整体的程序模型基本上只是规范化了外部系统访问Web服务器的响应模型，并没有对后台程序的具体实现制定明确的约束条件。因此在最粗野的后台实现中，读取参数，业务处理，生成页面等处理步骤是纠缠在一起的，很难理解，也很难重用。每一个后台页面都是一个不可分析的整体。<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&lt;%</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;String&nbsp;paramA&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;request.getParameter(</span><span style="color: #000000;">"</span><span style="color: #000000;">paramA</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;ResultSet&nbsp;rsA&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
</span><span style="color: #000000;">%&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;%=</span><span style="color: #000000;">rsA.getString(</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">%&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;String&nbsp;paramB&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;request.getParamter(</span><span style="color: #000000;">"</span><span style="color: #000000;">paramB</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;ResultSet&nbsp;rsB&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
</span><span style="color: #000000;">&lt;%</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;rsB.close();<br />
&nbsp;&nbsp;&nbsp;rsA.close();<br />
&nbsp;&nbsp;&nbsp;conn.close();<br />
</span><span style="color: #000000;">%&gt;</span></div>
<br />
<br />
2. 自发分离：在复杂的程序实践中，我们会自发的对业务处理代码和界面代码进行一定程度的分离。因为我们可以直观的感受到这两种代码的稳定性并不匹配。例如不同业务处理过程产生的结果都可以用一个html表格来展现，而同一个业务处理过程产生的结果页面可能经常发生变化。一般我们倾向于将业务代码写在页面上方，而界面代码写在页面下方，并使用一些原始的分解机制，例如include指令。这种分离是随意的，缺乏形式边界的。例如我们无法表达被包含的页面需要哪些参数，也难以避免全局变量名冲突。需要注意的是，分层的一般意义在于各个层面可以独立发展，它的隐含假定是各层面之间的交互是规范化的，只使用确定的数据结构，按照确定的方式进行交互。例如业务层和界面层通过标准的List/Map等数据结构交互，而不是使用具有无限多种样式的特殊的数据结构。(在弱类型语言环境中，实体对象的结构和Map是等价的).<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&lt;%</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;List&nbsp;header&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;List&nbsp;dataList&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
</span><span style="color: #000000;">%&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #000000;">&lt;%</span><span style="color: #000000;">@&nbsp;include&nbsp;file</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">/show_table.jsp</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">%&gt;</span></div>
<br />
<br />
&nbsp;&nbsp; 3. 规范分离：JSP所提供的useBean和tag机制，即所谓的Model1模型，是对程序结构分离的一种规范化。业务代码封装在java类中，一般业务函数与web环境无关，即不使用request和response对象, 允许单元测试。tag机制可以看作是对include指令的增强，是一种代码重用机制。tld描述明确了调用tag时的约束关系。调用tag时需要就地指定调用参数，而include页面所依赖的参数可能是在此前任意地方指定的，是与功能实现分离的。此外tag所使用的参数名是局部对象上的属性名，从而避免了对全局变量的依赖。很遗憾的是，jsp tag所封装的仍然是原始的IO模型，对程序结构缺乏精细的定义，在概念层面上只是对文本片段的再加工，难以支撑复杂的控件结构。早期jsp tag无法利用jsp模板本身来构造，无法构成一个层层递进的概念抽象机制，更是让这种孱弱的重用模型雪上加霜。在其位却无能谋其政，这直接造成了整个j2ee前台界面抽象层的概念缺失，以致很多人认为一种前台模板重用机制是无用的。在Witrix平台中所定义的tpl模板语言，充分利用了xml的结构特点，结合编译期变换技术，成为Witrix平台中进行结构抽象的基本手段。实际上，xml能够有效表达的语义比一般人所想象的要多得多。<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">　</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">jsp:useBean&nbsp;id</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">myBiz</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">/&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;</span><span style="color: #000000;">&lt;%</span><span style="color: #000000;">&nbsp;List&nbsp;dataList&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;myBiz.process(paramA)&nbsp;</span><span style="color: #000000;">%&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">ui:Table&nbsp;data</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;%=&nbsp;dataList&nbsp;%&gt;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">/&gt;</span></div>
<br />
&nbsp;&nbsp; <br />
&nbsp; 4. 框架分离：在Model1模型中，页面中存在着大量的粘结性代码，它们负责解析前台参数，进行类型转换和数据校验，定位特定的业务处理类，设置返回结果，控制页面跳转等。一种自然的想法是定义一个全局的程序框架，它根据集中的配置文件完成所有的粘结性操作。这也就是所谓面向action的WebMVC模型。这一模型实现了服务器端业务层和界面层在实现上的分离，但是对于外部访问者而言，它所暴露的仍然是原始的自动机模型：整个网站是一个庞大的自动机，每次访问都触发一个action，在action中可能更改自动机的状态（作为全局状态容器的session对象或者数据库）。struts作为面向action框架的先驱，它也很自然的成为了先烈。struts中所引入的FormBean, 链接管理等概念已经在实践中被证明是无益的。一些新兴的框架开始回归到通用的Map结构，直接指定跳转页面，或者利用CoC(Convention Over Configuration)缺省映射.<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;RegisterAction&nbsp;</span><span style="color: #0000ff;">extends</span><span style="color: #000000;">&nbsp;Action&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;ActionForward&nbsp;perform&nbsp;(ActionMapping&nbsp;mapping,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActionForm&nbsp;form,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletRequest&nbsp;req,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse&nbsp;res)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;RegisterForm&nbsp;rf&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(RegisterForm)&nbsp;form;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;mapping.findForward(</span><span style="color: #000000;">"</span><span style="color: #000000;">success</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
}</span></div>
<br />
&nbsp;&nbsp; <br />
5. 横向延展：分层之后必然导向各个层面的独立发展，我们的视野自然也会扩大到单个页面之外，看到一个层面上更多元素之间的相互作用．在面向对象语言大行其道的今天，继承(inheritance)无疑是多数人首先想到的程序结构组织手段．后台action可以很自然的利用java语言自身的继承机制，配置文件中也可以定义类似的extends或者parent属性．但是对于前台页面一般却很少有适用的抽象手段，于是便有人致力于前台页面的对象语言化：首先将前台页面采用某种对象语言表达，然后再利用对象语言内置的结构抽象机制．放弃界面的可描述性，将其转化为某种活动对象，在我看来是一种错误的方向．而JSF(JavaServerFace)规范却似乎想在这个方向上越走越远．JSF早期设计中存在的一个严重问题是延续了面向对象语言中的状态与行为绑定的组织方式．这造成每次访问后台页面都要重建整个Component Tree, 无法实现页面结构的有效缓存．而Witrix平台中的tpl模板语言编译出的结构是无状态的，可以在多个用户之间重用．<br />
<br />
&nbsp; 6. 相关聚合：对象化首先意味着相关性的局域化，它并不等价于对象语言化. 当面对一个大的集合的时候，最自然的管理手段便是分组聚合：紧密相关的元素被分配到同一分组，相关性被局域化到组内．例如，针对某个业务对象的增删改查操作可以看作属于同一分组. struts中的一个最佳实践是使用DispatchAction, 它根据一个额外的参数将调用请求映射到Action对象的子函数上．例如/book.do?dispatchMethod=add. 从外部看来，这种访问方式已经超越了原始的servlet响应模型，看起来颇有一些面向对象的样子，但也仅仅局限于样子而已．DispatchAction在struts框架中无疑只是一种权宜之计，它与form, navigation等都是不协调的，而且多个子函数之间并不共享任何状态变量（即不发生内部的相互作用），并不是真正对象化的组织方式．按照结构主义的观点，整体大于部分之和．当一组函数聚集在一起的时候，它们所催生的一个概念便是整体的表征：this指针．Witrix平台中的Jsplet框架是一个面向对象的Web框架，其中同属于一个对象的多个Action响应函数之间可以共享局部的状态变量（thisObj），而不仅仅是通过全局的session对象来发生无差别的全局关联．<a href="http://canonical.javaeye.com/blog/33873">http://canonical.javaeye.com/blog/33873</a> 需要注意的是，thisObj不仅仅聚集了后台的业务操作，它同时定义了前后台之间的一个标准状态共享机制，实现了前后台之间的聚合．而前台的add.jsp, view.jsp等页面也因此通过thisObj产生了状态关联，构成页面分组．为了更加明确的支持前台页面分组的概念，Witrix平台提供了其他一些辅助关联手段．例如标准页面中的按钮操作都集中在std.js中的stdPage对象上，因此只需要一条语句stdPage.mixin(DocflowOps);即可为docflow定制多个页面上的众多相关按钮操作．此外Witrix平台中定义了标准的url构建手段，它确保在多个页面间跳转的时候，所有以$字符为前缀的参数将被自动携带．从概念上说这是一种类似于cookie，但却更加灵活，更加面向应用的状态保持机制．<br />
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">　　</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;DaoWebAction&nbsp;</span><span style="color: #0000ff;">extends</span><span style="color: #000000;">&nbsp;WebContext{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IEntityDao&nbsp;entityDao;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;metaName;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Object&nbsp;actQuery(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thisObj.put(</span><span style="color: #000000;">"</span><span style="color: #000000;">pager</span><span style="color: #000000;">"</span><span style="color: #000000;">,pager);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;success();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Object&nbsp;actExport(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pager&nbsp;pager&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(Pager)thisObj.get(</span><span style="color: #000000;">"</span><span style="color: #000000;">pager</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;success();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br />
<br />
&nbsp; 7. 描述分离：当明确定义了Action所聚集而成的对象结构之后，我们再次回到问题的原点：如何简化程序基元（对象）的构建？继承始终是一种可行的手段，但是它要求信息的组织结构是递进式的，而很多时候我们实际希望的组织方式只是简单的加和。通过明确定义的meta(元数据)，从对象中分离出部分描述信息，在实践中被证明是一种有效的手段。同样的后台事件响应对象(ActionObject)，同样的前台界面显示代码(PageGroup)，配合不同的Meta，可以产生完全不同的行为结果, 表达不同的业务需求。<a href="http://canonical.javaeye.com/blog/114066">http://canonical.javaeye.com/blog/114066</a> 从概念上说，这可以看作是一种模板化过程或者是一种复杂的策略模式 ProductWebObject = DaoWebObject&lt;ProductMeta&gt;。当然限于技术实现的原因，在一般框架实现中，meta并不是通过泛型技术引入到Web对象中的。目前常见的开发实践中，经常可以看见类似BaseAction&lt;T&gt;, BaseManager&lt;T&gt;的基类，它们多半仅仅是为了自动实现类型检查。如果结合Annotation技术，则可以超越类型填充，部分达到Meta组合的效果。使用meta的另外一个副作用在于，meta提供了各个层面之间新的信息传递手段，它可以维系多个层面之间的共变(covariant)。例如在使用meta的情况下，后台代码调用requestVars(dsMeta.getUpdatableFields())得到提交参数，前台页面调用forEach dsMeta.getViewableFields()来生成界面. 则新增一个字段的时候，只需要在meta中修改一处，前后台即可实现同步更新，自动维持前后台概念的一致性。有趣的是，前后台在分离之后它们之间的关联变得更加丰富。<br />
<br />
8. 切面分离: Meta一般用于引入外部的描述信息，很少直接改变对象的行为结构。AOP(Aspect Oriented Programming)概念的出现为程序结构的组织提供了新的技术手段。AOP可以看作是程序结构空间中定位技术和组装技术的结合，它比继承机制和模板机制更加灵活，也更加强大。<a href="http://canonical.javaeye.com/blog/34941">http://canonical.javaeye.com/blog/34941</a> Witrix平台中通过类似AOP的BizFlow技术实现对DaoWebAction和前台界面的行为扩展，它可以在不扩展DaoWebAction类的情况下，增加/修正/减少web事件响应函数，增加/修正/减少前台界面展现元素。当前台发送的$bizId参数不同的时候，应用到WebObject上的行为切片也不同，从而可以自然的支持同一业务对象具有多个不同应用场景的情况（例如审核和拟制）。在BizFlow中定义了明确的实体化过程，前台提交的集合操作将被分解为针对单个实体的操作。例如前台提交objectEvent=Remove&amp;id=1&amp;id=2,将会调用两次&lt;action id="Remove-default"&gt;操作。注意到AOP定位技术首先要求的就是良好的坐标定义, 实体化明确定义了实体操作边界，为实体相关切点的构造奠定了基础。<a href="http://canonical.javaeye.com/blog/33784">http://canonical.javaeye.com/blog/33784</a><br />
<br />
9. 背景消除：在Witrix平台中, (DaoWebAction + StdPageGroup + Meta + BizFlow)构成完整的程序模型，因此一般情况下并不需要继承DaoWebAction类，也不需要增加新的前台页面文件，而只需要在BizFlow文件中对修正部分进行描述即可。在某种程度上DaoWebAction+StdPageGroup所提供的CRUD(CreateReadUpdateDelete)模型成为了默认的背景知识。如果背景信息极少泄漏，则我们可以在较高抽象层次上进行工作，而不再理会原始的构造机制。例如在深度集成hibernate的情况下，很少会有必须使用SQL语句的需求。BizFlow是对实体相关的所有业务操作和所有页面展现的集中描述，在考虑到背景知识的情况下，它定义了一个完整的自给自足的程序模型。当我们的建模视角转移到BizFlow模型上时，可以发展出新的程序构造手段。例如BizFlow之间可以定义类似继承机制的extends算子，可以定义实体状态驱动的有限自动机，可以定义不同实体之间的钩稽关系（实体A发生变化的时候自动更新实体B上的相关属性），也可以定义对Workflow的自然嵌入机制。从表面上看，BizFlow似乎回归到了前后台大杂烩的最初场景（甚至更加严重，它同时描述了多个相关页面和多个相关操作），但是在分分合合的模型建立过程中，大量信息被分解到背景模型中，同时发展了各种高级结构抽象机制, 确保了我们注意力的关注点始终是有限的变化部分。而紧致的描述提高了信息密度，简化了程序构造过程。<a href="http://canonical.javaeye.com/blog/126467">http://canonical.javaeye.com/blog/126467</a><br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">bizflow&nbsp;</span><span style="color: #ff0000;">extends</span><span style="color: #0000ff;">="docflow"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #008000;">&lt;!--</span><span style="color: #008000;">&nbsp;引入docflow模型，包括一系列界面修正和后台操作　</span><span style="color: #008000;">--&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">biz&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="my"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">tpls</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">tpl&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="initTpl"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">script&nbsp;</span><span style="color: #ff0000;">src</span><span style="color: #0000ff;">="my_ops.js"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">&gt;&lt;/</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stdPage.mixin(MyOps);&nbsp;//&nbsp;引入多个页面上相关按钮对应的操作<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">tpl</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">tpls</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">biz</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">bizflow</span><span style="color: #0000ff;">&gt;</span></div>
<br />
<br />
<br />
<img src ="http://Architects.blogjava.net/aggbug/180551.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2008-02-18 22:02 <a href="http://www.blogjava.net/canonical/archive/2008/02/18/180551.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转)什么才是软件开发的葵花宝典？</title><link>http://www.blogjava.net/soddabao/archive/2008/02/03/179152.html</link><dc:creator>冷面阎罗</dc:creator><author>冷面阎罗</author><pubDate>Sun, 03 Feb 2008 06:46:00 GMT</pubDate><guid>http://www.blogjava.net/soddabao/archive/2008/02/03/179152.html</guid><description><![CDATA[中国人大都喜欢用武侠小说来比较软件开发，但是在实战武功中，只有葵花宝典才是最厉害的，也只有掌握了葵花宝典，才能称为"不败"。 <br />
<br />
但什么才是软件开发的葵花宝典？ <br />
<br />
让我们先从一些现象出发。我们的前提是，软件开发是一项智力密集型劳动。对于智力密集型劳动，我们观察到的现象是，个体的表现差异很大，团队的表现差异很大，组织的表现差异很大，国家的表现差异很大。这不象体力占主要的劳动，象百米王跑百米的速度也仅比我快50%。但在棋类运动中，一个高手可以车轮战数位低手，而且毫无例外地将他们一一击败！ <br />
<br />
这些智力运动员表现出的特点是，计算精确而且速度快。其行为很象东方不败。虽然关于葵花宝典的传说很多，但最准确的描述只有一个字"快"。东方不败已经快到了吓人的地步。就象卡斯帕罗夫已快到了深蓝的地步。 <br />
<br />
有一则关于物理学家玻尔的轶事，有一次玻尔在普林斯顿大学听两个年青教授演讲他们的工作成果。期间玻尔突然发言说，如果照你们的研究算下去，会得到一个很有意思的推论。结果两个年青教授回去计算了两天，果然得出了同样的结论。玻尔是如何做到这样快的？ <br />
<br />
在软件开发中，我们同样注意到这样一种高手，他们可以每天写出一千行左右的高品质代码。他们可以运用已有的一些软件包，迅速完成一个新的产品。他们可以在很短的时间内，学会一项新的程序语言或是新技术。他们表现出一种神奇的速度。 <br />
<br />
在武侠小说中，所有的高手都有一些凡人不能企及的表现。象张无忌学太极，用龙爪手击败龙爪手名家；乔峰用太祖长拳击败天下英雄；姑苏慕容以其人之道还治其人之身，令狐冲一剑剌瞎十几双眼睛等等。我认为，之所以他们能做到这样，关键是在于他们快。 <br />
<br />
快并不意味着不准或品质差。快与品质并不矛盾。 <br />
<br />
高手的快，其实包含着很高的品质在其中。如果你因为高手的快，就质疑其品质，那就相当于在问：东方不败出手那么快，会不会刺不准？东方不败并不满足于刺死对手，他会在对手身上刺朵花。他把杀人变成了艺术。准确来说，他真正的兴趣不在杀人，而在于艺术。 <br />
<br />
退一步说，就算东方不败第一击有点偏差，他稍作修正后，马上跟上的第二第三击，也会击中他想击中的地方。在武功差的对手剑还没拨出来的时候，他已杀死对方并刺上了一朵花。 <br />
<br />
所以真正的软件高手，他并不满足于他的代码能有效地工作了，他认为编程是艺术，并醉心于其中。在低手能写出一个版本的时间里，他已经写出了第十版。其品质当然不可同日而语。就象一个九段棋手，在给定的时间里，他能计算十种可能，并将每种可能计算到100手之后，从中选择一种最有利的下法。低手岂有苟全的机会？ <br />
<br />
高手写软件总是不停地在重构(refactoring）。高手喜欢迭代式开发。高手说，增量就是打补丁，迭代就是推倒重来。对于软件这种东西，写一遍它可能OK（做到这一点也不容易），写十遍就是一个伟大的产品，再多写一遍它就更伟大些。 <br />
<br />
高手快的诀窍在于他很熟悉各种东西。高手看书很快，因为每一本新书里，值得他好好看的新技术只有一两章的内容。他能迅速看完，并准确领会这本书的中心思想和价值。而对于一个新手，每句话都是新的，他都需要去理解，每一段例子，他都需要去试。 <br />
<br />
很少看到一种100%全新的技术或理论。就象Java language specification里说的，Java没有使用任何新技术，用的都是业界久经考验的技术。对于高手来说，那些技术都是他所熟悉的。自然，很快他就从一个C++高手变成了Java高手。如果一个编程新手学Java，学两年也不如一个高手学两个月的。高手学新东西快。 <br />
<br />
高手写代码速度快。统计结果说，人均每人月的有效代码速度大概是300至400行。但那是业界平均生产效率。对于高手来说，这个数字太低了。每天写300至400行是完全有可能的。因为在写代码时，所有知识都已具备，已经没有任何需要他多花时间的事情了。他甚至很少需要Debug。 <br />
<br />
高手重用代码的能力很强，熟悉新的API的速度很快。这也是因为，他曾经使用过很多的API，重用过很多的代码。他知道哪些是可用的，哪些有缺陷。他既过用Qt，也用过gtk+，也用过windows API &amp; MFC，也用过AWT &amp; SWING。新的API对他来说，也是老熟人。 <br />
<br />
高手喜欢用轻量级的工具，象vi，notepad，最多到UltraEdit这样复杂的。高手用这种工具写出很多的东西。这些工具就象东方不败的针。那根针已具有神奇的魔力，有时候它可以当激光枪来用。 <br />
<br />
对于一些重量级的工具，高手虽不常用，但一经使出也威力大于常人。如果让东方不败用剑，最厉害的剑术名家也会败得很难看。高手其实用过很多的重量级工具，而且深知其优缺点。所以使出来，就会把威力发挥到最大，而把缺陷减少到最小。而低手则不然，总是把缺陷加以大大的发扬而浑不知其精髓何在。就象很多人学用UML、RUP、XP、Design pattern那样。 <br />
<br />
高手所学博杂且融会贯通。高手做什么都快，当低手还在一愁莫展的时候，高手已经圆满解决问题，去干别的事去了。 <br />
<br />
在成为高手的路上，要有热情，要循序渐进，要持之以恒。 <br />
<br />
要逼自己，书要快快地看。要试图迅速理解其主旨。其实你快快看所接受的信息量，与慢慢看接受的差不多。能明白多少很大程度上取决于你的功底。以后用到再回过头来看。一本对你来说新东西太多的书，不要指望看一次就全理解吸收。就象很多功力不够的人看design patterns那本书一样。慢慢看还不如找到多种信息来源，都快快看一遍。对于一个完全陌生的领域，只看一本书很远远不够的。 <br />
<br />
要逼自已，事要快快做。有一个朋友，几年前我介绍他去玩玩linux，他也表示想玩，但他现在还没碰过。他失去了很多机会。 <br />
<br />
平时要有意识提高自己写代码的速度，其实你一天写15行有效代码，与你写50行有效代码，其品质是差不多的。你应该把那些业界平均水平抛诸脑后，把超越自己做为唯一目标。等到你写了很多各式各样的代码，你的水平就不一般了。一个老师曾向我介绍他的学英语的决窍，他说你去啃原版小说，啃到50本，就和一般人有很大距离了。就是这个理。如果你写得太慢，怎么能写得多？水平怎么能提高？ <br />
<br />
要逼自己，学很多别人怕学的东西。低手总会说：这么多东西怎么学得过来啊。于是就少学或不学。这样就成不了高手了。高手有非常广的知识面，有很丰富的经验。知道很多低手不知道的事。玩过很多低手听都没听过的东西。 <br />
<br />
要逼自己，努力满足客户的各种需求。个人技能是在满足客户的各种需求的过程中提高的。比如你喜欢用Delphi，客户说一定要用VB，那你就答应他，然后把自己培养成为VB的高手。用户的需求看似变态，但对你是一个机会。 <br />
<br />
怎样才能做到看书快，写代码快，学新东西快，一个显而易见的途径就是将工作并行化。你在一台机器上make时，同时可以在看别的文档和聊天。对于计算机是这样，对人也是这样。如果你只能串行地处理问题，你的速度将提高有限。你的大脑有很大潜力可挖，它应该是一个多任务分时系统。努力减少它idle的时间。搞经济的Samuelson被人称为human brain main frame，可见他的大脑有多快。 <br />
<br />
让你的思维快起来，你就会区别于那些反应迟钝的人。如果你不能让人生的道路变长，就让它变宽。这世界变化快，需要你变得比它快才行。 <br />
<br />
这样加快并不会让你短命，相反，你有更多的时间来享受生活和锻炼身体。你的生活将更有品质，更丰富，更有意义。面对变化，你将立于不败之地。我们都是和自己赛跑的人，需要跑得比昨天的自己更快。 
<img src ="http://Architects.blogjava.net/aggbug/179152.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/soddabao/" target="_blank">冷面阎罗</a> 2008-02-03 14:46 <a href="http://www.blogjava.net/soddabao/archive/2008/02/03/179152.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle收购BEA——如何看待J2EE中间件的价值</title><link>http://www.blogjava.net/security/archive/2008/01/16/175796.html</link><dc:creator>david.turing</dc:creator><author>david.turing</author><pubDate>Wed, 16 Jan 2008 14:39:00 GMT</pubDate><guid>http://www.blogjava.net/security/archive/2008/01/16/175796.html</guid><description><![CDATA[Oracle终于收购了BEA了<br /><a href="http://www.oracle.com/bea/index.html">http://www.oracle.com/bea/index.html</a><br /><a href="http://biz.yahoo.com/ap/080116/oracle_bea.html">http://biz.yahoo.com/ap/080116/oracle_bea.html</a><br /><br />新一轮收购，其实最值得关注的是WebLogic/Tuxedo两个拳头产品，而作为一直缺乏中间件领头产品的Oracle公司，这一次又重新开始瓜分市场，微软/IBM/SAP都会面临直接的强有力的挑战。<br /><br />整个事件中，对于所有JavaEE开发者，无疑是WebLogic。<br />如果说，Oracle是最优秀的数据库产品，我觉得，WebLogic绝对是铁定最优秀的J2EE中间件服务器(对WAS6.1，用户普遍认为还是WebLogic 9/10更强大)。<br />有很多人认为WebSphere会是一个挑战者，这里面含有较多的商业因素，从技术含量上，从稳定性，可靠性和关键企业用户覆盖上，WebLogic的价值远胜于WebSphere。在中国，WebLogic关键企业用户要远胜于WebSphere。<br />Oracle的中间件定义范畴非常广，这次的收购，在J2EE的领域，将会是新一场中间件标准的全面对抗，如果考虑到Oracle数据库曾经完胜了IBM的DB2一回，这一次，在J2EE中间件上，Oracle又一次是IBM抛离在脑后了。<br /><br />在JavaEE中间件标准上，现在，Oracle有了Sibel，PeopleSoft,  <a title="BEA" href="www.bea.com" target="_blank">BEA</a>，在SOA Solution的完整性上，完全可以PK IBM了。<br /><br />大部分人关注，现在的IT企业，架构越来越复杂，甚至SOA，曾经一度成为我们未来最重要的IT新概念，而J2EE本身，中间件本身，有些人甚至认为不再重要了，因为SOA是面向服务的，本身并不依赖于特定的J2EE中间件。<br />其实，明眼人还是能看出，所有的IT概念背后，IT的基础设施仍然是IT生态链中的关键组成部分，实施一个SOA的项目，你必须购买主机硬件，购买OS，购买中间件，然后最后才在其上开发你的SOA架构。<br />现在，SOA对抗，虚一点看，好像是IT战略的范畴，实一点看(从技术、资金)，无非是平台之争。这一次Oracle收购BEA，足以让国人重新审视J2EE中间件的巨大价值和重要地位，WebLogic，目前，一个被IT500强公认为最优秀的J2EE中间件服务器，将会收购事件背后的其中一个主要的推动因素。无论SOA是如何成为第三波IT产业革命的重要推动力，J2EE中间件平台之争就犹豫当年的OS、浏览器之争那样激烈，是每个企业决策层实施SOA的时候必定考虑到的因素。<br /><br /><br /><img src ="http://Architects.blogjava.net/aggbug/175796.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/security/" target="_blank">david.turing</a> 2008-01-16 22:39 <a href="http://www.blogjava.net/security/archive/2008/01/16/175796.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++配置管理</title><link>http://www.blogjava.net/canonical/archive/2008/01/12/174892.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sat, 12 Jan 2008 12:58:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2008/01/12/174892.html</guid><description><![CDATA[&nbsp; 自从离开学校就基本上不再使用C++了，最近却又因为项目上的原因重新走入这一迷失的世界, 感觉很是缺乏一些顺手的工具。首先就是做配置管理有点麻烦, 因为缺乏反射机制, 无法直接映射, 所以一般需要手工书写配置设置功能. <br />
&nbsp; 我们希望配置类在配置阶段能够支持动态属性名，<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;GConfig&nbsp;cfg;<br />
&nbsp;&nbsp;cfg.set(</span><span style="color: #000000;">"</span><span style="color: #000000;">bgColor.b</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">3.0</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;cfg.set(</span><span style="color: #000000;">"</span><span style="color: #000000;">lightEnabled</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #0000ff;">false</span><span style="color: #000000;">);<br />
<br />
&nbsp;&nbsp;t_float&nbsp;b&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;cfg.get(</span><span style="color: #000000;">"</span><span style="color: #000000;">bgColor.b</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;bool&nbsp;l&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;cfg.get(</span><span style="color: #000000;">"</span><span style="color: #000000;">lightEnabled</span><span style="color: #000000;">"</span><span style="color: #000000;">);</span></div>
<br />
&nbsp;&nbsp;&nbsp; 但是内部使用时支持直接的属性访问，便于编译器检查， 也提高运算速度。<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t_float&nbsp;b&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;cfg.bgColor.b;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;l&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;cfg.lightEnabled;</span></div>
<br />
<br />
所幸C++的类型系统能够偷偷的去干很多见不得人的勾当，因此便有了下面这个简易机制。<br />
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">#define&nbsp;S_P(x)&nbsp;</span><span style="color: #0000ff;">do</span><span style="color: #000000;">{</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(strcmp(name,#x)&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">) { x&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;value;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">; } }&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">(</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br />
#define&nbsp;G_P(x)&nbsp;</span><span style="color: #0000ff;">do</span><span style="color: #000000;">{</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(strcmp(name,#x)&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">) { value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;x;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">; } }&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">(</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br />
<br />
</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;_GConfig{<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br />
&nbsp;&nbsp;bool&nbsp;lightEnabled;<br />
<br />
&nbsp;&nbsp;t_float&nbsp;minX;<br />
&nbsp;&nbsp;t_float&nbsp;maxX;<br />
&nbsp;&nbsp;t_float&nbsp;minY;<br />
&nbsp;&nbsp;t_float&nbsp;maxY;<br />
<br />
&nbsp;&nbsp;_GConfig(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;initialize&nbsp;all&nbsp;primitive&nbsp;members</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;memset(</span><span style="color: #0000ff;">this</span><span style="color: #000000;">,</span><span style="color: #000000;">0</span><span style="color: #000000;">,sizeof(_GConfig));<br />
&nbsp;&nbsp;}<br />
};<br />
<br />
</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;GConfig:&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;_GConfig{<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br />
&nbsp;&nbsp;GColor&nbsp;bgColor;<br />
<br />
&nbsp;&nbsp;GConfig(){<br />
&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;_variant_t&nbsp;get(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;name){<br />
&nbsp;&nbsp;&nbsp;&nbsp;_variant_t&nbsp;value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;get(name,value);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;value;<br />
&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;get(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;name,_variant_t</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;value){<br />
&nbsp;&nbsp;&nbsp;&nbsp;G_P(lightEnabled);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;G_P(minX);<br />
&nbsp;&nbsp;&nbsp;&nbsp;G_P(maxX);<br />
&nbsp;&nbsp;&nbsp;&nbsp;G_P(minY);<br />
&nbsp;&nbsp;&nbsp;&nbsp;G_P(maxY);<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;G_P(bgColor.r);<br />
&nbsp;&nbsp;&nbsp;&nbsp;G_P(bgColor.g);<br />
&nbsp;&nbsp;&nbsp;&nbsp;G_P(bgColor.b);<br />
&nbsp;&nbsp;&nbsp;&nbsp;G_P(bgColor.a);<br />
&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;set(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;name,&nbsp;_variant_t&nbsp;value){<br />
&nbsp;&nbsp;&nbsp;&nbsp;S_P(lightEnabled);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;S_P(minX);<br />
&nbsp;&nbsp;&nbsp;&nbsp;S_P(maxX);<br />
&nbsp;&nbsp;&nbsp;&nbsp;S_P(minY);<br />
&nbsp;&nbsp;&nbsp;&nbsp;S_P(maxY);<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;S_P(bgColor.r);<br />
&nbsp;&nbsp;&nbsp;&nbsp;S_P(bgColor.g);<br />
&nbsp;&nbsp;&nbsp;&nbsp;S_P(bgColor.b);<br />
&nbsp;&nbsp;&nbsp;&nbsp;S_P(bgColor.a);<br />
&nbsp;&nbsp;}<br />
};<br />
</span></div>
<br />
_variant_t是VC++在&lt;comdef.h&gt;中提供的对变体数据类型的封装。使用S_P和G_P这样的宏可以由编译器检查变量名的正确性。<br />
<img src ="http://Architects.blogjava.net/aggbug/174892.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2008-01-12 20:58 <a href="http://www.blogjava.net/canonical/archive/2008/01/12/174892.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关系模型与ORM</title><link>http://www.blogjava.net/canonical/archive/2008/01/06/173154.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sun, 06 Jan 2008 11:04:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2008/01/06/173154.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp; 关系数据库模型在理论上主要解决的是消除数据冗余的问题。关系模型的数学基础是所谓的集合论，而集合的基本含义正是一组具有某种原子性的互不相同的元素。面向对象技术是对相关性进行局域化的一种手段（相关的数据和操作聚集到同一对象名义下），在这一局域化过程中，相同的元素被识别出来，成为独立的对象。从某种意义上说，关系模型与对象模型是殊途同归的过程，是从不同侧面对同一事物的反映。关系模型中，我们关注的重点是元素组成的集合，允许的连接关系定义在集合之上。而在对象模型中，我们关注的首先是横向关联的实体，实体之间具有稳定的联系。在概念层面上，从对象模型映射到一种关系存储模型只是一个分组问题。为了断开实体之间的直接联系，关系模型创造了一个id字段，而对象模型并不是需要显式id的。在关系模型中，关联并不是通过某种存在的结构来表达的（一个实体持有另一个实体的指针，拥有直接联系），而是将直接关联问题弱化为某种计算过程，我们必须检查id的值（不是某种直接的存在性），通过某种运算过程才能重新发现数据之间的关联。<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 通过id（伴随一个匹配计算过程）来进行间接关联对于保证模型的一致性是非常关键的。在ORM中恢复了对象的强关联其实会造成很多潜在的复杂性。例如为了维护对象层面结构的一致性，在更新父子关系的时候，我们需要同时调用 child.setParent(parent); parent.getChildren().remove(child); 当关联结构更加复杂的时候，这里所需要的维护工作是随之增加的。不过，在ORM中，对象的形态是暂时性的。在ORM的一次session的操作过程中，对于对象状态的修改可以是不一致的。例如我们可以只调用child.setParent(parent); 而不需要同时&nbsp; parent.getChilren().remove(child); 只要我们在此次session操作中，不需要同时用到parent.getChildren(). 这种关联的暂时性对于很多ORM应用来说是必不可少的。<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 对象模型中可以直接表达的结构关系比关系模型要丰富一些，例如继承关系，many-to-many, one-to-list等。但是所有这些都不是真正本质性的差异。抛弃概念诠释，基类与众多派生类之间的关系基本上可以等价于一组one-to-one关系。而当关联对象本身的重要性凸现出来的时候，当我们无法把它约化为对象上的一些附属特性的时候（例如数组的下标），我们必然要建立相应的关联对象，而这正对应于关系模型中的中间关联表。中间关联表上增加额外的字段是一个自然的扩展过程，而对象模型上做这样的扩充往往表现为形态上的重大的不兼容的变化，例如从getManyToManyEntity() -&gt; getToManyRelation(), 这实际上意味着这里的对象形式是偶然的，简化的。 <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 在原始的关系数据库模型中，所有的表之间的地位是平等的，所有字段之间的地位是平等的（主键和外键在参与数据关联时和其他字段的处理方式一致）。这种概念上的均一性和普遍性往往被认为是理论的优美之处。但是现实世界是复杂的，发展的方向就是逐步识别出不同之处，并找出自然的表达形式将这些不同表达出来。均匀的关系模型是对称性最高的，最简化的模型。在面对物理约束时，它隐含的假设是集合之间很少发生相互作用，单表（表单到数据表之间的映射）和主从表是最广泛的情况。试着想象一下关系模型，在思维中一般我们只能看到两个数据表，当考虑到多个表的时候，因为这些表之间没有明确的可区分性，因此它们的意象是模糊的。只有明确意识到主键，外键，主表，从表，字典表，事实表，纬度表这些不同的概念的时候，当对称性出现破缺的时候，我们思维中的模型才能够丰富化起来。<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 关系模型理论应用到数据库具体应用中时，并不需要死守关系范式教条，它们只是描述了某种极端化的对唯一性的追求。面对具体应用的时候，理论本身也在不断丰富化。我并不把现实应用中必然需要增加冗余字段看作是关系理论失效的结果。从关系完全分解，到关系完全不分解之间，我们可以建立大量的模型。建立冗余字段的时候，我们存在着大量可能的选择，到底哪一种选择是最优的，理论方面仍然可以给我们以具体的指导。理论在各种不同纯化程度的关系模型中都可以给我们以直观的建议。数据仓库理论中建立的snowflake模式和star模式，强调了针对主题域的允许部分冗余的关系分解。这里实际上是强调了表之间的不同性。不再是所有的表都处于同一地位。Fact Table和Dimension Table之间的区别被识别出来，并被明确处理。在我看来，这是原始关系模型的一种自然发展，它也是关系模型理论的一部分。理论不应该是单一的，而是提供一个模型级列，在不同的复杂性层次上，我们可以根据理论的指导选择具体的实现模型。<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 关于ORM <a href="http://canonical.javaeye.com/blog/111500">http://canonical.javaeye.com/blog/111500</a><br />
&nbsp;&nbsp;&nbsp; 关系模型中的所谓关系是在使用时刻才定义的，所有建立关系的方式在某种程度上都是等价的，也是外在的。而在ORM中主键与外键之间的关联被独立出来，成为模型内置的部分。这在很多时候简化了数据查询的结构构造过程。<br />
&nbsp;&nbsp;&nbsp; 在ORM中主键因为缓存的存在而显出与其他字段的区别。ORM的使用使得数据存储的分解策略得到扩充。并不是所有的表的更新频度都是一致的，而且表中的数据量大小也不同。字典表一般较小，而且很少更新，可以安全的复制。在整个数据存储框架中，ORM作为独立的技术元素参与数据存储过程，通过主键提供缓存服务，产生了新的数据分布模型，提供了新的性能优化契机。<br />
<br />
<br />
<img src ="http://Architects.blogjava.net/aggbug/173154.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/canonical/" target="_blank">canonical</a> 2008-01-06 19:04 <a href="http://www.blogjava.net/canonical/archive/2008/01/06/173154.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>高性能分页标签extremeTable的Limit设计架构思想剖析</title><link>http://www.blogjava.net/asktalk/archive/2007/12/26/170625.html</link><dc:creator>Asktalk</dc:creator><author>Asktalk</author><pubDate>Wed, 26 Dec 2007 08:17:00 GMT</pubDate><guid>http://www.blogjava.net/asktalk/archive/2007/12/26/170625.html</guid><description><![CDATA[&nbsp;
<p><span style="font-family: 宋体">这是一个目前最好的一个开源分页标签的实现</span>---extremeTable<span style="font-family: 宋体">标签。今天谈谈它的</span>Limit<span style="font-family: 宋体">的设计架构思想。</span></p>
<p><span style="font-family: 宋体">这个设计很通用，经过作者的多次重构，现在extremeTable的架构非常漂亮。这个标签现在缺点是有些参数对mvc控制器屏蔽了，应提供一致的对外接口。不过整体上设计还是很精致的，面向对象来处理 html元素，与spring非常的默契</span><span style="font-family: 宋体">，非常便于开发和测试。</span></p>
<h1><span style="font-family: 宋体">类图关系<br />
<img height="680" alt="" src="http://www.blogjava.net/images/blogjava_net/asktalk/limit.png" width="776" border="0" /><br />
</span></h1>
<h1 style="margin-left: 18pt; text-indent: -18pt">1，&nbsp;<span style="font-family: 宋体">工厂</span>LimitFactory</h1>
<p>TableLimitFactory<span style="font-family: 宋体">，</span>AbstractLimitFactory<span style="font-family: 宋体">，</span>LimitFactory</p>
<p>TableLimitFactory<span style="font-family: 宋体">是最终实现的工厂，它</span>extends<span style="font-family: 宋体">了</span>AbstractLimitFactory<span style="font-family: 宋体">抽象类，</span>AbstractLimitFactory <span style="font-family: 宋体">类</span>implements<span style="font-family: 宋体">了</span>LimitFactory<span style="font-family: 宋体">接口。</span></p>
<p>TableLimitFactory<span style="font-family: 宋体">主要是用来实例化，通过构造函数传入参数。同时创建</span>Registry<span style="font-family: 宋体">来完成</span>jsp<span style="font-family: 宋体">页面参数传入</span>Registry<span style="font-family: 宋体">。当然还有一个功能就是从</span>web.xml<span style="font-family: 宋体">的配置文件读取一些全局参数。首先读取配置文件参数，然后根据参数创建</span>LimitRegistry<span style="font-family: 宋体">对象。</span></p>
<p>this.registry = new LimitRegistry(context, tableId, prefixWithTableId, state, stateAttr);</p>
<p>AbstractLimitFactory<span style="font-family: 宋体">主要是用来获取</span>jsp<span style="font-family: 宋体">页面上设置的参数，比如分页的信息（第几页，起始行，结束行，每页显示行数，查询条件，排序条件等），当然他是通过工具类</span>Registry<span style="font-family: 宋体">来实现。</span></p>
<h1 style="margin-left: 18pt; text-indent: -18pt">2，&nbsp;Limit</h1>
<p>TableLimit<span style="font-family: 宋体">，</span>Limit<span style="font-family: 宋体">。其主要作用是一个参数参数器，就是把</span>Registry<span style="font-family: 宋体">对象的参数传入</span>TableLimit<span style="font-family: 宋体">，考虑到分层吧，</span>TableLimit<span style="font-family: 宋体">是该标签和</span>action<span style="font-family: 宋体">通信的桥梁。就像我们的</span>j2ee<span style="font-family: 宋体">项目</span>vo<span style="font-family: 宋体">是</span>dao<span style="font-family: 宋体">和</span>struts<span style="font-family: 宋体">等</span>view<span style="font-family: 宋体">等数据传输工具。</span></p>
<h1 style="margin-left: 18pt; text-indent: -18pt">3，&nbsp;Preferences</h1>
<p>TableProperties<span style="font-family: 宋体">，</span>Properties <span style="font-family: 宋体">主要是来实现从</span>web.xml<span style="font-family: 宋体">配置的文件中读取配置的一些全局参数。</span></p>
<p>InputStream input = this.getClass().getResourceAsStream(preferencesLocation);</p>
<p>if (input != null) {</p>
<p style="text-indent: 15.75pt">properties.load(input);</p>
<p>}</p>
<p><span style="font-family: 宋体">其中</span>preferencesLocation<span style="font-family: 宋体">是路径，在</span>TableLimitFactory<span style="font-family: 宋体">初始化时候，</span><span style="font-family: 宋体">通过工具类</span>TableModelUtils.getPreferencesLocation(context)<span style="font-family: 宋体">获取。</span></p>
<p><span style="font-family: 宋体">这个设计也是大多数需要配置文件的系统常用的方法。</span></p>
<h1 style="margin-left: 18pt; text-indent: -18pt">4，&nbsp;Registry</h1>
<p>LimitRegistry<span style="font-family: 宋体">，</span>AbstractRegistry<span style="font-family: 宋体">，</span>Registry</p>
<p><span style="font-family: 宋体">这个体系结构和上面的工厂模式一样，就是</span>LimitRegistry<span style="font-family: 宋体">主要是用来实例化，通过构造函数传入参数。</span>AbstractRegistry<span style="font-family: 宋体">是实际实现类，获取</span>jsp<span style="font-family: 宋体">表单提交的参数，并提供</span>getter<span style="font-family: 宋体">方法供</span>Limit<span style="font-family: 宋体">来使用。</span>Registry<span style="font-family: 宋体">是一个接口。</span></p>
<p><span style="font-family: 宋体">所以这设计模式，我们可以来学习，</span></p>
<p><span style="font-family: 宋体">经典表述：<span style="color: red">类</span></span><span style="color: red">—</span><span style="color: red; font-family: 宋体">抽象类</span><span style="color: red">—</span><span style="color: red; font-family: 宋体">接口</span></p>
<p style="margin-left: 21pt; text-indent: -21pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 宋体">类：初始化，定义构造函数，传入参数。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 宋体">抽象类：定义业务方法在此。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 宋体">接口：定义接口方法，这个不用多说。</span></p>
<p style="margin-left: 18pt; text-indent: -18pt">（作者：asktalk&nbsp;&nbsp; 来自&nbsp;<a href="http://www.blogjava.net/askltak">http://www.blogjava.net/askltak</a> 原创文章，转载请注明出处）</p>
<img src ="http://Architects.blogjava.net/aggbug/170625.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/asktalk/" target="_blank">Asktalk</a> 2007-12-26 16:17 <a href="http://www.blogjava.net/asktalk/archive/2007/12/26/170625.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring Web框架与Struts的区别</title><link>http://www.blogjava.net/asktalk/archive/2007/12/25/asktalk.html</link><dc:creator>Asktalk</dc:creator><author>Asktalk</author><pubDate>Mon, 24 Dec 2007 18:23:00 GMT</pubDate><guid>http://www.blogjava.net/asktalk/archive/2007/12/25/asktalk.html</guid><description><![CDATA[<p>&nbsp; </p>
<p><span style="font-family: 宋体">下面是从</span>struts<span style="font-family: 宋体">的角度来谈谈</span>spring<span style="font-family: 宋体">自带的</span>web<span style="font-family: 宋体">框架的使用。</span><span style="font-family: 宋体"><br />
当然，我们在配置</span>web<span style="font-family: 宋体">框架前，需要把</span>spring<span style="font-family: 宋体">配置好，这里就不多说了。</span></p>
<h1 style="margin-left: 18pt; text-indent: -18pt">1.web<span style="font-family: 宋体">框架核心</span>servlet<span style="font-family: 宋体">在</span>web.xml<span style="font-family: 宋体">中的配置。<br />
</span></h1>
<p style="margin-left: 18pt; text-indent: 0cm"><br />
&nbsp;</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #008080">&nbsp;1</span><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #000000">&lt;</span><span style="color: #000000">servlet</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #000000">&lt;</span><span style="color: #000000">servlet</span><span style="color: #000000">-</span><span style="color: #000000">name</span><span style="color: #000000">&gt;</span><span style="color: #000000">Dispatcher</span><span style="color: #000000">&lt;/</span><span style="color: #000000">servlet</span><span style="color: #000000">-</span><span style="color: #000000">name</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #000000">&lt;</span><span style="color: #000000">servlet</span><span style="color: #000000">-</span><span style="color: #0000ff">class</span><span style="color: #000000">&gt;</span><span style="color: #000000">org.springframework.web.servlet.DispatcherServlet</span><span style="color: #000000">&lt;/</span><span style="color: #000000">servlet</span><span style="color: #000000">-</span><span style="color: #0000ff">class</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">init</span><span style="color: #000000">-</span><span style="color: #000000">param</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #000000">&lt;</span><span style="color: #000000">param</span><span style="color: #000000">-</span><span style="color: #000000">name</span><span style="color: #000000">&gt;</span><span style="color: #000000">contextConfigLocation</span><span style="color: #000000">&lt;/</span><span style="color: #000000">param</span><span style="color: #000000">-</span><span style="color: #000000">name</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">param</span><span style="color: #000000">-</span><span style="color: #000000">value</span><span style="color: #000000">&gt;/</span><span style="color: #000000">WEB</span><span style="color: #000000">-</span><span style="color: #000000">INF</span><span style="color: #000000">/</span><span style="color: #000000">Config.xml</span><span style="color: #000000">&lt;/</span><span style="color: #000000">param</span><span style="color: #000000">-</span><span style="color: #000000">value</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">init</span><span style="color: #000000">-</span><span style="color: #000000">param</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #000000">&lt;/</span><span style="color: #000000">servlet</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #000000">&lt;</span><span style="color: #000000">servlet</span><span style="color: #000000">-</span><span style="color: #000000">mapping</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #000000">&lt;</span><span style="color: #000000">servlet</span><span style="color: #000000">-</span><span style="color: #000000">name</span><span style="color: #000000">&gt;</span><span style="color: #000000">Dispatcher</span><span style="color: #000000">&lt;/</span><span style="color: #000000">servlet</span><span style="color: #000000">-</span><span style="color: #000000">name</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #000000">&lt;</span><span style="color: #000000">url</span><span style="color: #000000">-</span><span style="color: #000000">pattern</span><span style="color: #000000">&gt;*</span><span style="color: #000000">.</span><span style="color: #0000ff">do</span><span style="color: #000000">&lt;/</span><span style="color: #000000">url</span><span style="color: #000000">-</span><span style="color: #000000">pattern</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">servlet</span><span style="color: #000000">-</span><span style="color: #000000">mapping</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>
<p style="margin-left: 18pt; text-indent: 0cm">&nbsp;</p>
<p style="margin-left: 18pt; text-indent: 0cm"><span style="font-family: 宋体">如果没有配置</span>config.xml<span style="font-family: 宋体">文件，那么其默认的配置文件为</span>[ servlet-name ]-servlet.xml <span style="font-family: 宋体">。也就是我们这个配置的默认配置文件是</span>Dispatcher-servlet.xml</p>
<h1 style="margin-left: 18pt; text-indent: -18pt">2.web<span style="font-family: 宋体">框架的</span>xml<span style="font-family: 宋体">配置</span></h1>
<p>spring web<span style="font-family: 宋体">框架与</span>struts<span style="font-family: 宋体">最大的不同就是</span>spring web<span style="font-family: 宋体">框架根据分工，把每一种功能都定义为一种组件，所以在开发过程中需要配置的东西就非常多；</span>Spring<span style="font-family: 宋体">中分为几个角色：</span></p>
<p style="margin-left: 21pt; text-indent: -21pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 宋体">核心控制器，就是</span>web<span style="font-family: 宋体">框架的主</span> servlet<span style="font-family: 宋体">；</span></p>
<p style="margin-left: 21pt; text-indent: -21pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 宋体">业务控制器，也就是</span>struts<span style="font-family: 宋体">中的</span>action<span style="font-family: 宋体">对象；</span></p>
<p style="margin-left: 21pt; text-indent: -21pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 宋体">映射处理器，定义了访问路径如何与</span>web<span style="font-family: 宋体">的</span>xml<span style="font-family: 宋体">中的</span>bean<span style="font-family: 宋体">相匹配，就是定义了一种策略；</span></p>
<p style="margin-left: 21pt; text-indent: -21pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 宋体">视图和视图解析器，视图就是</span>jstl,velocity,xslt<span style="font-family: 宋体">等，视图解析器定义了</span>action<span style="font-family: 宋体">最终导航页面的策略；</span></p>
<p style="margin-left: 21pt; text-indent: -21pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 宋体">模型，就是</span>struts MVC<span style="font-family: 宋体">结构中的</span>model<span style="font-family: 宋体">；</span></p>
<p style="margin-left: 21pt; text-indent: -21pt"><span style="font-family: Wingdings">l&nbsp;</span>Command<span style="font-family: 宋体">对象，类似于</span>struts<span style="font-family: 宋体">中的</span>formBean<span style="font-family: 宋体">；</span></p>
<h2>2.1 Spring web<span style="font-family: 宋体">框架与</span>struts<span style="font-family: 宋体">框架的区别</span></h2>
<p><span style="font-family: 宋体">下面列出了一些。例如，</span></p>
<p style="margin-left: 21pt; text-indent: -21pt"><span style="font-family: Wingdings">n&nbsp;</span>Web<span style="font-family: 宋体">框架要拦截</span>*.do<span style="font-family: 宋体">路径，那么</span>*.do<span style="font-family: 宋体">如何与我们下面的</span>bean<span style="font-family: 宋体">匹配，就需要一个映射控制器。在</span>struts<span style="font-family: 宋体">中就是名字相同的匹配，不需要配置。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt"><span style="font-family: Wingdings">n&nbsp;</span>action<span style="font-family: 宋体">最后要导向到不同的页面，在</span>struts<span style="font-family: 宋体">中我们用的是默认的不需要在</span>xml<span style="font-family: 宋体">文件中配置，在</span>spring<span style="font-family: 宋体">中就需要配置视图解析器。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt"><span style="font-family: Wingdings">n&nbsp;</span><span style="font-family: 宋体">下面代码中，</span>Action<span style="font-family: 宋体">中</span><span style="font-family: 'Courier New'">commandClass</span><span style="font-family: 宋体">配置的就是类似于</span><span style="font-family: 'Courier New'">struts</span><span style="font-family: 宋体">中的</span><span style="font-family: 'Courier New'">formBean</span><span style="font-family: 宋体">对象。<br />
</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #008080">&nbsp;1</span><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&lt;?</span><span style="color: #000000">xml&nbsp;version</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">1.0</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;encoding</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">UTF-8</span><span style="color: #000000">"</span><span style="color: #000000">?&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&lt;!</span><span style="color: #000000">DOCTYPE&nbsp;beans&nbsp;PUBLIC&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">-//SPRING//DTD&nbsp;BEAN//EN</span><span style="color: #000000">"</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">http://www.springframework.org/dtd/spring-beans.dtd</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&lt;</span><span style="color: #000000">beans</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">&lt;!--</span><span style="color: #000000">Definition&nbsp;of&nbsp;View&nbsp;Resolver&nbsp;</span><span style="color: #000000">--&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">bean&nbsp;id</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">viewResolver</span><span style="color: #000000">"</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">org.springframework.web.servlet.view.InternalResourceViewResolver</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">property&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">viewClass</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">value</span><span style="color: #000000">&gt;</span><span style="color: #000000">org.springframework.web.servlet.view.JstlView</span><span style="color: #000000">&lt;/</span><span style="color: #000000">value</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">property</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">property&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">prefix</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">value</span><span style="color: #000000">&gt;/</span><span style="color: #000000">WEB</span><span style="color: #000000">-</span><span style="color: #000000">INF</span><span style="color: #000000">/</span><span style="color: #000000">view</span><span style="color: #000000">/&lt;/</span><span style="color: #000000">value</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">property</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">property&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">suffix</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">15</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">value</span><span style="color: #000000">&gt;</span><span style="color: #000000">.jsp</span><span style="color: #000000">&lt;/</span><span style="color: #000000">value</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">property</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">bean</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">18</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;<br />
</span><span style="color: #008080">19</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&lt;!</span><span style="color: #000000">—就是我们上面说的映射控制器&nbsp;</span><span style="color: #000000">--&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">20</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">&lt;!--</span><span style="color: #000000">Request&nbsp;Mapping&nbsp;</span><span style="color: #000000">--&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">21</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">bean&nbsp;id</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">urlMapping</span><span style="color: #000000">"</span><span style="color: #000000"><br />
</span><span style="color: #008080">22</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">org.springframework.web.servlet.handler.SimpleUrlHandlerMapping</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">23</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">property&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">mappings</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">24</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">props</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">25</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">prop&nbsp;key</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">/login.do</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">LoginAction</span><span style="color: #000000">&lt;/</span><span style="color: #000000">prop</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">26</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">props</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">27</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">property</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">28</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">bean</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">29</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;<br />
</span><span style="color: #008080">30</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&lt;!---</span><span style="color: #000000">类似于struts的action配置</span><span style="color: #000000">--&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">31</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">&lt;!---</span><span style="color: #000000">Action&nbsp;Definition</span><span style="color: #000000">--&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">32</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">bean&nbsp;id</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">LoginAction</span><span style="color: #000000">"</span><span style="color: #000000"><br />
</span><span style="color: #008080">33</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">com.maxway.action.LoginAction</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">34</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">property&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">commandClass</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">35</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">value</span><span style="color: #000000">&gt;</span><span style="color: #000000">com.maxway.action.LoginInfo</span><span style="color: #000000">&lt;/</span><span style="color: #000000">value</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">36</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">property</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">37</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">property&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">fail_view</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">38</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">value</span><span style="color: #000000">&gt;</span><span style="color: #000000">loginfail</span><span style="color: #000000">&lt;/</span><span style="color: #000000">value</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">39</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">property</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">40</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">property&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">success_view</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">41</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">value</span><span style="color: #000000">&gt;</span><span style="color: #000000">main</span><span style="color: #000000">&lt;/</span><span style="color: #000000">value</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">42</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">property</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">43</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">bean</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">44</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&lt;/</span><span style="color: #000000">beans</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">45</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<p style="margin-left: 21pt; text-indent: -21pt"><br />
</span></p>
<h1 style="margin-left: 18pt; text-indent: -18pt">&nbsp;</h1>
<h1 style="margin-left: 18pt; text-indent: -18pt">3.<span style="font-family: 宋体">代码的编写</span></h1>
<p style="margin-left: 18pt; text-indent: 0cm">Action<span style="font-family: 宋体">不外乎继承一些现成的类，来实现我们</span>view<span style="font-family: 宋体">部分的业务。<br />
<span style="font-family: 宋体">作者：<a href="http://www.blogjava.net/asktalk">http://www.blogjava.net/asktalk</a></span></span></p>
<img src ="http://Architects.blogjava.net/aggbug/170198.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/asktalk/" target="_blank">Asktalk</a> 2007-12-25 02:23 <a href="http://www.blogjava.net/asktalk/archive/2007/12/25/asktalk.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Eclipse启动机制（1）</title><link>http://www.blogjava.net/asktalk/archive/2007/12/22/169593.html</link><dc:creator>Asktalk</dc:creator><author>Asktalk</author><pubDate>Sat, 22 Dec 2007 08:33:00 GMT</pubDate><guid>http://www.blogjava.net/asktalk/archive/2007/12/22/169593.html</guid><description><![CDATA[&nbsp;
<p style="background: white"><span style="font-size: 10.5pt; font-family: 新宋体">最近我一直在研究</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">Eclipse</span><span style="font-size: 10.5pt; font-family: 新宋体">的架构体系，下面我们就来看看</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">Eclipse</span><span style="font-size: 10.5pt; font-family: 新宋体">的启动机制吧</span></p>
<p style="background: white"><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">1</span><span style="font-size: 10.5pt; font-family: 新宋体">、</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">Eclipse</span><span style="font-size: 10.5pt; font-family: 新宋体">源代码</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
eclipse-sourceBuild-srcIncluded-3.3.1.1.zip&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10.5pt; font-family: 新宋体">版本：</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">3.3.1.1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10.5pt; font-family: 新宋体">大小：</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">95.058MB<br />
</span><span style="font-size: 10.5pt; font-family: 新宋体">下载地址：</span><a href="http://download.eclipse.org/eclipse/downloads"><span style="font-size: 10.5pt; color: windowtext; font-family: 'Arial','sans-serif'; text-decoration: none; text-underline: none">http://download.eclipse.org/eclipse/downloads</a></span></p>
<p style="background: white">解压后的目录结构如下图，通过执行build.bat可以编译出完整的Eclipse-sdk-3.3.1.1运行包，和我们网上下载的一样。但是这个过程可能需要一个小时左右的时间，要有耐性哦。所有的插件工程目录在plugins中，我们只需要导入现有工程即可把plugins下所有工程导入。<br />
<img height="567" alt="" src="http://www.blogjava.net/images/blogjava_net/asktalk/eclipse1.jpg" width="446" border="0" /><br />
</p>
<p style="background: white"><span style="font-size: 10.5pt; font-family: 新宋体">下面我们就先来研究一下</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">Eclipse</span><span style="font-size: 10.5pt; font-family: 新宋体">最核心的部分，就是</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">RCP</span><span style="font-size: 10.5pt; font-family: 新宋体">部分必须的插件。下面我列出了</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">Eclipse RCP</span><span style="font-size: 10.5pt; font-family: 新宋体">需要的插件。<br />
<img height="348" alt="" src="http://www.blogjava.net/images/blogjava_net/asktalk/eclipse.jpg" width="435" border="0" /><br />
</span></p>
<p style="background: white"><span style="font-size: 10.5pt; font-family: 新宋体">将这些代码解压缩到一个空目录里，然后导入到</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">Source&nbsp;Insight</span><span style="font-size: 10.5pt; font-family: 新宋体">的</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">Project</span><span style="font-size: 10.5pt; font-family: 新宋体">里。</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<p style="background: white"><span style="font-size: 10.5pt; font-family: 新宋体">二、</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">Eclipse</span><span style="font-size: 10.5pt; font-family: 新宋体">启动过程</span></p>
<p style="background: white"><span style="font-size: 10.5pt; font-family: 新宋体">首先我们从</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">Eclipse</span><span style="font-size: 10.5pt; font-family: 新宋体">的启动过程开始分析。</span></p>
<p style="background: white"><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">1</span><span style="font-size: 10.5pt; font-family: 新宋体">、</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">exe</span><span style="font-size: 10.5pt; font-family: 新宋体">部分的引导</span></p>
<p style="background: white"><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">eclipse.exe</span><span style="font-size: 10.5pt; font-family: 新宋体">是</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">Eclipse</span><span style="font-size: 10.5pt; font-family: 新宋体">的启动文件，是与平台相关的可执行文件。它的功能比较简单，主要是加载</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">startup.jar</span><span style="font-size: 10.5pt; font-family: 新宋体">文件，代码在</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">Eclipse</span><span style="font-size: 10.5pt; font-family: 新宋体">源代码的</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">eclipse-sourceBuild-srcIncluded-3.3.1.1"plugins"org.eclipse.platform"launchersrc.zip</span><span style="font-size: 10.5pt; font-family: 新宋体">，对应多个平台。对于</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">win32</span><span style="font-size: 10.5pt; font-family: 新宋体">平台，你可以直接运行</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">win32</span><span style="font-size: 10.5pt; font-family: 新宋体">目录下的</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">build.bat</span><span style="font-size: 10.5pt; font-family: 新宋体">文件来编译得到它（需要安装</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">C</span><span style="font-size: 10.5pt; font-family: 新宋体">编译器）。</span></p>
<p style="background: white"><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">2</span><span style="font-size: 10.5pt; font-family: 新宋体">、</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">java</span><span style="font-size: 10.5pt; font-family: 新宋体">代码部分的执行入口</span></p>
<p style="background: white"><span style="font-size: 10.5pt; font-family: 新宋体">对于</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">Eclipse 3.3.1.1</span><span style="font-size: 10.5pt; font-family: 新宋体">版本来说，如果在</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">eclipse</span><span style="font-size: 10.5pt; font-family: 新宋体">目录下没有找到</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">startup.jar</span><span style="font-size: 10.5pt; font-family: 新宋体">，则直接执行</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">org.eclipse.equinox.launcher.Main.main</span><span style="font-size: 10.5pt; font-family: 新宋体">方法。</span></p>
<p style="background: white"><span style="font-size: 10.5pt; font-family: 新宋体">当然我们可以在</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">eclipse</span><span style="font-size: 10.5pt; font-family: 新宋体">目录下定制我们自己的启动引导包</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">startup.jar</span><span style="font-size: 10.5pt; font-family: 新宋体">，现在</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">Eclipse 3.3.1.1</span><span style="font-size: 10.5pt; font-family: 新宋体">好像已经不建议这样做了。如果有这个包，那么这个包将是</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">java</span><span style="font-size: 10.5pt; font-family: 新宋体">代码的执行入口，你可以在命令行下运行</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">java -jar startup.jar</span><span style="font-size: 10.5pt; font-family: 新宋体">命令来启动</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">Eclipse</span><span style="font-size: 10.5pt; font-family: 新宋体">。它的入口是</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">org.eclipse.core.launcher.Main</span><span style="font-size: 10.5pt; font-family: 新宋体">类，这个类最终执行的还是</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">org.eclipse.equinox.launcher.Main.main</span><span style="font-size: 10.5pt; font-family: 新宋体">方法。它对应的源代码在</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">org.eclipse.equinox.launcher</span><span style="font-size: 10.5pt; font-family: 新宋体">目录下的</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">Main.java</span><span style="font-size: 10.5pt; font-family: 新宋体">。关于此文件的定制详细信息请查看</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">eclipse-sourceBuild-srcIncluded-3.3.1.1"plugins"org.eclipse.platform"launchersrc.zip</span><span style="font-size: 10.5pt; font-family: 新宋体">中的</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">eclipse.c</span><span style="font-size: 10.5pt; font-family: 新宋体">的注解部分。<br />
<br />
<span style="font-size: 10.5pt; font-family: 新宋体">我们从</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">main</span><span style="font-size: 10.5pt; font-family: 新宋体">函数往后跟踪，找到</span><span style="font-size: 10.5pt; font-family: 'Arial','sans-serif'">basicRun</span><span style="font-size: 10.5pt; font-family: 新宋体">方法，这个是启动的主要部分。</span><br />
</span></p>
<p style="background: white">
<table cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 9pt; color: #7f0055; font-family: 'Arial','sans-serif'">protected</span></strong><strong><span style="font-size: 9pt; color: #7f0055; font-family: 'Arial','sans-serif'">void</span></strong><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'"> basicRun(String[] args) </span><strong><span style="font-size: 9pt; color: #7f0055; font-family: 'Arial','sans-serif'">throws</span></strong><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'"> Exception {</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.<em>getProperties</em>().put(</span><span style="font-size: 9pt; color: #2a00ff; font-family: 'Arial','sans-serif'">"eclipse.startTime"</span><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">, Long.<em>toString</em>(System.<em>currentTimeMillis</em>())); </span><span style="font-size: 9pt; color: #3f7f5f; font-family: 'Arial','sans-serif'">//$NON-NLS-1$</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 9pt; color: #0000c0; font-family: 'Arial','sans-serif'">commands</span><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'"> = args;</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String[] passThruArgs = processCommandLine(args);</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 9pt; color: #7f0055; font-family: 'Arial','sans-serif'">if</span></strong><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'"> (!</span><span style="font-size: 9pt; color: #0000c0; font-family: 'Arial','sans-serif'">debug</span><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">)</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </span><span style="font-size: 9pt; color: #3f7f5f; font-family: 'Arial','sans-serif'">// debug can be specified as system property as well</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </span><span style="font-size: 9pt; color: #0000c0; font-family: 'Arial','sans-serif'">debug</span><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'"> = System.<em>getProperty</em>(</span><em><span style="font-size: 9pt; color: #0000c0; font-family: 'Arial','sans-serif'">PROP_DEBUG</span></em><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">) != </span><strong><span style="font-size: 9pt; color: #7f0055; font-family: 'Arial','sans-serif'">null</span></strong><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">;</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setupVMProperties();&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 'Arial','sans-serif'">//</span><span style="font-family: 新宋体">设置</span><span style="font-family: 'Arial','sans-serif'">VM</span><span style="font-family: 新宋体">属性</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processConfiguration();&nbsp;&nbsp; </span><span style="font-family: 'Arial','sans-serif'">//</span><span style="font-family: 新宋体">读取</span><span style="font-family: 'Arial','sans-serif'">configuration/config.ini</span><span style="font-family: 新宋体">配置文件</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 9pt; color: #3f7f5f; font-family: 'Arial','sans-serif'">// need to ensure that getInstallLocation is called at least once to initialize the value.</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 9pt; color: #3f7f5f; font-family: 'Arial','sans-serif'">// Do this AFTER processing the configuration to allow the configuration to set</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 9pt; color: #3f7f5f; font-family: 'Arial','sans-serif'">// the install location.&nbsp;</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getInstallLocation();</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 9pt; color: #3f7f5f; font-family: 'Arial','sans-serif'">// locate boot plugin (may return -dev mode variations)</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; URL[] bootPath = getBootPath(</span><span style="font-size: 9pt; color: #0000c0; font-family: 'Arial','sans-serif'">bootLocation</span><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">);</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 9pt; color: #3f7f5f; font-family: 'Arial','sans-serif'">//Set up the JNI bridge.&nbsp;We need to know the install location to find the shared library</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setupJNI(bootPath);</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 9pt; color: #3f7f5f; font-family: 'Arial','sans-serif'">//ensure minimum Java version, do this after JNI is set up so that we can write an error message </span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 9pt; color: #3f7f5f; font-family: 'Arial','sans-serif'">//with exitdata if we fail.</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 9pt; color: #7f0055; font-family: 'Arial','sans-serif'">if</span></strong><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'"> (!checkVersion(System.<em>getProperty</em>(</span><span style="font-size: 9pt; color: #2a00ff; font-family: 'Arial','sans-serif'">"java.version"</span><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">), System.<em>getProperty</em>(</span><em><span style="font-size: 9pt; color: #0000c0; font-family: 'Arial','sans-serif'">PROP_REQUIRED_JAVA_VERSION</span></em><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">))) </span><span style="font-size: 9pt; color: #3f7f5f; font-family: 'Arial','sans-serif'">//$NON-NLS-1$</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 9pt; color: #7f0055; font-family: 'Arial','sans-serif'">return</span></strong><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">;</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setSecurityPolicy(bootPath);&nbsp;</span><span style="font-family: 'Arial','sans-serif'">//</span><span style="font-family: 新宋体">设置执行权限</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 9pt; color: #3f7f5f; font-family: 'Arial','sans-serif'">// splash handling is done here, because the default case needs to know</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 9pt; color: #3f7f5f; font-family: 'Arial','sans-serif'">// the location of the boot plugin we are going to use</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; handleSplash(bootPath);</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; beforeFwkInvocation();</span></p>
            <p style="text-align: left" align="left"><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invokeFramework(passThruArgs, bootPath);&nbsp;&nbsp;&nbsp; </span><span style="font-family: 'Arial','sans-serif'">//</span><span style="font-family: 新宋体">启动</span><span style="font-family: 'Arial','sans-serif'">Eclipse</span><span style="font-family: 新宋体">内核</span></p>
            <p><span style="font-size: 9pt; color: black; font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; }</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<img src ="http://Architects.blogjava.net/aggbug/169593.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/asktalk/" target="_blank">Asktalk</a> 2007-12-22 16:33 <a href="http://www.blogjava.net/asktalk/archive/2007/12/22/169593.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>代码之外的结构</title><link>http://www.blogjava.net/canonical/archive/2007/12/15/167994.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sat, 15 Dec 2007 11:46:00 GMT</pubDate><guid>http://www.blogjava.net/canonical/archive/2007/12/15/167994.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp; 我在各种场合一直都在强调结构问题是独立的，在程序语言之外存在着独立的，可研究的，富有成效的结构问题。<a href="http://canonical.javaeye.com/blog/147424 ">http://canonical.javaeye.com/blog/147424 </a>在这个方向上更进一步，我们注意到所有的代码并不是天然出现的，而是由人所编制的，因此代码世界内部并不构成封闭的，自足的某个世界。代码中的结构问题并不是由代码本身完全解决的，即在代码之外仍然存在着技术上可研究的结构问题。<br />
&nbsp;&nbsp;&nbsp; 我们在编制代码的同时也在编制着大量的说明文档。这些文档描述了代码片断之间的相互关系，描述了代码未来的扩展方向，描述了代码之间的可能的交互方式，同时也描述了针对现有代码实现的很多具体约束。例如我们在文档中约定某个量要在10和20之间，但在代码中却不一定显式进行了判断。针对代码结构的很多具体约束条件和相关性描述可能只在文档中体现，只在程序员的头脑中存在，而并不一定忠实的在代码结构中得到表达。<br />
&nbsp;&nbsp;&nbsp; 我在设计领域基本持有一种物理实在论，即某种技术相关的约束应该在技术世界中通过技术手段得到表达。只是这里的技术手段却不一定指在应用中加上特定的代码实现，虽然我们在代码实现中更直接的表达设计要求无疑是需要提倡的。为了在程序中有效的维护结构相关性，我们并不一定需要抽象出所有可能重用的代码，并不一定需要确保某一概念在程序中只有精确的唯一的表达。程序中难以直接精确表达的弱关联，仍然可以通过开发/设计工具等技术手段得到有效的维护。我们需要保证的是代码世界中知识的自恰性，而自恰性并不等于唯一性。<a href="http://canonical.javaeye.com/blog/33788">http://canonical.javaeye.com/blog/33788</a><br />
&nbsp;&nbsp;&nbsp; 在Witrix中我们采用一种物理模型驱动的开发方式，<a href="http://canonical.javaeye.com/blog/29412">http://canonical.javaeye.com/blog/29412</a> 由pdm模型出发，自动生成hibernate的hbm文件，java实体类，元数据meta文件，前台Action注册文件等。生成的配置文件通过syncWithModel标记与模型保持着稳定的关联。所有配置文件都支持手工修改，开发工具识别syncWithModel标记，当pdm模型发生变化的时候，工具自动将变化信息同步到各个配置文件中。注意到这里并不是采用一个统一的元数据模型的方式，各个配置文件所表达的信息在一定程度上是重复的，也可能是不一致的。例如后台数据库允许保存100个字节，但是前台meta中我们可能配置只允许录入20个字节。根据不同应用场景的需要，我们可以在各个层面对每个配置文件进行独立的调节. 当然,在一般情况下并不存在这种需要。整个开发过程中，信息表达的自恰性并不是在应用程序代码中得到定义的,而是因为开发工具的存在而在技术上得到保证的。放松模型之间的唯一匹配要求，我们可以得到更加丰富，更加灵活的软件结构。实际上我认为RoR(RubyOnRails)采用直接映射的ActiveRecord的方式虽然有效保证了系统变动中知识的一致性，但是如果不允许在各个层面上都能够自然的定义某种偏离，它在复杂应用中的价值就要打上大大的折扣。<br />
<br />
<img src ="http://Architects.blogjava.net/aggbug/167994.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:n