<?xml version="1.0" encoding="gb2312"?>

<!-- RSS generated by oioj.net on 4/16/2004 ; 感谢LeXRus提供 RSS 2.0 文档; 此文件可自由使用，但请保留此行信息 --> 
<!-- Source download URL: http://blogger.org.cn/blog/rss2.asp       -->
<rss version="2.0">

<channel>
<title>玻璃杯中的花生壳</title>
<link>http://blogger.org.cn/blog/blog.asp?name=littcricket</link>
<description>玻璃杯中的花生壳的博客</description>
<copyright>blogger.org.cn</copyright>
<generator>W3CHINA Blog</generator>
<webMaster>webmaster@blogger.org.cn</webMaster>
<item>
<title><![CDATA[Java开发者的十大戒律]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=30041</link>
<author>littcricket</author>
<pubDate>2007/11/27 18:26:08</pubDate>
<description><![CDATA[<A>　有许多标准和实践准则可适用于Java<NOBR><B class=kgb onmouseover='isShowAds = true;isShowAds2 = true;KeyGate_ads.Move(this,"","","-100835","开发","ROR%u5E94%u7528%u63A2%u7D22","http%3A//www.sd2china.cn/track1.html", event)' style="BORDER-TOP-WIDTH: 0px; FONT-WEIGHT: normal; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; CURSOR: hand; COLOR: #0000ff; BORDER-RIGHT-WIDTH: 0px; TEXT-DECORATION: underline" onclick='javascript:window.open("http://s4.17luntan.com/ClickPortal/WebClick.aspx?id=-100835&amp;k=%u5F00%u53D1&amp;siteid=0098295a-e262-40f7-ae50-7a6fbbdb678b&amp;url=http%3A//news.csdn.net/n/20071126/111088.html&amp;gourl=http%3A//www.sd2china.cn/track1.html&amp;parm=0DBA12E7BFB3CA37E6613C283B270E4571045B59146C1F31&amp;alliedsiteid=0");' onmouseout="isShowAds = false;isShowAds2 = false">开发</B></NOBR>者，但此处要说的，是每个Java开发者需坚守的基本原则。
<P>　　<STRONG>一、为<NOBR><B class=kgb onmouseover='isShowAds = false;isShowAds2 = false;isShowGg = true;InTextAds_GgLayer="_u4EE3_u7801";KeyGate_ads.ShowGgAds(this,"_u4EE3_u7801",event)' style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-WEIGHT: normal; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; CURSOR: hand; COLOR: #0000ff; PADDING-TOP: 0px; BORDER-RIGHT-WIDTH: 0px; TEXT-DECORATION: underline" onclick='javascript:window.open("http://pagead2.googlesyndication.com/pagead/iclk?sa=l&amp;ai=BHLjewu9LR8XBO5P26AOtndD6CbLP4xb6pILgAsCNtwHw_TkQARgBIIL2kgsoFDgAUKGm3LwFYNkCqgEKMjAwMDAxNjEyM7IBDW5ld3MuY3Nkbi5uZXTIAQHaAStodHRwOi8vbmV3cy5jc2RuLm5ldC9uLzIwMDcxMTI2LzExMTA4OC5odG1sqQIlK5SyZT-BPsgCiraEAqgDAegD9QLoAwXoAyD1AwAEAAA&amp;num=1&amp;adurl=http://www.meichong.biz.com.hk&amp;client=ca-pub-7244513001137299");GgKwClickStat("代码","www.meichong.biz.com.hk","afc","2000016123");' onmouseout='isShowGg = false;InTextAds_GgLayer="_u4EE3_u7801"'>代码</B></NOBR>加注释</STRONG>。虽然每个人都知道这点，但有时却不自觉忘了履行，今天你“忘了”加注释了吗?虽然注释对 程序的功能没什么“贡献”，但过一段时间，比如说两星期之后或者更长，回过头来看看自己的代码，说不定已经记不住它是干什么的了。如果这些代码是你个人 的，那还算是走运了，不幸的是，当然了，大多数时候都是别人的不幸，很多时候大家都是在为<NOBR><B class=kgb onmouseover='isShowAds = false;isShowAds2 = false;isShowGg = true;InTextAds_GgLayer="_u516C_u53F8";KeyGate_ads.ShowGgAds(this,"_u516C_u53F8",event)' style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-WEIGHT: normal; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; CURSOR: hand; COLOR: #0000ff; PADDING-TOP: 0px; BORDER-RIGHT-WIDTH: 0px; TEXT-DECORATION: underline" onclick='javascript:window.open("http://pagead2.googlesyndication.com/pagead/iclk?sa=l&amp;ai=BHLjewu9LR8XBO5P26AOtndD6CbLP4xb6pILgAsCNtwHw_TkQARgBIIL2kgsoFDgAUKGm3LwFYNkCqgEKMjAwMDAxNjEyM7IBDW5ld3MuY3Nkbi5uZXTIAQHaAStodHRwOi8vbmV3cy5jc2RuLm5ldC9uLzIwMDcxMTI2LzExMTA4OC5odG1sqQIlK5SyZT-BPsgCiraEAqgDAegD9QLoAwXoAyD1AwAEAAA&amp;num=1&amp;adurl=http://www.meichong.biz.com.hk&amp;client=ca-pub-7244513001137299");GgKwClickStat("公司","www.meichong.biz.com.hk","afc","2000016123");' onmouseout='isShowGg = false;InTextAds_GgLayer="_u516C_u53F8"'>公司</B></NOBR>写代码，写代码的人也许早已经离开了公司，但别忘了一句古 话，有来有往嘛，为他人，也为我们自己，请为你的代码加上注释。</P>
<P>　　<STRONG>二、不要让事情复杂化</STRONG>。<NOBR><B class=kgb onmouseover='isShowAds = false;isShowAds2 = false;isShowGg = true;InTextAds_GgLayer="_u7A0B_u5E8F_u5458";KeyGate_ads.ShowGgAds(this,"_u7A0B_u5E8F_u5458",event)' style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-WEIGHT: normal; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; CURSOR: hand; COLOR: #0000ff; PADDING-TOP: 0px; BORDER-RIGHT-WIDTH: 0px; TEXT-DECORATION: underline" onclick='javascript:window.open("http://pagead2.googlesyndication.com/pagead/iclk?sa=l&amp;ai=BsJSxwu9LR8XBO5P26AOtndD6CYbOlDT625C1BMCNtwGgnAEQDxgPIIL2kgsoFDgAUJPGq-j7_____wFg2QKqAQoyMDAwMDE2MTIzsgENbmV3cy5jc2RuLm5ldMgBAdoBK2h0dHA6Ly9uZXdzLmNzZG4ubmV0L24vMjAwNzExMjYvMTExMDg4Lmh0bWyAAgGpAuKJSsceKoI-qAMB6AP1AugDBegDIPUDAAQAAA&amp;num=15&amp;adurl=http://www.china-brand.net/aboutus/giftInfo.php%3Fid%3D2110&amp;client=ca-pub-7244513001137299");GgKwClickStat("程序员","www.china-brand.net","afc","2000016123");' onmouseout='isShowGg = false;InTextAds_GgLayer="_u7A0B_u5E8F_u5458"'>程序员</B></NOBR>有时候总是对简单问题想出复杂的<NOBR><B class=kgb onmouseover='isShowAds = true;isShowAds2 = true;KeyGate_ads.Move(this,"","","-100840","解决方案","OSS%u5546%u52A1%20%u2013%20ZK%u65B9%u5F0F","http%3A//www.sd2china.cn/track1.html", event)' style="BORDER-TOP-WIDTH: 0px; FONT-WEIGHT: normal; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; CURSOR: hand; COLOR: #0000ff; BORDER-RIGHT-WIDTH: 0px; TEXT-DECORATION: underline" onclick='javascript:window.open("http://s4.17luntan.com/ClickPortal/WebClick.aspx?id=-100840&amp;k=%u89E3%u51B3%u65B9%u6848&amp;siteid=0098295a-e262-40f7-ae50-7a6fbbdb678b&amp;url=http%3A//news.csdn.net/n/20071126/111088.html&amp;gourl=http%3A//www.sd2china.cn/track1.html&amp;parm=0DBA12E7BFB3CA37E6613C283B270E4571045B59146C1F31&amp;alliedsiteid=0");' onmouseout="isShowAds = false;isShowAds2 = false">解决方案</B></NOBR>，比如说，在只有五个用户的程序中引 入EJB、对程序实现了并不需要的框架(framework)，之类的还有属性文件、面向对象解决方案、多线程等等。为什么要这样做呢?也许我们并不知道 是否这样会更好，但这样做也许可以学到一些新东西，或者让自己更感兴趣一些。如果是不知道为什么这样做，建议多请教经验丰富的程序员，如果是为了个人的目 的，麻烦让自己更专业一点。</P>
<P>　　<STRONG>三、始终牢记</STRONG>——“少即是好(Less is more)并不总是对的”。代码效率虽然很重要，但在许多解决方案中，编写更少的代码并不能改善这些代码的效率，请看下面这个简单的例子：</P>
<P></P>
<TABLE style="BORDER-RIGHT: rgb(204,204,204) 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: rgb(204,204,204) 1px dotted; BORDER-LEFT: rgb(204,204,204) 1px dotted; BORDER-BOTTOM: rgb(204,204,204) 1px dotted" cellSpacing=0 cellPadding=6 width="95%" align=center border=0>
<TBODY>
<TR>
<TD bgColor=#f3f3f3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(newStatusCode.equals("SD")&nbsp;&amp;&amp;&nbsp;(sellOffDate&nbsp;==&nbsp;null&nbsp;|| <BR>todayDate.compareTo(sellOffDate)&lt;0&nbsp;||&nbsp;(lastUsedDate&nbsp;!=&nbsp;null&nbsp;&amp;&amp; <BR>todayDate.compareTo(lastUsedDate)&gt;0))&nbsp;|| <BR>(newStatusCode.equals("OBS")&nbsp;&amp;&amp;&nbsp;(OBSDate&nbsp;==&nbsp;null&nbsp;|| <BR>todayDate.compareTo(OBSDate)&lt;0))){ <BR>newStatusCode&nbsp;=&nbsp;"NYP"; <BR>}</TD></TR></TBODY></TABLE>
<P>　　能看明白if条件语句是干什么的吗?能想出来是谁写的这段代码吗?如果把它分成两段独立的if语句，是不是更容易理解呢，下面是修改后的代码：</P>
<P></P>
<TABLE style="BORDER-RIGHT: rgb(204,204,204) 1px dotted; TABLE-LAYOUT: auto; BORDER-TOP: rgb(204,204,204) 1px dotted; BORDER-LEFT: rgb(204,204,204) 1px dotted; BORDER-BOTTOM: rgb(204,204,204) 1px dotted" cellSpacing=0 cellPadding=6 width="95%" align=center border=0>
<TBODY>
<TR>
<TD bgColor=#f3f3f3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(newStatusCode.equals("SD")&nbsp;&amp;&amp;&nbsp;(sellOffDate&nbsp;==&nbsp;null&nbsp;|| <BR>todayDate.compareTo(sellOffDate)&lt;0&nbsp;||&nbsp;(lastUsedDate&nbsp;!=&nbsp;null&nbsp;&amp;&amp; <BR>todayDate.compareTo(lastUsedDate)&gt;0))){ <BR>newStatusCode&nbsp;=&nbsp;"NYP"; <BR>}else <BR>if(newStatusCode.equals("OBS")&nbsp;&amp;&amp;&nbsp;(OBSDate&nbsp;==&nbsp;null&nbsp;|| <BR>todayDate.compareTo(OBSDate)&lt;0)) <BR>{ <BR>newStatusCode&nbsp;=&nbsp;"NYP"; <BR>}</TD></TR></TBODY></TABLE>
<P>　　是不是读起来容易多了呢，在此只是多加了一个if和两个花括号，但代码的可读性与可理解性就一下子提高了一大截。</P>
<P>　　<STRONG>四、请不要硬编码</STRONG>。开发者经常有意“忘记”或忽略掉这点，因为有些时候开发日程逼得实在太紧。其实，多写一行定义静态变量的代码能花多少时间呢?</P>
<P></P>
<TABLE style="BORDER-RIGHT: rgb(204,204,204) 1px dotted; TABLE-LAYOUT: auto; BORDER-TOP: rgb(204,204,204) 1px dotted; BORDER-LEFT: rgb(204,204,204) 1px dotted; BORDER-BOTTOM: rgb(204,204,204) 1px dotted" cellSpacing=0 cellPadding=6 width="95%" align=center border=0>
<TBODY>
<TR>
<TD bgColor=#f3f3f3><STRONG><FONT color=#990000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></STRONG>public&nbsp;class&nbsp;A&nbsp;{ <BR>public&nbsp;static&nbsp;final&nbsp;String&nbsp;S_CONSTANT_ABC&nbsp;=&nbsp;"ABC"; <BR>public&nbsp;boolean&nbsp;methodA(String&nbsp;sParam1){ <BR>if&nbsp;(A.S_CONSTANT_ABC.equalsIgnoreCase(sParam1)){ <BR>return&nbsp;true; <BR>} <BR>return&nbsp;false; <BR>} <BR>}</TD></TR></TBODY></TABLE>
<P>　　现在，每次需要将“ABC”与其他变量进行比较时，不必记住实际代码，直接引用A.S_CONSTANT_ABC就行了，而且在今后需要进行修改时，也可在一处修改，不会翻遍整个源代码逐个修改了。</P>
<P>　　<STRONG>五、不要“创造”自己的框架(framework)。</STRONG>确切来说，有数以千计的各种框架存在，而且大多数是开 源的，这些框架都是优秀的解决方案，可用于日常程序开发中，我们只需使用这些框架的最新版本就行了，至少表面上要跟上形势吧。被大家广为接受的最为明显的 一个例子就是Struts了，这个开源web框架非常适合用在基于web的应用程序中。是不是想开发出自己的Struts呢，还是省点力气吧，回头看看第 二条——不要让事情复杂化。另外，如果正在开发的程序只有3个窗口，就不要使用Struts了，对这种程序来说，不需要那么多的“控制”。</P>
<P>　　<STRONG>六、不要使用println及字符串连接</STRONG>。通常为了调试方便，开发者喜欢在可能的所有地方都加上 System.out.println，也许还会提醒自己回过头来再来删除，但有些时候，经常会忘了删除或者不愿意删除它们。既然使用 System.out.println是为了测试，那么测试完之后，为什么还要留着它们呢，因为在删除时，很可能会删除掉真正有用的代码，所以不能低估 System.out.println危害啊，请看下面的代码：</P>
<P></P>
<TABLE style="BORDER-RIGHT: rgb(204,204,204) 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: rgb(204,204,204) 1px dotted; BORDER-LEFT: rgb(204,204,204) 1px dotted; BORDER-BOTTOM: rgb(204,204,204) 1px dotted" cellSpacing=0 cellPadding=6 width="95%" align=center border=0>
<TBODY>
<TR>
<TD bgColor=#f3f3f3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public&nbsp;class&nbsp;BadCode&nbsp;{ <BR>public&nbsp;static&nbsp;void&nbsp;calculationWithPrint(){ <BR>double&nbsp;someValue&nbsp;=&nbsp;0D; <BR>for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;10000;&nbsp;i++)&nbsp;{ <BR>System.out.println(someValue&nbsp;=&nbsp;someValue&nbsp;+&nbsp;i); <BR>} <BR>} <BR>public&nbsp;static&nbsp;void&nbsp;calculationWithOutPrint(){ <BR>double&nbsp;someValue&nbsp;=&nbsp;0D; <BR>for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;10000;&nbsp;i++)&nbsp;{ <BR>someValue&nbsp;=&nbsp;someValue&nbsp;+&nbsp;i; <BR>} <BR>} <BR>public&nbsp;static&nbsp;void&nbsp;main(String&nbsp;[]&nbsp;n)&nbsp;{ <BR>BadCode.calculationWithPrint(); <BR>BadCode.calculationWithOutPrint(); <BR>} <BR>}</TD></TR></TBODY></TABLE>
<P>　　从测试中可以发现，方法calculationWithOutPrint()执行用了0.001204秒，作为对比，方法calculationWithPrint()执行可是用了10.52秒。</P>
<P>　　要避免浪费CPU时间，最好的方法是引入像如下的包装方法：</P>
<P></P>
<TABLE style="BORDER-RIGHT: rgb(204,204,204) 1px dotted; TABLE-LAYOUT: auto; BORDER-TOP: rgb(204,204,204) 1px dotted; BORDER-LEFT: rgb(204,204,204) 1px dotted; BORDER-BOTTOM: rgb(204,204,204) 1px dotted" cellSpacing=0 cellPadding=6 width="95%" align=center border=0>
<TBODY>
<TR>
<TD bgColor=#f3f3f3>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public&nbsp;class&nbsp;BadCode&nbsp;{ <BR>public&nbsp;static&nbsp;final&nbsp;int&nbsp;DEBUG_MODE&nbsp;=&nbsp;1; <BR>public&nbsp;static&nbsp;final&nbsp;int&nbsp;PRODUCTION_MODE&nbsp;=&nbsp;2; <BR>public&nbsp;static&nbsp;void&nbsp;calculationWithPrint(int&nbsp;logMode){ <BR>double&nbsp;someValue&nbsp;=&nbsp;0D; <BR>for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;10000;&nbsp;i++)&nbsp;{ <BR>someValue&nbsp;=&nbsp;someValue&nbsp;+&nbsp;i; <BR>myPrintMethod(logMode,&nbsp;someValue); <BR>} <BR>} <BR>public&nbsp;static&nbsp;void&nbsp;myPrintMethod(int&nbsp;logMode,&nbsp;double&nbsp;value)&nbsp;{ <BR>if&nbsp;(logMode&nbsp;&gt;&nbsp;BadCode.DEBUG_MODE)&nbsp;{&nbsp;return;&nbsp;} <BR>System.out.println(value); <BR>} <BR>public&nbsp;static&nbsp;void&nbsp;main(String&nbsp;[]&nbsp;n)&nbsp;{ <BR>BadCode.calculationWithPrint(BadCode.PRODUCTION_MODE); <BR>} <BR>}</P></TD></TR></TBODY></TABLE>
<P>　　另外，字符串连接也是浪费CPU时间的一个大头，请看下面的示例代码：</P>
<P></P>
<TABLE style="BORDER-RIGHT: rgb(204,204,204) 1px dotted; TABLE-LAYOUT: auto; BORDER-TOP: rgb(204,204,204) 1px dotted; BORDER-LEFT: rgb(204,204,204) 1px dotted; BORDER-BOTTOM: rgb(204,204,204) 1px dotted" cellSpacing=0 cellPadding=6 width="95%" align=center border=0>
<TBODY>
<TR>
<TD bgColor=#f3f3f3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public&nbsp;static&nbsp;void&nbsp;concatenateStrings(String&nbsp;startingString)&nbsp;{ <BR>for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;20;&nbsp;i++)&nbsp;{ <BR>startingString&nbsp;=&nbsp;startingString&nbsp;+&nbsp;startingString; <BR>} <BR>} <BR>public&nbsp;static&nbsp;void&nbsp;concatenateStringsUsingStringBuffer(String&nbsp;startingString)&nbsp;{ <BR>StringBuffer&nbsp;sb&nbsp;=&nbsp;new&nbsp;StringBuffer(); <BR>sb.append(startingString); <BR>for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;20;&nbsp;i++)&nbsp;{ <BR>sb.append(sb.toString()); <BR>} <BR>}</TD></TR></TBODY></TABLE>
<P>　　在测试中可发现，使用StringBuffer的方法只用了0.01秒执行完毕，而使用连接的方法则用了0.08秒，选择显而易见了。</P>
<P>　　<STRONG>七、多关注GUI(用户界面)。</STRONG>再三强调，GUI对商业客户来说，与程序的功能及效率同等重要，GUI是一 个成功程序的最基本部分，而很多IT经理往往都没注意到GUI的重要性。在现实生活中，许多公司可能为了节省开支，没有雇用那些有着设计“用户友好”界面 丰富经验的网页设计者，此时Java开发者只能依赖他们自身的HTML基本功及在此领域有限的知识，结果，很多开发出来的程序都是“计算机友好”甚于“用 户友好”。很少有开发者同时精通软件开发及GUI设计，如果你在公司“不幸”被分配负责程序界面，就应该遵守下面三条原则：</P>
<P>　　1、 不要再发明一次轮子，即不做无用功。现有的程序可能会有类似的界面需求。</P>
<P>　　2、 先创建一个原型。这是非常重要一步，用户一般想看到他们将使用的东西，而且可以先利用这个原型征求用户的意见，再慢慢修改成用户想要的样子。</P>
<P>　　3、 学会换位思考。换句话来说，就是从用户的角度来审查程序的需求。举例来讲，一个汇总的窗口可以跨页或者不跨页，作为一个软件开发者，可能会倾向于不跨页，因为这样简单一些。但是，从用户的角度来看，可能不希望看到上百行数据都挤在同一页上。</P>
<P>　　<STRONG>八、文档需求不放松</STRONG>。每个商业需求都必须记录在案，这可能听上去像童话，似乎在现实生活中很难实现。而我们要做的是，不管开发时间多紧迫，不管最终期限多临近，对每个商业需求都必须记录在案。</P>
<P>　　<STRONG>九、单元测试、单元测试、单元测试</STRONG>。关于什么是单元测试的最好方法，在此不便细说，只是强调，单元测试一定要完成，这也是编程中最基本的原则。当然了，如果有人帮你做单元测试自然是最好，如果没有，就自己来做吧，当创建一个单元测试计划时，请遵守以下三条最基本的原则：</P>
<P>　　1、 先于编写类代码之前编写单元测试。</P>
<P>　　2、 记录单元测试中的代码注释。</P>
<P>　　3、 测试所有执行关键功能的公有方法，这里不是指set和get方法，除非它们是以自己独特方式执行set和get方法。</P>
<P>　　<STRONG>十、质量，而不是数量</STRONG>。有些时候因为产品问题、期限紧迫、或一些预料之外的事情，导致常常不能按时下班，但一般而言，公司不会因为雇员经常加班而对之表扬和奖励，公司只看重高质量的工作。如果遵守了前九条原则，你会发现自己写出的代码bug少且可维护性高，无形中质量提高了一大步。</P></A>]]></description>
</item><item>
<title><![CDATA[配置Spring数据源]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=27916</link>
<author>littcricket</author>
<pubDate>2007/9/7 9:41:12</pubDate>
<description><![CDATA[<A>　不管通过何种持久化技术，都必须通过数据连接访问数据库，在Spring中，数据连接是通过数据源获得的。在以往的应用中，数据源一般是Web应用服务器提供的。在Spring中，你不但可以通过JNDI获取应用服务器的数据源，也可以直接在Spring容器中配置数据源，此外，你还可以通过代码的方式创建一个数据源，以便进行无依赖的单元测试
<P>配置一个数据源 <BR>&nbsp;&nbsp;&nbsp; Spring在第三方依赖包中包含了两个数据源的实现类包，其一是Apache的DBCP，其二是 C3P0。可以在Spring配置文件中利用这两者中任何一个配置数据源。</P>
<P><STRONG>&nbsp;DBCP数据源</STRONG> <BR>&nbsp;&nbsp;&nbsp; DBCP类包位于 <SPRING_HOME></SPRING_HOME>/lib/jakarta-commons/commons-dbcp.jar，DBCP是一个依赖 Jakarta commons-pool对象池机制的数据库连接池，所以在类路径下还必须包括<SPRING_HOME></SPRING_HOME>/lib/jakarta- commons/commons-pool.jar。下面是使用DBCP配置MySql数据源的配置片断：</P>
<DIV class=code_title>xml 代码</DIV>
<DIV class=dp-highlighter>
<DIV class=bar></DIV>
<OL class=dp-xml>
<LI class=alt><SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>bean</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>id</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"dataSource"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>class</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"org.apache.commons.dbcp.BasicDataSource"</SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN></SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=attribute>destroy-method</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"close"</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"driverClassName"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>value</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"com.mysql.jdbc.Driver"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=tag>/&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"url"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>value</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"jdbc:mysql://localhost:3309/sampledb"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=tag>/&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"username"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>value</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"root"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=tag>/&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"password"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>value</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"1234"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=tag>/&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN></SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>bean</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> </LI></OL></DIV>
<P>BasicDataSource提供了close()方法关闭数据源，所以必须设定destroy-method=”close”属性， 以便Spring容器关闭时，数据源能够正常关闭。除以上必须的数据源属性外，还有一些常用的属性： <BR>&nbsp;&nbsp;&nbsp; defaultAutoCommit：设置从数据源中返回的连接是否采用自动提交机制，默认值为 true； <BR>&nbsp;&nbsp;&nbsp; defaultReadOnly：设置数据源是否仅能执行只读操作， 默认值为 false； <BR>&nbsp;&nbsp;&nbsp; maxActive：最大连接数据库连接数，设置为0时，表示没有限制； <BR>&nbsp;&nbsp;&nbsp; maxIdle：最大等待连接中的数量，设置为0时，表示没有限制； <BR>&nbsp;&nbsp;&nbsp; maxWait：最大等待秒数，单位为毫秒， 超过时间会报出错误信息； <BR>&nbsp;&nbsp;&nbsp; validationQuery：用于验证连接是否成功的查询SQL语句，SQL语句必须至少要返回一行数据， 如你可以简单地设置为：“select count(*) from user”； <BR>&nbsp;&nbsp;&nbsp; removeAbandoned：是否自我中断，默认是 false ； <BR>&nbsp;&nbsp;&nbsp; removeAbandonedTimeout：几秒后数据连接会自动断开，在removeAbandoned为true，提供该值； <BR>&nbsp;&nbsp;&nbsp; logAbandoned：是否记录中断事件， 默认为 false； </P>
<P><STRONG>C3P0数据源</STRONG> <BR>&nbsp;&nbsp;&nbsp; C3P0是一个开放源代码的JDBC数据源实现项目，它在lib目录中与Hibernate一起发布，实现了JDBC3和JDBC2扩展规范说明的 Connection 和Statement 池。C3P0类包位于<SPRING_HOME></SPRING_HOME>/lib/c3p0/c3p0-0.9.0.4.jar。下面是使用C3P0配置一个 Oracle数据源：</P>
<DIV class=code_title>xml 代码</DIV>
<DIV class=dp-highlighter>
<DIV class=bar></DIV>
<OL class=dp-xml>
<LI class=alt><SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>bean</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>id</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"dataSource"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>class</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"com.mchange.v2.c3p0.ComboPooledDataSource"</SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN></SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=attribute>destroy-method</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"close"</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"driverClass"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>value</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"&nbsp;oracle.jdbc.driver.OracleDriver&nbsp;"</SPAN><SPAN class=tag>/&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"jdbcUrl"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>value</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"&nbsp;jdbc:oracle:thin:@localhost:1521:ora9i&nbsp;"</SPAN><SPAN class=tag>/&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"user"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>value</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"admin"</SPAN><SPAN class=tag>/&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"password"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>value</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"1234"</SPAN><SPAN class=tag>/&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN></SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>bean</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> </LI></OL></DIV>
<P>ComboPooledDataSource和BasicDataSource一样提供了一个用于关闭数据源的close()方法，这样我们就可以保证Spring容器关闭时数据源能够成功释放。 <BR>&nbsp;&nbsp;&nbsp; C3P0拥有比DBCP更丰富的配置属性，通过这些属性，可以对数据源进行各种有效的控制： <BR>&nbsp;&nbsp;&nbsp; acquireIncrement：当连接池中的连接用完时，C3P0一次性创建新连接的数目； <BR>&nbsp;&nbsp;&nbsp; acquireRetryAttempts：定义在从数据库获取新连接失败后重复尝试获取的次数，默认为30； <BR>&nbsp;&nbsp;&nbsp; acquireRetryDelay：两次连接中间隔时间，单位毫秒，默认为1000； <BR>&nbsp;&nbsp;&nbsp; autoCommitOnClose：连接关闭时默认将所有未提交的操作回滚。默认为false； <BR>&nbsp;&nbsp;&nbsp; automaticTestTable： C3P0将建一张名为Test的空表，并使用其自带的查询语句进行测试。如果定义了这个参数，那么属性preferredTestQuery将被忽略。你 不能在这张Test表上进行任何操作，它将中为C3P0测试所用，默认为null； <BR>&nbsp;&nbsp;&nbsp; breakAfterAcquireFailure：获取连接失败将会引起所有等待获取连接的线程抛出异常。但是数据源仍有效保留，并在下次调&nbsp;&nbsp; 用getConnection()的时候继续尝试获取连接。如果设为true，那么在尝试获取连接失败后该数据源将申明已断开并永久关闭。默认为 false； <BR>&nbsp;&nbsp;&nbsp; checkoutTimeout：当连接池用完时客户端调用getConnection()后等待获取新连接的时间，超时后将抛出SQLException，如设为0则无限期等待。单位毫秒，默认为0； <BR>&nbsp;&nbsp;&nbsp; connectionTesterClassName： 通过实现ConnectionTester或QueryConnectionTester的类来测试连接，类名需设置为全限定名。默认为 com.mchange.v2.C3P0.impl.DefaultConnectionTester；&nbsp;<BR>&nbsp;&nbsp;&nbsp; idleConnectionTestPeriod：隔多少秒检查所有连接池中的空闲连接，默认为0表示不检查； <BR>&nbsp;&nbsp;&nbsp; initialPoolSize：初始化时创建的连接数，应在minPoolSize与maxPoolSize之间取值。默认为3； <BR>&nbsp;&nbsp;&nbsp; maxIdleTime：最大空闲时间，超过空闲时间的连接将被丢弃。为0或负数则永不丢弃。默认为0； <BR>&nbsp;&nbsp;&nbsp; maxPoolSize：连接池中保留的最大连接数。默认为15； <BR>&nbsp;&nbsp;&nbsp; maxStatements：JDBC的标准参数，用以控制数据源内加载的PreparedStatement数量。但由于预缓存的Statement属 于单个Connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素，如果maxStatements与 maxStatementsPerConnection均为0，则缓存被关闭。默认为0； <BR>&nbsp;&nbsp;&nbsp; maxStatementsPerConnection：连接池内单个连接所拥有的最大缓存Statement数。默认为0； <BR>&nbsp;&nbsp;&nbsp; numHelperThreads：C3P0是异步操作的，缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能，通过多线程实现多个操作同时被执行。默认为3； <BR>&nbsp;&nbsp;&nbsp; preferredTestQuery：定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个参数能显著提高测试速度。测试的表必须在初始数据源的时候就存在。默认为null； <BR>&nbsp;&nbsp;&nbsp; propertyCycle： 用户修改系统配置参数执行前最多等待的秒数。默认为300； <BR>&nbsp;&nbsp;&nbsp; testConnectionOnCheckout：因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的时候都 将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable <BR>等方法来提升连接测试的性能。默认为false； <BR>&nbsp;&nbsp;&nbsp; testConnectionOnCheckin：如果设为true那么在取得连接的同时将校验连接的有效性。默认为false。 <BR><BR><STRONG>读配置文件的方式引用属性： </STRONG></P>
<DIV class=dp-highlighter>
<DIV class=bar></DIV>
<OL class=dp-xml>
<LI class=alt><SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>bean</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>id</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"propertyConfigurer"</SPAN><SPAN>&nbsp;&nbsp; &nbsp;&nbsp;</SPAN></SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=attribute>class</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"location"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>value</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"/WEB-INF/jdbc.properties"</SPAN><SPAN class=tag>/&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN></SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>bean</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN></SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>bean</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>id</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"dataSource"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>class</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"org.apache.commons.dbcp.BasicDataSource"</SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=attribute>destroy-method</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"close"</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"driverClassName"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>value</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"${jdbc.driverClassName}"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=tag>/&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"url"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>value</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"${jdbc.url}"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=tag>/&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"username"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>value</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"${jdbc.username}"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=tag>/&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"password"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>value</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"${jdbc.password}"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=tag>/&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN></SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>bean</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp;</SPAN> </LI></OL></DIV>
<P>&nbsp;&nbsp;&nbsp; 在jdbc.properties属性文件中定义属性值： <BR>&nbsp;&nbsp;&nbsp; jdbc.driverClassName= com.mysql.jdbc.Driver <BR>&nbsp;&nbsp;&nbsp; jdbc.url= jdbc:mysql://localhost:3309/sampledb <BR>&nbsp;&nbsp;&nbsp; jdbc.username=root <BR>&nbsp;&nbsp;&nbsp; jdbc.password=1234 <BR>&nbsp;&nbsp;&nbsp; 提示 经常有开发者在${xxx}的前后不小心键入一些空格，这些空格字符将和变量合并后作为属性的值。如： <property name="username" value=" ${jdbc.username} "></property>的属性配置项，在前后都有空格，被解析后，username的值为“ 1234 ”，这将造成最终的错误，因此需要特别小心。<BR><BR><STRONG>&nbsp;获取JNDI数据源</STRONG> <BR>&nbsp;&nbsp;&nbsp; 如果应用配置在高性能的应用服务器（如WebLogic或Websphere等）上，我们可能更希望使用应用服务器本身提供的数据源。应用服务器的数据源 使用JNDI开放调用者使用，Spring为此专门提供引用JNDI资源的JndiObjectFactoryBean类。下面是一个简单的配置：</P>
<DIV class=code_title>xml 代码</DIV>
<DIV class=dp-highlighter>
<DIV class=bar></DIV>
<OL class=dp-xml>
<LI class=alt><SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>bean</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>id</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"dataSource"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>class</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"org.springframework.jndi.JndiObjectFactoryBean"</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN></SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"jndiName"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>value</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"java:comp/env/jdbc/bbt"</SPAN><SPAN class=tag>/&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN></SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>bean</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> </LI></OL></DIV>
<P>通过jndiName指定引用的JNDI数据源名称。 <BR>&nbsp;&nbsp;&nbsp; Spring 2.0为获取J2EE资源提供了一个jee命名空间，通过jee命名空间，可以有效地简化J2EE资源的引用。下面是使用jee命名空间引用JNDI数据源的配置： </P>
<DIV class=code_title>xml 代码</DIV>
<DIV class=dp-highlighter>
<DIV class=bar></DIV>
<OL class=dp-xml>
<LI class=alt><SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>beans</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>xmlns</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>http</SPAN><SPAN>://www.springframework.org/schema/beans&nbsp; &nbsp;&nbsp;</SPAN></SPAN> 
<LI class=""><SPAN></SPAN><SPAN class=attribute>xmlns:xsi</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>http</SPAN><SPAN>://www.w3.org/2001/XMLSchema-instance&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN></SPAN><SPAN class=attribute>xmlns:jee</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>http</SPAN><SPAN>://www.springframework.org/schema/jee&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN></SPAN><SPAN class=attribute>xsi:schemaLocation</SPAN><SPAN>="http://www.springframework.org/schema/beans&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>http://www.springframework.org/schema/beans/spring-beans-2.0.xsd&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>http://www.springframework.org/schema/jee&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>http://www.springframework.org/schema/jee/spring-jee-2.0.xsd"</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN></SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>jee:jndi-lookup</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>id</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"dataSource"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>jndi-name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"&nbsp;java:comp/env/jdbc/bbt"</SPAN><SPAN class=tag>/&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN></SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>beans</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> </LI></OL></DIV>
<P><FONT face=Arial>Spring的数据源实现类 <BR>&nbsp;&nbsp;&nbsp; Spring本身也提供了一个简单的数据源实现类DriverManagerDataSource ，它位于org.springframework.jdbc.datasource包中。这个类实现了javax.sql.DataSource接口，但 它并没有提供池化连接的机制，每次调用getConnection()获取新连接时，只是简单地创建一个新的连接。因此，这个数据源类比较适合在单元测试 或简单的独立应用中使用，因为它不需要额外的依赖类。 <BR>&nbsp;&nbsp;&nbsp;&nbsp; 下面，我们来看一下DriverManagerDataSource的简单使用：</FONT><FONT face=Arial>当然，我们也可以通过配置的方式直接使用DriverManagerDataSource。</FONT></P>
<DIV class=code_title>java 代码</DIV>
<DIV class=dp-highlighter>
<DIV class=bar></DIV>
<OL class=dp-j>
<LI class=alt><SPAN><SPAN>DriverManagerDataSource&nbsp;ds&nbsp;=&nbsp;</SPAN><SPAN class=keyword>new</SPAN><SPAN>&nbsp;DriverManagerDataSource&nbsp;();&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN></SPAN> 
<LI class=""><SPAN>ds.setDriverClassName(</SPAN><SPAN class=string>"com.mysql.jdbc.Driver"</SPAN><SPAN>);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>ds.setUrl(</SPAN><SPAN class=string>"jdbc:mysql://localhost:3309/sampledb"</SPAN><SPAN>);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>ds.setUsername(</SPAN><SPAN class=string>"root"</SPAN><SPAN>);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>ds.setPassword(</SPAN><SPAN class=string>"1234"</SPAN><SPAN>);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>Connection&nbsp;actualCon&nbsp;=&nbsp;ds.getConnection();&nbsp;&nbsp;</SPAN> </LI></OL></DIV>
<P>&nbsp;</P>
<P><FONT face=Arial><STRONG>小结</STRONG> </FONT></P>
<P><FONT face=Arial>&nbsp;&nbsp;&nbsp; 不管采用何种持久化技术，都需要定义数据源。Spring附带了两个数据源的实现类包，你可以自行选择进行定义。在实际部署时，我们可能会直接采用应用服 务器本身提供的数据源，这时，则可以通过JndiObjectFactoryBean或jee命名空间引用JNDI中的数据源。 </FONT></P>
<P><FONT face=Arial>DBCP与C3PO配置的区别：</FONT></P>
<P><FONT face=Arial>C3PO ：</FONT><FONT face=Arial>DBCP：</FONT></P>
<DIV class=code_title>xml 代码</DIV>
<DIV class=dp-highlighter>
<DIV class=bar></DIV>
<OL class=dp-xml>
<LI class=alt><SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>bean</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>id</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"dataSource"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>class</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"com.mchange.v2.c3p0.ComboPooledDataSource"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>destroy-method</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"close"</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"driverClass"</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>value</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>oracle.jdbc.driver.OracleDriver</SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>value</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>property</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"jdbcUrl"</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>value</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>jdbc:oracle:thin:@10.10.10.6:1521:DataBaseName</SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>value</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>property</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"user"</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>value</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>testAdmin</SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>value</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>property</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"password"</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>value</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>123456</SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>value</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>property</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN></SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>bean</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> </LI></OL></DIV>
<P>&nbsp;</P>
<DIV class=code_title>xml 代码</DIV>
<DIV class=dp-highlighter>
<DIV class=bar></DIV>
<OL class=dp-xml>
<LI class=alt><SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>bean</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>id</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"dataSource"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>class</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"org.apache.commons.dbcp.BasicDataSource"</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>destroy-method</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"close"</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"driverClassName"</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>value</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>oracle.jdbc.driver.OracleDriver</SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>value</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>property</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"url"</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>value</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>jdbc:oracle:thin:@10.10.10.6:1521:DataBaseName</SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>value</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>property</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"username"</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>value</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>testAdmin</SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>value</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>property</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>property</SPAN><SPAN>&nbsp;</SPAN><SPAN class=attribute>name</SPAN><SPAN>=</SPAN><SPAN class=attribute-value>"password"</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;</SPAN><SPAN class=tag-name>value</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>123456</SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>value</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=alt><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>property</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> 
<LI class=""><SPAN></SPAN><SPAN class=tag>&lt;/</SPAN><SPAN class=tag-name>bean</SPAN><SPAN class=tag>&gt;</SPAN><SPAN>&nbsp;&nbsp;</SPAN> </LI></OL></DIV></A>]]></description>
</item><item>
<title><![CDATA[java多线程设计模式]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=27828</link>
<author>littcricket</author>
<pubDate>2007/9/3 14:31:14</pubDate>
<description><![CDATA[<STRONG>线程的创建和启动<BR><BR></STRONG>java语言已经内置了多线程支持，所有实现Runnable接口的类都可被启动一个新线程，新线程会执行该实例的run()方法，当run()方法执行完毕后，线程就结束了。一旦一个线程执行完毕，这个实例就不能再重新启动，只能重新生成一个新实例，再启动一个新线程。
<P style="CLEAR: right">Thread类是实现了Runnable接口的一个实例，它代表一个线程的实例，并且，启动线程的唯一方法就是通过Thread类的start()实例方法：</P>
<P style="CLEAR: right">Thread t = new Thread();<BR>t.start();</P>
<P style="CLEAR: right">start()方法是一个native方法，它将启动一个新线程，并执行run()方法。Thread类默认的run()方法什么也不做就退出了。注意：直接调用run()方法并不会启动一个新线程，它和调用一个普通的java方法没有什么区别。</P>
<P style="CLEAR: right">因此，有两个方法可以实现自己的线程：</P>
<P style="CLEAR: right">方法1：自己的类extend Thread，并复写run()方法，就可以启动新线程并执行自己定义的run()方法。例如：</P>
<P style="CLEAR: right">public class MyThread extends Thread {<BR>&nbsp;&nbsp;&nbsp; public run() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("MyThread.run()");<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P style="CLEAR: right">在合适的地方启动线程：new MyThread().start();</P>
<P style="CLEAR: right">方法2：如果自己的类已经extends另一个类，就无法直接extends Thread，此时，必须实现一个Runnable接口：</P>
<P style="CLEAR: right">public class MyThread extends OtherClass implements Runnable {<BR>&nbsp;&nbsp;&nbsp; public run() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("MyThread.run()");<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P style="CLEAR: right">为了启动MyThread，需要首先实例化一个Thread，并传入自己的MyThread实例：</P>
<P style="CLEAR: right">MyThread myt = new MyThread();<BR>Thread t = new Thread(myt);<BR>t.start();</P>
<P style="CLEAR: right">事实上，当传入一个Runnable target参数给Thread后，Thread的run()方法就会调用target.run()，参考JDK源代码：</P>
<P style="CLEAR: right">public void run() {<BR>&nbsp;&nbsp;&nbsp; if (target != null) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; target.run();<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P style="CLEAR: right">线程还有一些Name, ThreadGroup, isDaemon等设置，由于和线程设计模式关联很少，这里就不多说了。</P>
<DIV style="CLEAR: right" align=left><STRONG>线程的同步</STRONG></DIV>
<P style="CLEAR: right" align=left>由于同一进程内的多个线程共享内存空间，在Java中，就是共享实例，当多个线程试图同时修改某个实例的内容时，就会造成冲突，因此，线程必须实现共享互斥，使多线程同步。</P>
<P style="CLEAR: right" align=left>最简单的同步是将一个方法标记为synchronized，对同一个实例来说，任一时刻只能有一个synchronized方法在执行。当一个方法正在执行某个synchronized方法时，其他线程如果想要执行这个实例的任意一个synchronized方法，都必须等待当前执行synchronized方法的线程退出此方法后，才能依次执行。</P>
<P style="CLEAR: right" align=left>但是，非synchronized方法不受影响，不管当前有没有执行synchronized方法，非synchronized方法都可以被多个线程同时执行。</P>
<P style="CLEAR: right" align=left>此外，必须注意，只有同一实例的synchronized方法同一时间只能被一个线程执行，不同实例的synchronized方法是可以并发的。例如，class A定义了synchronized方法sync()，则不同实例a1.sync()和a2.sync()可以同时由两个线程来执行。</P>
<P style="CLEAR: right" align=left><BR><STRONG>Java锁机制</STRONG></P>
<P style="CLEAR: right" align=left>多线程同步的实现最终依赖锁机制。我们可以想象某一共享资源是一间屋子，每个人都是一个线程。当A希望进入房间时，他必须获得门锁，一旦A获得门锁，他进去后就立刻将门锁上，于是B,C,D...就不得不在门外等待，直到A释放锁出来后，B,C,D...中的某一人抢到了该锁（具体抢法依赖于JVM的实现，可以先到先得，也可以随机挑选），然后进屋又将门锁上。这样，任一时刻最多有一人在屋内（使用共享资源）。</P>
<P style="CLEAR: right" align=left>Java语言规范内置了对多线程的支持。对于Java程序来说，每一个对象实例都有一把“锁”，一旦某个线程获得了该锁，别的线程如果希望获得该锁，只能等待这个线程释放锁之后。获得锁的方法只有一个，就是synchronized关键字。例如：</P>
<P style="CLEAR: right" align=left>public class SharedResource {<BR>&nbsp;&nbsp;&nbsp; private int count = 0;<BR><BR>&nbsp;&nbsp;&nbsp; public int getCount() { return count; }<BR><BR>&nbsp;&nbsp;&nbsp; public <FONT color=#ff0000><STRONG>synchronized</STRONG></FONT> void setCount(int count) { this.count = count; }<BR><BR>}</P>
<P style="CLEAR: right" align=left>同步方法public synchronized void setCount(int count) { this.count = count; } 事实上相当于：</P>
<P style="CLEAR: right" align=left>public&nbsp;void setCount(int count) {<BR>&nbsp;&nbsp;&nbsp; <STRONG><FONT color=#339966>synchronized(this) { // 在此获得this锁<BR></FONT><FONT color=#ff0000>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;this.count = count;</FONT></STRONG><BR>&nbsp;&nbsp;&nbsp; <FONT color=#339966><STRONG>} // 在此释放this锁<BR></STRONG></FONT>}</P>
<P style="CLEAR: right" align=left>红色部分表示需要同步的代码段，该区域为“危险区域”，如果两个以上的线程同时执行，会引发冲突，因此，要更改SharedResource的内部状态，必须先获得SharedResource实例的锁。</P>
<P style="CLEAR: right" align=left>退出synchronized块时，线程拥有的锁自动释放，于是，别的线程又可以获取该锁了。</P>
<P style="CLEAR: right" align=left>为了提高性能，不一定要锁定this，例如，SharedResource有两个独立变化的变量：</P>
<P style="CLEAR: right" align=left>public class SharedResouce {<BR>&nbsp;&nbsp;&nbsp; private int a = 0;<BR>&nbsp;&nbsp;&nbsp; private int b = 0;<BR><BR>&nbsp;&nbsp;&nbsp; public synchronized void setA(int a) { this.a = a; }<BR><BR>&nbsp;&nbsp;&nbsp; public synchronized void setB(int b) { this.b = b; }<BR>}</P>
<P style="CLEAR: right" align=left>若同步整个方法，则setA()的时候无法setB()，setB()时无法setA()。为了提高性能，可以使用不同对象的锁：</P>
<P style="CLEAR: right" align=left>public class SharedResouce {<BR>&nbsp;&nbsp;&nbsp; private int a = 0;<BR>&nbsp;&nbsp;&nbsp; private int b = 0;<BR>&nbsp;&nbsp;&nbsp; private Object sync_a = new Object();<BR>&nbsp;&nbsp;&nbsp; private Object sync_b = new Object();<BR><BR>&nbsp;&nbsp;&nbsp; public void setA(int a) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#339966><STRONG>synchronized(sync_a) {<BR></STRONG></FONT>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.a = a;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; public synchronized void setB(int b) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#339966><STRONG>synchronized(sync_b) {<BR></STRONG></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.b = b;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P style="CLEAR: right" align=left><STRONG>wait/notify机制</STRONG></P>
<P style="CLEAR: right" align=left>通常，多线程之间需要协调工作。例如，浏览器的一个显示图片的线程displayThread想要执行显示图片的任务，必须等待下载线程downloadThread将该图片下载完毕。如果图片还没有下载完，displayThread可以暂停，当downloadThread完成了任务后，再通知displayThread“图片准备完毕，可以显示了”，这时，displayThread继续执行。</P>
<P style="CLEAR: right" align=left>以上逻辑简单的说就是：如果条件不满足，则等待。当条件满足时，等待该条件的线程将被唤醒。在Java中，这个机制的实现依赖于wait/notify。等待机制与锁机制是密切关联的。例如：</P>
<P style="CLEAR: right" align=left>synchronized(obj) {<BR>&nbsp;&nbsp;&nbsp; while(!condition) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obj.<STRONG><FONT color=#0000ff>wait()</FONT></STRONG>;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; obj.doSomething();<BR>}</P>
<P style="CLEAR: right" align=left>当线程A获得了obj锁后，发现条件condition不满足，无法继续下一处理，于是线程A就wait()。</P>
<P style="CLEAR: right" align=left>在另一线程B中，如果B更改了某些条件，使得线程A的condition条件满足了，就可以唤醒线程A：</P>
<P style="CLEAR: right" align=left>synchronized(obj) {<BR>&nbsp;&nbsp;&nbsp; condition = true;<BR>&nbsp;&nbsp;&nbsp; obj.notify();<BR>}</P>
<P style="CLEAR: right" align=left><STRONG><FONT color=#ff0000>需要注意的概念是：</FONT></STRONG></P>
<P style="CLEAR: right" align=left># 调用obj的wait(), notify()方法前，必须获得obj锁，也就是必须写在synchronized(obj) {...} 代码段内。</P>
<P style="CLEAR: right" align=left># 调用obj.wait()后，线程A就释放了obj的锁，否则线程B无法获得obj锁，也就无法在synchronized(obj) {...} 代码段内唤醒A。</P>
<P style="CLEAR: right" align=left># 当obj.wait()方法返回后，线程A需要再次获得obj锁，才能继续执行。</P>
<P style="CLEAR: right" align=left># 如果A1,A2,A3都在obj.wait()，则B调用obj.notify()只能唤醒A1,A2,A3中的一个（具体哪一个由JVM决定）。</P>
<P style="CLEAR: right" align=left># obj.notifyAll()则能全部唤醒A1,A2,A3，但是要继续执行obj.wait()的下一条语句，必须获得obj锁，因此，A1,A2,A3只有一个有机会获得锁继续执行，例如A1，其余的需要等待A1释放obj锁之后才能继续执行。</P>
<P style="CLEAR: right" align=left># 当B调用obj.notify/notifyAll的时候，B正持有obj锁，因此，A1,A2,A3虽被唤醒，但是仍无法获得obj锁。直到B退出synchronized块，释放obj锁后，A1,A2,A3中的一个才有机会获得锁继续执行。</P>
<DIV style="CLEAR: right" align=left><STRONG>wait/sleep的区别<BR></STRONG><BR>
<P style="CLEAR: right">前面讲了wait/notify机制，Thread还有一个sleep()静态方法，它也能使线程暂停一段时间。sleep与wait的不同点是：sleep并不释放锁，并且sleep的暂停和wait暂停是不一样的。obj.wait会使线程进入obj对象的等待集合中并等待唤醒。</P>
<P style="CLEAR: right">但是wait()和sleep()都可以通过interrupt()方法打断线程的暂停状态，从而使线程立刻抛出InterruptedException。</P>
<P style="CLEAR: right">如果线程A希望立即结束线程B，则可以对线程B对应的Thread实例调用interrupt方法。如果此刻线程B正在wait/sleep/join，则线程B会立刻抛出InterruptedException，在catch() {} 中直接return即可安全地结束线程。</P>
<P style="CLEAR: right">需要注意的是，InterruptedException是线程自己从内部抛出的，并不是interrupt()方法抛出的。对某一线程调用interrupt()时，如果该线程正在执行普通的代码，那么该线程根本就不会抛出InterruptedException。但是，一旦该线程进入到wait()/sleep()/join()后，就会立刻抛出InterruptedException。</P>
<DIV style="CLEAR: right" align=left><STRONG>java多线程设计模式(6)&nbsp;GuardedSuspention</STRONG><BR><BR>
<DIV style="CLEAR: right">
<P>GuardedSuspention模式主要思想是：</P>
<P>当条件不满足时，线程等待，直到条件满足时，等待该条件的线程被唤醒。</P>
<P>我们设计一个客户端线程和一个服务器线程，客户端线程不断发送请求给服务器线程，服务器线程不断处理请求。当请求队列为空时，服务器线程就必须等待，直到客户端发送了请求。</P>
<P>先定义一个请求队列：Queue</P>
<P>package com.crackj2ee.thread;<BR><BR>import java.util.*;<BR><BR>public class Queue {<BR>&nbsp;&nbsp;&nbsp; private List queue = new LinkedList();<BR><BR>&nbsp;&nbsp;&nbsp; public synchronized Request <FONT color=#ff0000>getRequest</FONT>() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#0000ff><STRONG>while(queue.size()==0) {<BR></STRONG></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.wait();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(InterruptedException ie) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (Request)queue.remove(0);<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; public synchronized void <FONT color=#ff0000>putRequest</FONT>(Request request) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; queue.add(request);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#993300><STRONG>this.notifyAll();</STRONG></FONT><BR>&nbsp;&nbsp;&nbsp; }<BR><BR>}</P>
<P>蓝色部分就是服务器线程的等待条件，而客户端线程在放入了一个request后，就使服务器线程等待条件满足，于是唤醒服务器线程。</P>
<P>客户端线程：ClientThread</P>
<P>package com.crackj2ee.thread;<BR><BR>public class ClientThread extends Thread {<BR>&nbsp;&nbsp;&nbsp; private Queue queue;<BR>&nbsp;&nbsp;&nbsp; private String clientName;<BR><BR>&nbsp;&nbsp;&nbsp; public ClientThread(Queue queue, String clientName) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.queue = queue;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.clientName = clientName;<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; public String toString() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "[ClientThread-" + clientName + "]";<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; public void run() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0; i&lt;100; i++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Request request = new Request("" + (long)(Math.random()*10000));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(this + " send request: " + request);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><FONT color=#ff0000>queue.putRequest(request);<BR></FONT></STRONG>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.sleep((long)(Math.random() * 10000 + 1000));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(InterruptedException ie) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(this + " shutdown.");<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>服务器线程：ServerThread</P>
<P>package com.crackj2ee.thread;<BR>public class ServerThread extends Thread {<BR>&nbsp;&nbsp;&nbsp; private boolean stop = false;<BR>&nbsp;&nbsp;&nbsp; private Queue queue;<BR><BR>&nbsp;&nbsp;&nbsp; public ServerThread(Queue queue) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.queue = queue;<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; public void shutdown() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stop = true;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.interrupt();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.join();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(InterruptedException ie) {}<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; public void run() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(!stop) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#ff0000><STRONG>Request request = queue.getRequest();<BR></STRONG></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("[ServerThread] handle request: " + request);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.sleep(2000);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(InterruptedException ie) {}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("[ServerThread] shutdown.");<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>服务器线程在红色部分可能会阻塞，也就是说，Queue.getRequest是一个阻塞方法。这和java标准库的许多IO方法类似。</P>
<P>最后，写一个Main来启动他们：</P>
<P>package com.crackj2ee.thread;<BR><BR>public class Main {<BR><BR>&nbsp;&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Queue queue = new Queue();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ServerThread server = new ServerThread(queue);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#ff0000><STRONG>server.start();<BR></STRONG></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ClientThread[] clients = new ClientThread[5];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0; i&lt;clients.length; i++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clients[i] = new ClientThread(queue, ""+i);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#ff0000><STRONG>clients[i].start();<BR></STRONG></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.sleep(100000);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(InterruptedException ie) {}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server.shutdown();<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>我们启动了5个客户端线程和一个服务器线程，运行结果如下：</P>
<P>[ClientThread-0] send request: Request-4984<BR>[ServerThread] handle request: Request-4984<BR>[ClientThread-1] send request: Request-2020<BR>[ClientThread-2] send request: Request-8980<BR>[ClientThread-3] send request: Request-5044<BR>[ClientThread-4] send request: Request-548<BR>[ClientThread-4] send request: Request-6832<BR>[ServerThread] handle request: Request-2020<BR>[ServerThread] handle request: Request-8980<BR>[ServerThread] handle request: Request-5044<BR>[ServerThread] handle request: Request-548<BR>[ClientThread-4] send request: Request-1681<BR>[ClientThread-0] send request: Request-7859<BR>[ClientThread-3] send request: Request-3926<BR>[ServerThread] handle request: Request-6832<BR>[ClientThread-2] send request: Request-9906<BR>......</P>
<P>可以观察到ServerThread处理来自不同客户端的请求。</P>
<P><STRONG><FONT color=#ff0000>思考</FONT></STRONG></P>
<P>Q: 服务器线程的wait条件while(queue.size()==0)能否换成if(queue.size()==0)?</P>
<P>A: 在这个例子中可以，因为服务器线程只有一个。但是，如果服务器线程有多个（例如Web应用程序有多个线程处理并发请求，这非常普遍），就会造成严重问题。</P>
<P>Q: 能否用sleep(1000)代替wait()?</P>
<P>A: 绝对不可以。sleep()不会释放锁，因此sleep期间别的线程根本没有办法调用getRequest()和putRequest()，导致所有相关线程都被阻塞。</P>
<P>Q: (Request)queue.remove(0)可以放到synchronized() {}块外面吗？</P>
<P>A: 不可以。因为while()是测试queue，remove()是使用queue，两者是一个原子操作，不能放在synchronized外面。</P>
<P><STRONG><FONT color=#ff0000>总结</FONT></STRONG></P>
<P>多线程设计看似简单，实际上必须非常仔细地考虑各种锁定/同步的条件，稍不小心，就可能出错。并且，当线程较少时，很可能发现不了问题，一旦问题出现又难以调试。</P>
<P>所幸的是，已有一些被验证过的模式可以供我们使用，我们会继续介绍一些常用的多线程设计模式。</P>
<P><BR><STRONG><FONT color=#ff0000>java多线程设计模式(7)&nbsp;Worker&nbsp;Pattern</FONT></STRONG></P>
<P><STRONG><FONT color=#ff0000></FONT></STRONG><BR>&nbsp;</P>
<DIV style="CLEAR: right">
<P>前面谈了多线程应用程序能极大地改善用户相应。例如对于一个Web应用程序，每当一个用户请求服务器连接时，服务器就可以启动一个新线程为用户服务。</P>
<P>然而，创建和销毁线程本身就有一定的开销，如果频繁创建和销毁线程，CPU和内存开销就不可忽略，垃圾收集器还必须负担更多的工作。因此，线程池就是为了避免频繁创建和销毁线程。</P>
<P>每当服务器接受了一个新的请求后，服务器就从线程池中挑选一个等待的线程并执行请求处理。处理完毕后，线程并不结束，而是转为阻塞状态再次被放入线程池中。这样就避免了频繁创建和销毁线程。</P>
<P>Worker Pattern实现了类似线程池的功能。首先定义Task接口：</P>
<P>package com.crackj2ee.thread;<BR>public interface Task {<BR>&nbsp;&nbsp;&nbsp; void <STRONG><FONT color=#0000ff>execute</FONT></STRONG>();<BR>}</P>
<P>线程将负责执行execute()方法。注意到任务是由子类通过实现execute()方法实现的，线程本身并不知道自己执行的任务。它只负责运行一个耗时的execute()方法。</P>
<P>具体任务由子类实现，我们定义了一个CalculateTask和一个TimerTask：</P>
<P>// CalculateTask.java<BR>package com.crackj2ee.thread;<BR>public class CalculateTask implements Task {<BR>&nbsp;&nbsp;&nbsp; private static int count = 0;<BR>&nbsp;&nbsp;&nbsp; private int num = count;<BR>&nbsp;&nbsp;&nbsp; public CalculateTask() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count++;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public void <FONT color=#0000ff><STRONG>execute</STRONG></FONT>() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("[CalculateTask " + num + "] start...");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.sleep(3000);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(InterruptedException ie) {}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("[CalculateTask " + num + "] done.");<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>// TimerTask.java<BR>package com.crackj2ee.thread;<BR>public class TimerTask implements Task {<BR>&nbsp;&nbsp;&nbsp; private static int count = 0;<BR>&nbsp;&nbsp;&nbsp; private int num = count;<BR>&nbsp;&nbsp;&nbsp; public TimerTask() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count++;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public void <STRONG><FONT color=#0000ff>execute</FONT></STRONG>() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("[TimerTask " + num + "] start...");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.sleep(2000);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(InterruptedException ie) {}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("[TimerTask " + num + "] done.");<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>以上任务均简单的sleep若干秒。</P>
<P>TaskQueue实现了一个队列，客户端可以将请求放入队列，服务器线程可以从队列中取出任务：</P>
<P>package com.crackj2ee.thread;<BR>import java.util.*;<BR>public class TaskQueue {<BR>&nbsp;&nbsp;&nbsp; private List queue = new LinkedList();<BR>&nbsp;&nbsp;&nbsp; public synchronized Task <STRONG><FONT color=#ff0000>getTask</FONT></STRONG>() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(queue.size()==0) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.wait();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(InterruptedException ie) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (Task)queue.remove(0);<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public synchronized void <FONT color=#ff0000><STRONG>putTask</STRONG></FONT>(Task task) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; queue.add(task);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.notifyAll();<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>终于到了真正的WorkerThread，这是真正执行任务的服务器线程：</P>
<P>package com.crackj2ee.thread;<BR>public class WorkerThread extends Thread {<BR>&nbsp;&nbsp;&nbsp; private static int count = 0;<BR>&nbsp;&nbsp;&nbsp; private boolean busy = false;<BR>&nbsp;&nbsp;&nbsp; private boolean stop = false;<BR>&nbsp;&nbsp;&nbsp; private TaskQueue queue;<BR>&nbsp;&nbsp;&nbsp; public WorkerThread(ThreadGroup group, TaskQueue queue) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(group, "worker-" + count);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count++;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.queue = queue;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public void shutdown() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stop = true;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.interrupt();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.join();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(InterruptedException ie) {}<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public boolean isIdle() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return !busy;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public void run() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(getName() + " start.");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(!stop) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Task task = <FONT color=#ff0000><STRONG>queue.getTask();</STRONG></FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(task!=null) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; busy = true;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; task.execute();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; busy = false;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(getName() + " end.");<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>前面已经讲过，queue.getTask()是一个阻塞方法，服务器线程可能在此wait()一段时间。此外，WorkerThread还有一个shutdown方法，用于安全结束线程。</P>
<P>最后是ThreadPool，负责管理所有的服务器线程，还可以动态增加和减少线程数：</P>
<P>package com.crackj2ee.thread;<BR>import java.util.*;<BR>public class ThreadPool extends ThreadGroup {<BR>&nbsp;&nbsp;&nbsp; private List threads = new LinkedList();<BR>&nbsp;&nbsp;&nbsp; private TaskQueue queue;<BR>&nbsp;&nbsp;&nbsp; public ThreadPool(TaskQueue queue) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super("Thread-Pool");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.queue = queue;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public synchronized void addWorkerThread() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread t = new WorkerThread(this, queue);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; threads.add(t);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t.start();<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public synchronized void removeWorkerThread() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(threads.size()&gt;0) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WorkerThread t = (WorkerThread)threads.remove(0);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t.shutdown();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public synchronized void <FONT color=#ff0000><STRONG>currentStatus</STRONG></FONT>() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("-----------------------------------------------");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Thread count = " + threads.size());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Iterator it = threads.iterator();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(it.hasNext()) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WorkerThread t = (WorkerThread)it.next();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(t.getName() + ": " + (t.isIdle() ? "idle" : "busy"));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("-----------------------------------------------");<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>currentStatus()方法是为了方便调试，打印出所有线程的当前状态。</P>
<P>最后，Main负责完成main()方法：</P>
<P>package com.crackj2ee.thread;<BR>public class Main {<BR>&nbsp;&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TaskQueue queue = new TaskQueue();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ThreadPool pool = new ThreadPool(queue);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0; i&lt;10; i++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; queue.putTask(new CalculateTask());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; queue.putTask(new TimerTask());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pool.addWorkerThread();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pool.addWorkerThread();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doSleep(8000);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pool.currentStatus();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pool.addWorkerThread();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pool.addWorkerThread();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pool.addWorkerThread();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pool.addWorkerThread();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pool.addWorkerThread();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doSleep(5000);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pool.currentStatus();<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; private static void doSleep(long ms) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.sleep(ms);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(InterruptedException ie) {}<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>main()一开始放入了20个Task，然后动态添加了一些服务线程，并定期打印线程状态，运行结果如下：</P>
<P>worker-0 start.<BR>[CalculateTask 0] start...<BR>worker-1 start.<BR>[TimerTask 0] start...<BR>[TimerTask 0] done.<BR>[CalculateTask 1] start...<BR>[CalculateTask 0] done.<BR>[TimerTask 1] start...<BR>[CalculateTask 1] done.<BR>[CalculateTask 2] start...<BR>[TimerTask 1] done.<BR>[TimerTask 2] start...<BR>[TimerTask 2] done.<BR>[CalculateTask 3] start...<BR>-----------------------------------------------<BR>Thread count = 2<BR>worker-0: busy<BR>worker-1: busy<BR>-----------------------------------------------<BR>[CalculateTask 2] done.<BR>[TimerTask 3] start...<BR>worker-2 start.<BR>[CalculateTask 4] start...<BR>worker-3 start.<BR>[TimerTask 4] start...<BR>worker-4 start.<BR>[CalculateTask 5] start...<BR>worker-5 start.<BR>[TimerTask 5] start...<BR>worker-6 start.<BR>[CalculateTask 6] start...<BR>[CalculateTask 3] done.<BR>[TimerTask 6] start...<BR>[TimerTask 3] done.<BR>[CalculateTask 7] start...<BR>[TimerTask 4] done.<BR>[TimerTask 7] start...<BR>[TimerTask 5] done.<BR>[CalculateTask 8] start...<BR>[CalculateTask 4] done.<BR>[TimerTask 8] start...<BR>[CalculateTask 5] done.<BR>[CalculateTask 9] start...<BR>[CalculateTask 6] done.<BR>[TimerTask 9] start...<BR>[TimerTask 6] done.<BR>[TimerTask 7] done.<BR>-----------------------------------------------<BR>Thread count = 7<BR><STRONG><FONT color=#008080>worker-0: idle<BR></FONT></STRONG>worker-1: busy<BR>worker-2: busy<BR><STRONG><FONT color=#008080>worker-3: idle</FONT></STRONG><BR>worker-4: busy<BR>worker-5: busy<BR>worker-6: busy<BR>-----------------------------------------------<BR>[CalculateTask 7] done.<BR>[CalculateTask 8] done.<BR>[TimerTask 8] done.<BR>[TimerTask 9] done.<BR>[CalculateTask 9] done.</P>
<P><STRONG>仔细观察</STRONG>：一开始只有两个服务器线程，因此线程状态都是忙，后来线程数增多，7个线程中的两个状态变成idle，说明处于wait()状态。</P>
<P><FONT color=#ff0000><STRONG>思考</STRONG></FONT>：本例的线程调度算法其实根本没有，因为这个应用是围绕TaskQueue设计的，不是以Thread Pool为中心设计的。因此，Task调度取决于TaskQueue的getTask()方法，你可以改进这个方法，例如使用优先队列，使优先级高的任务先被执行。</P>
<P>如果所有的服务器线程都处于busy状态，则说明任务繁忙，TaskQueue的队列越来越长，最终会导致服务器内存耗尽。因此，可以限制TaskQueue的等待任务数，超过最大长度就拒绝处理。许多Web服务器在用户请求繁忙时就会拒绝用户：HTTP 503 SERVICE UNAVAILABLE</P>
<CENTER></CENTER></DIV>
<CENTER></CENTER></DIV><FONT color=#ff0000><STRONG>java多线程设计模式(8)&nbsp;ReadWriteLock</STRONG></FONT><BR><BR>
<DIV style="CLEAR: right">
<P>多线程读写同一个对象的数据是很普遍的，通常，要避免读写冲突，必须保证任何时候仅有一个线程在写入，有线程正在读取的时候，写入操作就必须等待。简单说，就是要避免“写-写”冲突和“读-写”冲突。但是同时读是允许的，因为“读-读”不冲突，而且很安全。</P>
<P>要实现以上的ReadWriteLock，简单的使用synchronized就不行，我们必须自己设计一个ReadWriteLock类，在读之前，必须先获得“读锁”，写之前，必须先获得“写锁”。举例说明：</P>
<P>DataHandler对象保存了一个可读写的char[]数组：</P>
<P>package com.crackj2ee.thread;<BR><BR>public class DataHandler {<BR>&nbsp;&nbsp;&nbsp; // store data:<BR>&nbsp;&nbsp;&nbsp; private char[] buffer = "AAAAAAAAAA".toCharArray();<BR><BR>&nbsp;&nbsp;&nbsp; private char[] doRead() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] ret = new char[buffer.length];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0; i&lt;buffer.length; i++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret[i] = buffer[i];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sleep(3);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ret;<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; private void doWrite(char[] data) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(data!=null) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer = new char[data.length];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0; i&lt;buffer.length; i++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[i] = data[i];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sleep(10);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; private void sleep(int ms) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.sleep(ms);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(InterruptedException ie) {}<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>doRead()和doWrite()方法是非线程安全的读写方法。为了演示，加入了sleep()，并设置读的速度大约是写的3倍，这符合通常的情况。</P>
<P>为了让多线程能安全读写，我们设计了一个ReadWriteLock：</P>
<P>package com.crackj2ee.thread;<BR>public class ReadWriteLock {<BR>&nbsp;&nbsp;&nbsp; private int readingThreads = 0;<BR>&nbsp;&nbsp;&nbsp; private int writingThreads = 0;<BR>&nbsp;&nbsp;&nbsp; private int waitingThreads = 0; // waiting for write<BR>&nbsp;&nbsp;&nbsp; private boolean preferWrite = true;<BR><BR>&nbsp;&nbsp;&nbsp; public synchronized void readLock() throws InterruptedException {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(writingThreads&gt;0 || (preferWrite &amp;&amp; waitingThreads&gt;0))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.wait();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; readingThreads++;<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; public synchronized void readUnlock() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; readingThreads--;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; preferWrite = true;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; notifyAll();<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; public synchronized void writeLock() throws InterruptedException {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; waitingThreads++;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(readingThreads&gt;0 || writingThreads&gt;0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.wait();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; finally {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; waitingThreads--;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writingThreads++;<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; public synchronized void writeUnlock() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writingThreads--;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; preferWrite = false;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; notifyAll();<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>readLock()用于获得读锁，readUnlock()释放读锁，writeLock()和writeUnlock()一样。由于锁用完必须释放，因此，必须保证lock和unlock匹配。我们修改DataHandler，加入ReadWriteLock：</P>
<P>package com.crackj2ee.thread;<BR>public class DataHandler {<BR>&nbsp;&nbsp;&nbsp; // store data:<BR>&nbsp;&nbsp;&nbsp; private char[] buffer = "AAAAAAAAAA".toCharArray();<BR>&nbsp;&nbsp;&nbsp; // lock:<BR>&nbsp;&nbsp;&nbsp; private ReadWriteLock lock = new ReadWriteLock();<BR><BR>&nbsp;&nbsp;&nbsp; public char[] read(String name) throws InterruptedException {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(name + " waiting for read...");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><FONT color=#ff0000>lock.readLock();</FONT></STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] data = doRead();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(name + " reads data: " + new String(data));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return data;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; finally {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><FONT color=#ff0000>lock.readUnlock();<BR></FONT></STRONG>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; public void write(String name, char[] data) throws InterruptedException {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(name + " waiting for write...");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><FONT color=#ff0000>lock.writeLock();<BR></FONT></STRONG>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(name + " wrote data: " + new String(data));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doWrite(data);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; finally {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG><FONT color=#ff0000>lock.writeUnlock();<BR></FONT></STRONG>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; private char[] doRead() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] ret = new char[buffer.length];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0; i&lt;buffer.length; i++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret[i] = buffer[i];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sleep(3);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ret;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; private void doWrite(char[] data) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(data!=null) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer = new char[data.length];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0; i&lt;buffer.length; i++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[i] = data[i];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sleep(10);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; private void sleep(int ms) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.sleep(ms);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(InterruptedException ie) {}<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>public方法read()和write()完全封装了底层的ReadWriteLock，因此，多线程可以安全地调用这两个方法：</P>
<P>// ReadingThread不断读取数据：<BR>package com.crackj2ee.thread;<BR>public class ReadingThread extends Thread {<BR>&nbsp;&nbsp;&nbsp; private DataHandler handler;<BR>&nbsp;&nbsp;&nbsp; public ReadingThread(DataHandler handler) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.handler = handler;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public void run() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(;;) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] data = handler.read(getName());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.sleep((long)(Math.random()*1000+100));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(InterruptedException ie) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>// WritingThread不断写入数据，每次写入的都是10个相同的字符：<BR>package com.crackj2ee.thread;<BR>public class WritingThread extends Thread {<BR>&nbsp;&nbsp;&nbsp; private DataHandler handler;<BR>&nbsp;&nbsp;&nbsp; public WritingThread(DataHandler handler) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.handler = handler;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public void run() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] data = new char[10];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(;;) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fill(data);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; handler.write(getName(), data);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.sleep((long)(Math.random()*1000+100));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(InterruptedException ie) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; //&nbsp;产生一个A-Z随机字符，填入char[10]:<BR>&nbsp;&nbsp;&nbsp; private void fill(char[] data) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char c = (char)(Math.random()*26+'A');<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0; i&lt;data.length; i++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[i] = c;<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>最后Main负责启动这些线程：</P>
<P>package com.crackj2ee.thread;<BR>public class Main {<BR>&nbsp;&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataHandler handler = new DataHandler();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread[] ts = new Thread[] {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new ReadingThread(handler),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new ReadingThread(handler),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new ReadingThread(handler),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new ReadingThread(handler),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new ReadingThread(handler),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new WritingThread(handler),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new WritingThread(handler)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0; i&lt;ts.length; i++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ts[i].start();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>我们启动了5个读线程和2个写线程，运行结果如下：</P>
<P><FONT face="Courier New">Thread-0 waiting for read...<BR>Thread-1 waiting for read...<BR>Thread-2 waiting for read...<BR>Thread-3 waiting for read...<BR>Thread-4 waiting for read...<BR>Thread-5 waiting for write...<BR>Thread-6 waiting for write...<BR>Thread-4 reads data: AAAAAAAAAA<BR>Thread-3 reads data: AAAAAAAAAA<BR>Thread-2 reads data: AAAAAAAAAA<BR>Thread-1 reads data: AAAAAAAAAA<BR>Thread-0 reads data: AAAAAAAAAA<BR>Thread-5 wrote data: EEEEEEEEEE<BR>Thread-6 wrote data: MMMMMMMMMM<BR>Thread-1 waiting for read...<BR>Thread-4 waiting for read...<BR>Thread-1 reads data: MMMMMMMMMM<BR>Thread-4 reads data: MMMMMMMMMM<BR>Thread-2 waiting for read...<BR>Thread-2 reads data: MMMMMMMMMM<BR>Thread-0 waiting for read...<BR>Thread-0 reads data: MMMMMMMMMM<BR>Thread-4 waiting for read...<BR>Thread-4 reads data: MMMMMMMMMM<BR>Thread-2 waiting for read...<BR>Thread-5 waiting for write...<BR>Thread-2 reads data: MMMMMMMMMM<BR>Thread-5 wrote data: GGGGGGGGGG<BR>Thread-6 waiting for write...<BR>Thread-6 wrote data: AAAAAAAAAA<BR>Thread-3 waiting for read...<BR>Thread-3 reads data: AAAAAAAAAA<BR>......</FONT></P>
<P>可以看到，每次读/写都是完整的原子操作，因为我们每次写入的都是10个相同字符。并且，每次读出的都是最近一次写入的内容。</P>
<P>如果去掉ReadWriteLock：</P>
<P>package com.crackj2ee.thread;<BR>public class DataHandler {<BR><BR>&nbsp;&nbsp;&nbsp; // store data:<BR>&nbsp;&nbsp;&nbsp; private char[] buffer = "AAAAAAAAAA".toCharArray();<BR><BR>&nbsp;&nbsp;&nbsp; public char[] read(String name) throws InterruptedException {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] data = doRead();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(name + " reads data: " + new String(data));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return data;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public void write(String name, char[] data) throws InterruptedException {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(name + " wrote data: " + new String(data));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doWrite(data);<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp; private char[] doRead() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] ret = new char[10];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0; i&lt;10; i++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret[i] = buffer[i];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sleep(3);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ret;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; private void doWrite(char[] data) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0; i&lt;10; i++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[i] = data[i];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sleep(10);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; private void sleep(int ms) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.sleep(ms);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(InterruptedException ie) {}<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>运行结果如下：</P>
<P><FONT face="Courier New">Thread-5 wrote data: AAAAAAAAAA<BR>Thread-6 wrote data: MMMMMMMMMM<BR>Thread-0 reads data: AAAAAAAAAA<BR>Thread-1 reads data: AAAAAAAAAA<BR>Thread-2 reads data: AAAAAAAAAA<BR>Thread-3 reads data: AAAAAAAAAA<BR>Thread-4 reads data: AAAAAAAAAA<BR>Thread-2 reads data: MAAAAAAAAA<BR>Thread-3 reads data: MAAAAAAAAA<BR>Thread-5 wrote data: CCCCCCCCCC<BR>Thread-1 reads data: MAAAAAAAAA<BR>Thread-0 reads data: MAAAAAAAAA<BR>Thread-4 reads data: MAAAAAAAAA<BR></FONT><STRONG><FONT face="Courier New" color=#ff0000>Thread-6 wrote data: EEEEEEEEEE<BR>Thread-3 reads data: EEEEECCCCC<BR>Thread-4 reads data: EEEEEEEEEC<BR>Thread-1 reads data: EEEEEEEEEE</FONT></STRONG></P>
<P>可以看到在Thread-6写入EEEEEEEEEE的过程中，3个线程读取的内容是不同的。</P>
<P><FONT color=#ff0000><STRONG>思考</STRONG></FONT></P>
<P>java的synchronized提供了最底层的物理锁，要在synchronized的基础上，实现自己的逻辑锁，就必须仔细设计ReadWriteLock。</P>
<P>Q: lock.readLock()为什么不放入try{ }&nbsp;内？<BR>A: 因为readLock()会抛出InterruptedException，导致readingThreads++不执行，而readUnlock()在finally{ } 中，导致readingThreads--执行，从而使readingThread状态出错。writeLock()也是类似的。</P>
<P>Q: preferWrite有用吗？<BR>A: 如果去掉preferWrite，线程安全不受影响。但是，如果读取线程很多，上一个线程还没有读取完，下一个线程又开始读了，就导致写入线程长时间无法获得writeLock；如果写入线程等待的很多，一个接一个写，也会导致读取线程长时间无法获得readLock。preferWrite的作用是让读/写交替执行，避免由于读线程繁忙导致写无法进行和由于写线程繁忙导致读无法进行。</P>
<P>Q: notifyAll()换成notify()行不行？<BR>A: 不可以。由于preferWrite的存在，如果一个线程刚读取完毕，此时preferWrite=true，再notify()，若恰好唤醒的是一个读线程，则while(writingThreads&gt;0 || (preferWrite &amp;&amp; waitingThreads&gt;0))可能为true导致该读线程继续等待，而等待写入的线程也处于wait()中，结果所有线程都处于wait()状态，谁也无法唤醒谁。因此，notifyAll()比notify()要来得安全。程序验证notify()带来的死锁：</P>
<P><FONT face="Courier New">Thread-0 waiting for read...<BR>Thread-1 waiting for read...<BR>Thread-2 waiting for read...<BR>Thread-3 waiting for read...<BR>Thread-4 waiting for read...<BR>Thread-5 waiting for write...<BR>Thread-6 waiting for write...<BR>Thread-0 reads data: AAAAAAAAAA<BR>Thread-4 reads data: AAAAAAAAAA<BR>Thread-3 reads data: AAAAAAAAAA<BR>Thread-2 reads data: AAAAAAAAAA<BR>Thread-1 reads data: AAAAAAAAAA<BR>Thread-5 wrote data: CCCCCCCCCC<BR>Thread-2 waiting for read...<BR>Thread-1 waiting for read...<BR>Thread-3 waiting for read...<BR>Thread-0 waiting for read...<BR>Thread-4 waiting for read...<BR>Thread-6 wrote data: LLLLLLLLLL<BR>Thread-5 waiting for write...<BR>Thread-6 waiting for write...<BR>Thread-2 reads data: LLLLLLLLLL<BR>Thread-2 waiting for read...<BR>（运行到此不动了）</FONT></P>
<P>注意到这种死锁是由于所有线程都在等待别的线程唤醒自己，结果都无法醒过来。这和两个线程希望获得对方已有的锁造成死锁不同。因此多线程设计的难度远远高于单线程应用。</P></DIV></DIV></DIV><BR>]]></description>
</item><item>
<title><![CDATA[java中switch的使用]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=26371</link>
<author>littcricket</author>
<pubDate>2007/7/16 10:42:18</pubDate>
<description><![CDATA[<A>　<STRONG><U><FONT style="BACKGROUND-COLOR: #ffff66">java中switch的使用</FONT></U></STRONG> 
<DIV class=postText>
<DIV class=storytext>关于java中switch使用的一些说明<BR>
<P><FONT size=2>switch(表达式)<BR>{<BR>case 常量表达式1:语句1;<BR>....<BR>case 常量表达式2:语句2;<BR>default:语句;<BR>}<BR>default就是如果没有符合的case就执行它,default并不是必须的.<BR>case后的语句可以不用大括号.<BR>switch语句的判断条件可以接受int,byte,char,short,不能接受其他类型.<BR>一旦case匹配,就会顺序执行后面的程序代码,而不管后面的case是否匹配,直到遇见break,利用这一特性可以让好几个case执行统一语句.</FONT></P>
<P><FONT size=2>例如:</FONT></P>
<P><FONT size=2>switch(x)</FONT></P>
<P><FONT size=2>{</FONT></P>
<P><FONT size=2>case 1:</FONT></P>
<P><FONT size=2>case 2:</FONT></P>
<P><FONT size=2>case3: System.out.println("haha");</FONT></P>
<P><FONT size=2>break;</FONT></P>
<P><FONT size=2>case4: System.out.println("hehe");</FONT></P>
<P><FONT size=2>}</FONT></P></DIV>&nbsp;</DIV></A>]]></description>
</item><item>
<title><![CDATA[性格，编码，测试]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=26370</link>
<author>littcricket</author>
<pubDate>2007/7/16 9:51:45</pubDate>
<description><![CDATA[<P>自己的性格是属于偏急的那种，什么事情到手上，恨不能马上做完，就开始享受生活了，结果就是在coding的过程中，遇到问题自己比较急，问题解决的不好，就求助于别人，而在心态好的情况下，自己未必也不能解决；然后就是在coding完以后，测试粗糙，以至于后来的bug很多，（在编码的过程中，coding是30%，测试是70%，觉得也是依照每个人的性格不一样，有的人习惯在coding比较细心，有得人比较粗心，自然在coding和测试中花的时间比例不同）对自己的信心也是一种打击，也是一种不成熟的表现，还是那句话，人才是磨出来的，自己慢慢用心体会吧。</P>]]></description>
</item><item>
<title><![CDATA[突然想到的几句话！]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=26369</link>
<author>littcricket</author>
<pubDate>2007/7/16 9:45:08</pubDate>
<description><![CDATA[<P>1.人才是磨出来的</P>
<P>&nbsp; 2.每天应该反省自己，做到了什么，没做到什么了，做错了什么</P>]]></description>
</item><item>
<title><![CDATA[理解Spring AOP中的关键概念]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=25980</link>
<author>littcricket</author>
<pubDate>2007/7/4 13:42:41</pubDate>
<description><![CDATA[<A>　
<P><FONT face="Courier New" size=2>这一周我都在用空余的时间来看Spring这个东西，突然觉得这个东西并没有想像中那么深不可测，最多只有AOP这方面的东西不是我所熟悉的，不过经过自己努力，也不是不可理解的。<BR><BR>AOP，面向切面的编程，是一种从各个方面对软件系统进行关注的开发方法，也就是说，可以把要实现的系统从多个方面进行理解和开发。比如一个系统，它包含了业务逻辑，日志管理，安全管理（认证管理）等，一般而言，我在开发包含这些方面的程序时，就很容易进入单面一维的操作去：比如下面是一个用户管理程序的部份：<BR>1、验证用户是否已经登录<BR>2、记录日志<BR>3、进行操作，对重要的操作都可能要进行日志记录。<BR>4、记录用户离开时间<BR>......<BR>由上面的步骤可以看到，真正的业务逻辑只有第3步，其它的都是附加的功能，或者是从另一方面加入的功能，他们和业务逻辑是相辅相成，可是业务逻辑并不需要知道这些附加的功能，又从另一方面来看，每一进行的操作都会触发附加的操作，而且这些应该是自动的，业务逻辑所不知道的。<BR><BR>所以就引进一个拦截器的概念，对用户的操作进行拦截，然后进行附加的操作。而用户的操作并不知道这些拦截器的存在，从而可以使开发业务逻辑的程序员可以专心地写他的业务逻辑，而其它程序员则专心写他的拦截器，从而就可以使程序员从多个方面进行关注，进行编程。而Spring AOP就起到了这个拦截器的作用，而这些就演化出很多的术语，也无非是拦截器而已，现在俗一点来理解这些个术语：<BR><BR>切面：宏观上要关注的编程方面，比如安全管理方面，日志记录方面，而这些都只是宏观上的，没有任何代码实现，就好像这样说：我这个系统要一个安全管理系统等等，就是大至上需要这个切面功能。<BR><BR>通知（Advice）：切面功能的代码实现，也就是说具体的切面功能。<BR><BR>连接点（Joinpoint）：程序运行中可以把通知道插入的所有地方，比如某方法前，后，或抛出异常，而所以这些方法的插入点都是连接点。<BR><BR>切入点（Pointcut）：定义了通知可以插入到哪些连接点。<BR><BR>Advisor：这里只有Spring才有，它包含了通知和切入点，以定义在什么连接点插入什么通知。<BR><BR>下面我用一个代码例子来说明：<BR><BR>文件：SayHelloService.java<BR></FONT></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"><FONT size=2><FONT face="Courier New"><SPAN style="COLOR: #008080">1</SPAN>&nbsp;<SPAN style="COLOR: #0000ff">package</SPAN></FONT> </FONT><FONT size=2><FONT face="Courier New"><SPAN style="COLOR: #000000">&nbsp;com.bullonline.study.spring.ch03;<BR></SPAN><SPAN style="COLOR: #008080">2</SPAN>&nbsp;</FONT> </FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT size=2><FONT face="Courier New"><SPAN style="COLOR: #008080">3</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">interface</SPAN></FONT> </FONT><FONT size=2><FONT face="Courier New"><SPAN style="COLOR: #000000">&nbsp;SayHelloService&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">4</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN></FONT> </FONT><FONT size=2><FONT face="Courier New"><SPAN style="COLOR: #000000">&nbsp;printMessage(String&nbsp;message);<BR></SPAN><SPAN style="COLOR: #008080">5</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN></FONT> </FONT><FONT size=2><FONT face="Courier New"><SPAN style="COLOR: #000000">&nbsp;printInfomation(String&nbsp;info);<BR></SPAN><SPAN style="COLOR: #008080">6</SPAN>&nbsp;</FONT> </FONT><FONT size=2><FONT face="Courier New"><SPAN style="COLOR: #000000">}<BR></SPAN><SPAN style="COLOR: #008080">7</SPAN> </FONT></FONT>&nbsp;<SPAN style="COLOR: #000000"></SPAN></DIV><BR><FONT face="Courier New" size=2>文件：SayHelloServiceImpl.java</FONT> <BR>
<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"><FONT face="Courier New"><FONT color=#000000><FONT size=2><SPAN style="COLOR: #008080">&nbsp;1</SPAN>&nbsp;<SPAN style="COLOR: #0000ff">package</SPAN></FONT> </FONT></FONT><FONT face="Courier New"><FONT color=#000000><FONT size=2><SPAN style="COLOR: #000000">&nbsp;com.bullonline.study.spring.ch03;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;2</SPAN>&nbsp;</FONT> </FONT></FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT color=#000000><FONT size=2><SPAN style="COLOR: #008080">&nbsp;3</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;SayHelloServiceImpl&nbsp;</SPAN><SPAN style="COLOR: #0000ff">implements</SPAN></FONT> </FONT></FONT><FONT face="Courier New"><FONT color=#000000><FONT size=2><SPAN style="COLOR: #000000">&nbsp;SayHelloService&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;4</SPAN>&nbsp;</FONT> </FONT></FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT color=#000000><FONT size=2><SPAN style="COLOR: #008080">&nbsp;5</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN></FONT> </FONT></FONT><FONT face="Courier New"><FONT color=#000000><FONT size=2><SPAN style="COLOR: #000000">&nbsp;printMessage(String&nbsp;message)&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;6</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">message:</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN></FONT> </FONT></FONT><FONT face="Courier New"><FONT color=#000000><FONT size=2><SPAN style="COLOR: #000000">&nbsp;message);<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;7</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">---------------------------------\n</SPAN><SPAN style="COLOR: #000000">"</SPAN></FONT> </FONT></FONT><FONT face="Courier New"><FONT color=#000000><FONT size=2><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;8</SPAN>&nbsp;</FONT> </FONT></FONT><FONT face="Courier New"><FONT color=#000000><FONT size=2><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;9</SPAN>&nbsp;</FONT> </FONT></FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT color=#000000><FONT size=2><SPAN style="COLOR: #008080">10</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN></FONT> </FONT></FONT><FONT face="Courier New"><FONT color=#000000><FONT size=2><SPAN style="COLOR: #000000">&nbsp;printInfomation(String&nbsp;info)&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">11</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><IMG src="http://www.blogjava.net/Images/dot.gif"><IMG src="http://www.blogjava.net/Images/dot.gif">..Infomation<IMG src="http://www.blogjava.net/Images/dot.gif"><IMG src="http://www.blogjava.net/Images/dot.gif"><IMG src="http://www.blogjava.net/Images/dot.gif"></SPAN><SPAN style="COLOR: #000000">"</SPAN></FONT> </FONT></FONT><FONT face="Courier New"><FONT color=#000000><FONT size=2><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">12</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">=&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;love&nbsp;is&nbsp;good&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=</SPAN><SPAN style="COLOR: #000000">"</SPAN></FONT> </FONT></FONT><FONT face="Courier New"><FONT color=#000000><FONT size=2><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">13</SPAN>&nbsp;</FONT> </FONT></FONT><FONT face="Courier New"><FONT color=#000000><FONT size=2><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(info);<BR></SPAN><SPAN style="COLOR: #008080">14</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">---------------------------------\n</SPAN><SPAN style="COLOR: #000000">"</SPAN></FONT> </FONT></FONT><FONT face="Courier New"><FONT color=#000000><FONT size=2><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">15</SPAN>&nbsp;</FONT> </FONT></FONT><FONT face="Courier New"><FONT color=#000000><FONT size=2><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">16</SPAN>&nbsp;</FONT> </FONT></FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT color=#000000><FONT size=2><SPAN style="COLOR: #008080">17</SPAN>&nbsp;</FONT> </FONT></FONT><FONT face="Courier New"><FONT color=#000000><FONT size=2><SPAN style="COLOR: #000000">}<BR></SPAN><SPAN style="COLOR: #008080">18</SPAN> </FONT></FONT></FONT>&nbsp;<SPAN style="COLOR: #000000"></SPAN></DIV><BR><FONT face="Courier New" size=2>文件：SayHelloAdvice.java<BR></FONT>
<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"><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">&nbsp;1</SPAN>&nbsp;<SPAN style="COLOR: #0000ff">package</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;com.bullonline.study.spring.ch03;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;2</SPAN>&nbsp;</FONT> </FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">&nbsp;3</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">import</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;java.lang.reflect.Method;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;4</SPAN>&nbsp;</FONT> </FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">&nbsp;5</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">import</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;org.springframework.aop.MethodBeforeAdvice;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;6</SPAN>&nbsp;</FONT> </FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">&nbsp;7</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;SayHelloAdvice&nbsp;</SPAN><SPAN style="COLOR: #0000ff">implements</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;MethodBeforeAdvice&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;8</SPAN>&nbsp;</FONT> </FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">&nbsp;9</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;before(Method&nbsp;method,&nbsp;Object[]&nbsp;args,&nbsp;Object&nbsp;target)<BR></SPAN><SPAN style="COLOR: #008080">10</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">throws</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;Throwable&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">11</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(method.toString()&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">:&nbsp;say&nbsp;hello&nbsp;to&nbsp;you!!</SPAN><SPAN style="COLOR: #000000">"</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">12</SPAN>&nbsp;</FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">13</SPAN>&nbsp;</FONT> </FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">14</SPAN>&nbsp;<SPAN style="COLOR: #000000">}</SPAN></FONT> </FONT></DIV><BR><FONT face="Courier New" size=2>文件：MyClassFilter.java<BR></FONT>
<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"><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">&nbsp;1</SPAN>&nbsp;<SPAN style="COLOR: #0000ff">package</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;com.bullonline.study.spring.ch03;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;2</SPAN>&nbsp;</FONT> </FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">&nbsp;3</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">import</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;org.springframework.aop.ClassFilter;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;4</SPAN>&nbsp;</FONT> </FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">&nbsp;5</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;MyClassFilter&nbsp;</SPAN><SPAN style="COLOR: #0000ff">implements</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;ClassFilter&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;6</SPAN>&nbsp;</FONT> </FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">&nbsp;7</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">boolean</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;matches(Class&nbsp;target)&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;8</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">true</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;9</SPAN>&nbsp;</FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">10</SPAN>&nbsp;</FONT> </FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">11</SPAN>&nbsp;</FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">}<BR></SPAN><SPAN style="COLOR: #008080">12</SPAN> </FONT></FONT>&nbsp;<SPAN style="COLOR: #000000"></SPAN></DIV><BR><FONT face="Courier New" size=2>文件：MyMethodMatcher.java</FONT> <BR>
<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"><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">&nbsp;1</SPAN>&nbsp;<SPAN style="COLOR: #0000ff">package</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;com.bullonline.study.spring.ch03;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;2</SPAN>&nbsp;</FONT> </FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">&nbsp;3</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">import</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;java.lang.reflect.Method;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;4</SPAN>&nbsp;</FONT> </FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">&nbsp;5</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">import</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;org.springframework.aop.MethodMatcher;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;6</SPAN>&nbsp;</FONT> </FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">&nbsp;7</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;MyMethodMatcher&nbsp;</SPAN><SPAN style="COLOR: #0000ff">implements</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;MethodMatcher&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;8</SPAN>&nbsp;</FONT> </FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">&nbsp;9</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">boolean</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;matches(Method&nbsp;method,&nbsp;Class&nbsp;target)&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">10</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;methodName&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;method.getName();<BR></SPAN><SPAN style="COLOR: #008080">11</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(methodName.equals(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">printMessage</SPAN><SPAN style="COLOR: #000000">"</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">))&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">12</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">true</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #008080">13</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</SPAN><SPAN style="COLOR: #0000ff">else</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">14</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #008080">15</SPAN>&nbsp;</FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">16</SPAN>&nbsp;</FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">17</SPAN>&nbsp;</FONT> </FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">18</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">boolean</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;isRuntime()&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">19</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #008080">20</SPAN>&nbsp;</FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">21</SPAN>&nbsp;</FONT> </FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">22</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">boolean</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;matches(Method&nbsp;arg0,&nbsp;Class&nbsp;arg1,&nbsp;Object[]&nbsp;arg2)&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">23</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN></FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #008080">24</SPAN>&nbsp;</FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">25</SPAN>&nbsp;</FONT> </FONT><SPAN style="COLOR: #000000"><BR></SPAN><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #008080">26</SPAN>&nbsp;</FONT> </FONT><FONT face="Courier New"><FONT size=2><SPAN style="COLOR: #000000">}<BR></SPAN><SPAN style="COLOR: #008080">27</SPAN> </FONT></FONT>&nbsp;<SPAN style="COLOR: #000000"></SPAN></DIV><BR><FONT face="Courier New" size=2>文件：MyPointcut.java<BR>
<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>&nbsp;<SPAN style="COLOR: #0000ff">package</SPAN><SPAN style="COLOR: #000000">&nbsp;com.bullonline.study.spring.ch03;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;2</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;3</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;org.springframework.aop.ClassFilter;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;4</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;org.springframework.aop.MethodMatcher;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;5</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;org.springframework.aop.Pointcut;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;6</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;7</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;MyPointcut&nbsp;</SPAN><SPAN style="COLOR: #0000ff">implements</SPAN><SPAN style="COLOR: #000000">&nbsp;Pointcut&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;8</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;ClassFilter&nbsp;filter;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;9</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;MethodMatcher&nbsp;matcher;<BR></SPAN><SPAN style="COLOR: #008080">10</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">11</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;setClassFilter(ClassFilter&nbsp;filter)&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">12</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.filter&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;filter;<BR></SPAN><SPAN style="COLOR: #008080">13</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">14</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">15</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;setMethodMatcher(MethodMatcher&nbsp;matcher)&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">16</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.matcher&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;matcher;<BR></SPAN><SPAN style="COLOR: #008080">17</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">18</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">19</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;ClassFilter&nbsp;getClassFilter()&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">20</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.filter;<BR></SPAN><SPAN style="COLOR: #008080">21</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">22</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">23</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;MethodMatcher&nbsp;getMethodMatcher()&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">24</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.matcher;<BR></SPAN><SPAN style="COLOR: #008080">25</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">26</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">27</SPAN>&nbsp;<SPAN style="COLOR: #000000">}<BR></SPAN><SPAN style="COLOR: #008080">28</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN></DIV><BR>文件：MyPointcutAdvisor.java<BR>
<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>&nbsp;<SPAN style="COLOR: #0000ff">package</SPAN><SPAN style="COLOR: #000000">&nbsp;com.bullonline.study.spring.ch03;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;2</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;3</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;org.aopalliance.aop.Advice;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;4</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;org.springframework.aop.Pointcut;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;5</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;org.springframework.aop.PointcutAdvisor;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;6</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;7</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;MyPointcutAdvisor&nbsp;</SPAN><SPAN style="COLOR: #0000ff">implements</SPAN><SPAN style="COLOR: #000000">&nbsp;PointcutAdvisor&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;8</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;Pointcut&nbsp;pointcut;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;9</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;Advice&nbsp;advice;<BR></SPAN><SPAN style="COLOR: #008080">10</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">11</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;setPointcut(Pointcut&nbsp;pointcut)&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">12</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.pointcut&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;pointcut;<BR></SPAN><SPAN style="COLOR: #008080">13</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">14</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">15</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;setAdvice(Advice&nbsp;advice)&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">16</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.advice&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;advice;<BR></SPAN><SPAN style="COLOR: #008080">17</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">18</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">19</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;Pointcut&nbsp;getPointcut()&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">20</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.pointcut;<BR></SPAN><SPAN style="COLOR: #008080">21</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">22</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">23</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">boolean</SPAN><SPAN style="COLOR: #000000">&nbsp;isPerInstance()&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">24</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #008080">25</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">26</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">27</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;Advice&nbsp;getAdvice()&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">28</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.advice;<BR></SPAN><SPAN style="COLOR: #008080">29</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">30</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">31</SPAN>&nbsp;<SPAN style="COLOR: #000000">}<BR></SPAN><SPAN style="COLOR: #008080">32</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN></DIV><BR>文件：TestApp.java<BR>
<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>&nbsp;<SPAN style="COLOR: #0000ff">package</SPAN><SPAN style="COLOR: #000000">&nbsp;com.bullonline.study.spring.ch03;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;2</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;3</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;org.springframework.beans.factory.BeanFactory;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;4</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;org.springframework.beans.factory.xml.XmlBeanFactory;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;5</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;org.springframework.core.io.ClassPathResource;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;6</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;7</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;TestApp&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;8</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;main(String[]&nbsp;args)&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;9</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BeanFactory&nbsp;factory&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;XmlBeanFactory(</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;ClassPathResource(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">applicationContext.xml</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">));<BR></SPAN><SPAN style="COLOR: #008080">10</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SayHelloService&nbsp;service&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(SayHelloService)&nbsp;factory.getBean(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">sayHelloService</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">11</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;service.printMessage(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Hello,&nbsp;World!!</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">12</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;service.printInfomation(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">haha<IMG src="http://www.blogjava.net/Images/dot.gif"><IMG src="http://www.blogjava.net/Images/dot.gif">..</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #008080">13</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">14</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">15</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">16</SPAN>&nbsp;<SPAN style="COLOR: #000000">}<BR></SPAN><SPAN style="COLOR: #008080">17</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN></DIV><BR>文件：applicationContext.xml<BR>
<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>&nbsp;<SPAN style="COLOR: #0000ff">&lt;?</SPAN><SPAN style="COLOR: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"</SPAN><SPAN style="COLOR: #0000ff">?&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;2</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">&lt;!</SPAN><SPAN style="COLOR: #ff00ff">DOCTYPE&nbsp;beans&nbsp;PUBLIC&nbsp;"-//SPRING//DTD&nbsp;BEAN//EN"&nbsp;"http://www.springframework.org/dtd/spring-beans.dtd"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;3</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;4</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">beans</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;5</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">bean&nbsp;</SPAN><SPAN style="COLOR: #ff0000">id</SPAN><SPAN style="COLOR: #0000ff">="helloWorld"</SPAN><SPAN style="COLOR: #ff0000">&nbsp;class</SPAN><SPAN style="COLOR: #0000ff">="com.bullonline.study.spring.ch01.HelloWorld"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;6</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">property&nbsp;</SPAN><SPAN style="COLOR: #ff0000">name</SPAN><SPAN style="COLOR: #0000ff">="message"</SPAN><SPAN style="COLOR: #ff0000">&nbsp;value</SPAN><SPAN style="COLOR: #0000ff">="Haha<IMG src="http://www.blogjava.net/Images/dot.gif"><IMG src="http://www.blogjava.net/Images/dot.gif">.Hello,&nbsp;World!!"</SPAN><SPAN style="COLOR: #0000ff">&gt;&lt;/</SPAN><SPAN style="COLOR: #800000">property</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;7</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">bean</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;8</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;9</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">bean&nbsp;</SPAN><SPAN style="COLOR: #ff0000">id</SPAN><SPAN style="COLOR: #0000ff">="sayHelloServiceImpl"</SPAN><SPAN style="COLOR: #ff0000">&nbsp;class</SPAN><SPAN style="COLOR: #0000ff">="com.bullonline.study.spring.ch03.SayHelloServiceImpl"</SPAN><SPAN style="COLOR: #ff0000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">/&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">10</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">bean&nbsp;</SPAN><SPAN style="COLOR: #ff0000">id</SPAN><SPAN style="COLOR: #0000ff">="classFilter"</SPAN><SPAN style="COLOR: #ff0000">&nbsp;class</SPAN><SPAN style="COLOR: #0000ff">="com.bullonline.study.spring.ch03.MyClassFilter"</SPAN><SPAN style="COLOR: #ff0000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">/&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">11</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">bean&nbsp;</SPAN><SPAN style="COLOR: #ff0000">id</SPAN><SPAN style="COLOR: #0000ff">="methodMatcher"</SPAN><SPAN style="COLOR: #ff0000">&nbsp;class</SPAN><SPAN style="COLOR: #0000ff">="com.bullonline.study.spring.ch03.MyMethodMatcher"</SPAN><SPAN style="COLOR: #ff0000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">/&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">12</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">bean&nbsp;</SPAN><SPAN style="COLOR: #ff0000">id</SPAN><SPAN style="COLOR: #0000ff">="sayHelloAdvice"</SPAN><SPAN style="COLOR: #ff0000">&nbsp;class</SPAN><SPAN style="COLOR: #0000ff">="com.bullonline.study.spring.ch03.SayHelloAdvice"</SPAN><SPAN style="COLOR: #ff0000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">/&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">13</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">14</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">bean&nbsp;</SPAN><SPAN style="COLOR: #ff0000">id</SPAN><SPAN style="COLOR: #0000ff">="myPointcut"</SPAN><SPAN style="COLOR: #ff0000">&nbsp;class</SPAN><SPAN style="COLOR: #0000ff">="com.bullonline.study.spring.ch03.MyPointcut"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">15</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">property&nbsp;</SPAN><SPAN style="COLOR: #ff0000">name</SPAN><SPAN style="COLOR: #0000ff">="classFilter"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">16</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">ref&nbsp;</SPAN><SPAN style="COLOR: #ff0000">bean</SPAN><SPAN style="COLOR: #0000ff">="classFilter"</SPAN><SPAN style="COLOR: #0000ff">/&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">17</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">property</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">18</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">property&nbsp;</SPAN><SPAN style="COLOR: #ff0000">name</SPAN><SPAN style="COLOR: #0000ff">="methodMatcher"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">19</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">ref&nbsp;</SPAN><SPAN style="COLOR: #ff0000">bean</SPAN><SPAN style="COLOR: #0000ff">="methodMatcher"</SPAN><SPAN style="COLOR: #0000ff">/&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">20</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">property</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">21</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">bean</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">22</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">23</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">bean&nbsp;</SPAN><SPAN style="COLOR: #ff0000">id</SPAN><SPAN style="COLOR: #0000ff">="myPointcutAdvisor"</SPAN><SPAN style="COLOR: #ff0000">&nbsp;class</SPAN><SPAN style="COLOR: #0000ff">="com.bullonline.study.spring.ch03.MyPointcutAdvisor"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">24</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">property&nbsp;</SPAN><SPAN style="COLOR: #ff0000">name</SPAN><SPAN style="COLOR: #0000ff">="pointcut"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">25</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">ref&nbsp;</SPAN><SPAN style="COLOR: #ff0000">bean</SPAN><SPAN style="COLOR: #0000ff">="myPointcut"</SPAN><SPAN style="COLOR: #0000ff">/&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">26</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">property</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">27</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">property&nbsp;</SPAN><SPAN style="COLOR: #ff0000">name</SPAN><SPAN style="COLOR: #0000ff">="advice"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">28</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">ref&nbsp;</SPAN><SPAN style="COLOR: #ff0000">bean</SPAN><SPAN style="COLOR: #0000ff">="sayHelloAdvice"</SPAN><SPAN style="COLOR: #0000ff">/&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">29</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">property</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">30</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">bean</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">31</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;<BR></SPAN><SPAN style="COLOR: #008080">32</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">bean&nbsp;</SPAN><SPAN style="COLOR: #ff0000">id</SPAN><SPAN style="COLOR: #0000ff">="sayHelloService"</SPAN><SPAN style="COLOR: #ff0000">&nbsp;class</SPAN><SPAN style="COLOR: #0000ff">="org.springframework.aop.framework.ProxyFactoryBean"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">33</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">property&nbsp;</SPAN><SPAN style="COLOR: #ff0000">name</SPAN><SPAN style="COLOR: #0000ff">="proxyInterfaces"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SP]]></description>
</item><item>
<title><![CDATA[Spring AOP四种创建通知(拦截器)类型实例]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=25979</link>
<author>littcricket</author>
<pubDate>2007/7/4 13:15:40</pubDate>
<description><![CDATA[<A>　
<P>1、Spring只支持方法拦截，也就是说，只能在方法的前后进行拦截，而不能在属性前后进行拦截。<BR>2、Spring支持四种拦截类型：目标方法调用前（before），目标方法调用后（after），目标方法调用前后（around），以及目标方法抛出异常（throw）。<BR>3、前置拦截的类必须实现MethodBeforeAdvice接口，实现其中的before方法。<BR>4、后置拦截的类必须实现AfterReturningAdvice接口，实现其中的afterReturning方法。<BR>5、前后拦截的类必须实现MethodInterceptor接口，实现其中的invoke方法。前后拦截是唯一可以控制目标方法是否被真正调用的拦截类型，也可以控制返回对象。而前置拦截或后置拦截不能控制，它们不能印象目标方法的调用和返回。<BR>但是以上的拦截的问题在于，不能对于特定方法进行拦截，而只能对某个类的全部方法作拦截。所以下面引入了两个新概念：“切入点”和“引入通知”。<BR>6、”切入点“的定义相当于更加细化地规定了哪些方法被哪些拦截器所拦截，而并非所有的方法都被所有的拦截器所拦截。在ProxyFactoryBean的属性中，interceptorNames属性的对象也由拦截（Advice）变成了引入通知（Advisor），正是在Advisor中详细定义了切入点（PointCut）和拦截（Advice）的对应关系，比如常见的基于名字的切入点匹配（NameMatchMethodPointcutAdvisor类）和基于正则表达式的切入点匹配（RegExpPointcutAdvisor类）。这些切入点都属于”静态切入点“，因为他们只在代理创建的时候被创建一次，而不是每次运行都创建。</P>
<P>&nbsp;</P>
<P>下面我们进行实例的开发</P>
<P>&nbsp;</P>
<P>首先创建业务接口：</P>
<P>&nbsp;</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 95%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">package</SPAN><SPAN style="COLOR: #000000">&nbsp;AdvisorTest;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><BR><IMG id=_48_166_Open_Image onclick="this.style.display='none'; document.getElementById('_48_166_Open_Text').style.display='none'; document.getElementById('_48_166_Closed_Image').style.display='inline'; document.getElementById('_48_166_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=_48_166_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_48_166_Closed_Text').style.display='none'; document.getElementById('_48_166_Open_Image').style.display='inline'; document.getElementById('_48_166_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">interface</SPAN><SPAN style="COLOR: #000000">&nbsp;Shopping&nbsp;</SPAN><SPAN id=_48_166_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</SPAN><SPAN id=_48_166_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;String&nbsp;buySomething(String&nbsp;type);<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;String&nbsp;buyAnything(String&nbsp;type);<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;testException();<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN></DIV></DIV>
<P>&nbsp;下面是业务实现类，我们的通知就是以这些实现类作为切面，在业务方法前后加入我们的通知代码</P>
<P>&nbsp;</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 95%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">package</SPAN><SPAN style="COLOR: #000000">&nbsp;AdvisorTest;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><BR><IMG id=_68_596_Open_Image onclick="this.style.display='none'; document.getElementById('_68_596_Open_Text').style.display='none'; document.getElementById('_68_596_Closed_Image').style.display='inline'; document.getElementById('_68_596_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=_68_596_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_68_596_Closed_Text').style.display='none'; document.getElementById('_68_596_Open_Image').style.display='inline'; document.getElementById('_68_596_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;ShoppingImpl&nbsp;</SPAN><SPAN style="COLOR: #0000ff">implements</SPAN><SPAN style="COLOR: #000000">&nbsp;Shopping&nbsp;</SPAN><SPAN id=_68_596_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</SPAN><SPAN id=_68_596_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;Customer&nbsp;customer;<BR><IMG id=_132_154_Open_Image onclick="this.style.display='none'; document.getElementById('_132_154_Open_Text').style.display='none'; document.getElementById('_132_154_Closed_Image').style.display='inline'; document.getElementById('_132_154_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=_132_154_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_132_154_Closed_Text').style.display='none'; document.getElementById('_132_154_Open_Image').style.display='inline'; document.getElementById('_132_154_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;Customer&nbsp;getCustomer()&nbsp;</SPAN><SPAN id=_132_154_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</SPAN><SPAN id=_132_154_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;customer;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG id=_200_231_Open_Image onclick="this.style.display='none'; document.getElementById('_200_231_Open_Text').style.display='none'; document.getElementById('_200_231_Closed_Image').style.display='inline'; document.getElementById('_200_231_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=_200_231_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_200_231_Closed_Text').style.display='none'; document.getElementById('_200_231_Open_Image').style.display='inline'; document.getElementById('_200_231_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;setCustomer(Customer&nbsp;customer)&nbsp;</SPAN><SPAN id=_200_231_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</SPAN><SPAN id=_200_231_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.customer&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;customer;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG id=_274_368_Open_Image onclick="this.style.display='none'; document.getElementById('_274_368_Open_Text').style.display='none'; document.getElementById('_274_368_Closed_Image').style.display='inline'; document.getElementById('_274_368_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=_274_368_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_274_368_Closed_Text').style.display='none'; document.getElementById('_274_368_Open_Image').style.display='inline'; document.getElementById('_274_368_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;String&nbsp;buySomething(String&nbsp;type)&nbsp;</SPAN><SPAN id=_274_368_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</SPAN><SPAN id=_274_368_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.getCustomer().getName()</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;bye&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">type</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;success</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<BR><IMG id=_415_518_Open_Image onclick="this.style.display='none'; document.getElementById('_415_518_Open_Text').style.display='none'; document.getElementById('_415_518_Closed_Image').style.display='inline'; document.getElementById('_415_518_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=_415_518_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_415_518_Closed_Text').style.display='none'; document.getElementById('_415_518_Open_Image').style.display='inline'; document.getElementById('_415_518_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;String&nbsp;buyAnything(String&nbsp;type)&nbsp;</SPAN><SPAN id=_415_518_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</SPAN><SPAN id=_415_518_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.getCustomer().getName()</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;bye&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">type</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;success</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG id=_551_594_Open_Image onclick="this.style.display='none'; document.getElementById('_551_594_Open_Text').style.display='none'; document.getElementById('_551_594_Closed_Image').style.display='inline'; document.getElementById('_551_594_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=_551_594_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_551_594_Closed_Text').style.display='none'; document.getElementById('_551_594_Open_Image').style.display='inline'; document.getElementById('_551_594_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;testException()</SPAN><SPAN id=_551_594_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</SPAN><SPAN id=_551_594_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">throw</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;ClassCastException();<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN></DIV></DIV>
<P>&nbsp;</P>
<P>（1）前置通知</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 配置了前置通知的bean,在执行业务方法前，均会执行前置拦截器的before方法</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 95%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">package</SPAN><SPAN style="COLOR: #000000">&nbsp;AdvisorTest;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;java.lang.reflect.Method;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;org.springframework.aop.MethodBeforeAdvice;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">前置通知</SPAN><SPAN style="COLOR: #008000"><BR><IMG id=_171_346_Open_Image onclick="this.style.display='none'; document.getElementById('_171_346_Open_Text').style.display='none'; document.getElementById('_171_346_Closed_Image').style.display='inline'; document.getElementById('_171_346_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=_171_346_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_171_346_Closed_Text').style.display='none'; document.getElementById('_171_346_Open_Image').style.display='inline'; document.getElementById('_171_346_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;WelcomeAdvice&nbsp;</SPAN><SPAN style="COLOR: #0000ff">implements</SPAN><SPAN style="COLOR: #000000">&nbsp;MethodBeforeAdvice&nbsp;</SPAN><SPAN id=_171_346_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</SPAN><SPAN id=_171_346_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;before(Method&nbsp;method,&nbsp;Object[]&nbsp;args,&nbsp;Object&nbsp;obj)<BR><IMG id=_256_343_Open_Image onclick="this.style.display='none'; document.getElementById('_256_343_Open_Text').style.display='none'; document.getElementById('_256_343_Closed_Image').style.display='inline'; document.getElementById('_256_343_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=_256_343_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_256_343_Closed_Text').style.display='none'; document.getElementById('_256_343_Open_Image').style.display='inline'; document.getElementById('_256_343_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">throws</SPAN><SPAN style="COLOR: #000000">&nbsp;Throwable&nbsp;</SPAN><SPAN id=_256_343_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</SPAN><SPAN id=_256_343_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;type</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">(String)args[</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">];<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Hello&nbsp;welcome&nbsp;to&nbsp;bye&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">type);<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN></DIV></DIV>
<P>&nbsp;</P>
<P>（2）后置通知</P>配置了前置通知的bean,在执行业务方法前，均会执行前置拦截器的afterReturnning方法 
<P>&nbsp;</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 95%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">package</SPAN><SPAN style="COLOR: #000000">&nbsp;AdvisorTest;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;java.lang.reflect.Method;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;org.springframework.aop.AfterReturningAdvice;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;org.springframework.aop.MethodBeforeAdvice;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">后置通知</SPAN><SPAN style="COLOR: #008000"><BR><IMG id=_227_442_Open_Image onclick="this.style.display='none'; document.getElementById('_227_442_Open_Text').style.display='none'; document.getElementById('_227_442_Closed_Image').style.display='inline'; document.getElementById('_227_442_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=_227_442_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_227_442_Closed_Text').style.display='none'; document.getElementById('_227_442_Open_Image').style.display='inline'; document.getElementById('_227_442_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;ThankYouAdvice&nbsp;</SPAN><SPAN style="COLOR: #0000ff">implements</SPAN><SPAN style="COLOR: #000000">&nbsp;AfterReturningAdvice&nbsp;</SPAN><SPAN id=_227_442_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</SPAN><SPAN id=_227_442_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;afterReturning(Object&nbsp;obj,&nbsp;Method&nbsp;method,&nbsp;Object[]&nbsp;arg1,<BR><IMG id=_333_437_Open_Image onclick="this.style.display='none'; document.getElementById('_333_437_Open_Text').style.display='none'; document.getElementById('_333_437_Closed_Image').style.display='inline'; document.getElementById('_333_437_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=_333_437_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_333_437_Closed_Text').style.display='none'; document.getElementById('_333_437_Open_Image').style.display='inline'; document.getElementById('_333_437_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;arg2)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">throws</SPAN><SPAN style="COLOR: #000000">&nbsp;Throwable&nbsp;</SPAN><SPAN id=_333_437_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</SPAN><SPAN id=_333_437_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;type</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">(String)arg1[</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">];<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Hello&nbsp;Thankyou&nbsp;to&nbsp;bye&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">type);<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN></DIV></DIV>
<P>&nbsp;</P>
<P>（3）环绕通知</P>
<P>配置了前置通知的bean,在执行业务方法前后，均会执行前置拦截器的invoke方法</P>
<P>需要注意的是<FONT color=#ff0000>必须调用目标方法，如不调用，目标方法将不被执行</FONT></P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 95%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">package</SPAN><SPAN style="COLOR: #000000">&nbsp;AdvisorTest;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;org.aopalliance.intercept.MethodInterceptor;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;org.aopalliance.intercept.MethodInvocation;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><BR><IMG id=_182_519_Open_Image onclick="this.style.display='none'; document.getElementById('_182_519_Open_Text').style.display='none'; document.getElementById('_182_519_Closed_Image').style.display='inline'; document.getElementById('_182_519_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=_182_519_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_182_519_Closed_Text').style.display='none'; document.getElementById('_182_519_Open_Image').style.display='inline'; document.getElementById('_182_519_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;MethodAdvisor&nbsp;</SPAN><SPAN style="COLOR: #0000ff">implements</SPAN><SPAN style="COLOR: #000000">&nbsp;MethodInterceptor&nbsp;</SPAN><SPAN id=_182_519_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</SPAN><SPAN id=_182_519_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top><BR><IMG id=_253_516_Open_Image onclick="this.style.display='none'; document.getElementById('_253_516_Open_Text').style.display='none'; document.getElementById('_253_516_Closed_Image').style.display='inline'; document.getElementById('_253_516_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=_253_516_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_253_516_Closed_Text').style.display='none'; document.getElementById('_253_516_Open_Image').style.display='inline'; document.getElementById('_253_516_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;Object&nbsp;invoke(MethodInvocation&nbsp;invocation)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">throws</SPAN><SPAN style="COLOR: #000000">&nbsp;Throwable&nbsp;</SPAN><SPAN id=_253_516_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</SPAN><SPAN id=_253_516_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;str</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">(String)invocation.getArguments()[</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">];<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">this&nbsp;is&nbsp;before</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">str</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;in&nbsp;MethodInterceptor</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;obj</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">invocation.proceed();&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">调用目标方法，如不调用，目标方法将不被执行</SPAN><SPAN style="COLOR: #008000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">this&nbsp;is&nbsp;after</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">str</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;in&nbsp;MethodInterceptor</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN></DIV></DIV>
<P>&nbsp;</P>
<P>（4）异常通知</P>
<P>ThrowsAdvice是一个标示接口，我们可以在类中定义一个或多个，来捕获定义异常通知的<STRONG>bean抛出的异常，并在抛出异常前执行相应的方法</STRONG></P>
<P>public void afterThrowing(Throwable throwa){}</P>
<P>或者</P>
<P>public void afterThrowing(Method method,Object[] args,Object target,Throwable throwable){</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 95%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">package</SPAN><SPAN style="COLOR: #000000">&nbsp;AdvisorTest;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;org.springframework.aop.ThrowsAdvice;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><BR><IMG id=_123_236_Open_Image onclick="this.style.display='none'; document.getElementById('_123_236_Open_Text').style.display='none'; document.getElementById('_123_236_Closed_Image').style.display='inline'; document.getElementById('_123_236_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=_123_236_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_123_236_Closed_Text').style.display='none'; document.getElementById('_123_236_Open_Image').style.display='inline'; document.getElementById('_123_236_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;ExceptionAdvisor&nbsp;</SPAN><SPAN style="COLOR: #0000ff">implements</SPAN><SPAN style="COLOR: #000000">&nbsp;ThrowsAdvice&nbsp;</SPAN><SPAN id=_123_236_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</SPAN><SPAN id=_123_236_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG id=_174_234_Open_Image onclick="this.style.display='none'; document.getElementById('_174_234_Open_Text').style.display='none'; document.getElementById('_174_234_Closed_Image').style.display='inline'; document.getElementById('_174_234_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=_174_234_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_174_234_Closed_Text').style.display='none'; document.getElementById('_174_234_Open_Image').style.display='inline'; document.getElementById('_174_234_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;afterThrowing(ClassCastException&nbsp;e)</SPAN><SPAN id=_174_234_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</SPAN><SPAN id=_174_234_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">this&nbsp;is&nbsp;from&nbsp;exceptionAdvisor</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN></DIV></DIV>
<P>&nbsp;</P>
<P>配置文件</P>
<P>&nbsp;</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 95%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">&lt;?</SPAN><SPAN style="COLOR: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"</SPAN><SPAN style="COLOR: #0000ff">?&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">&lt;!</SPAN><SPAN style="COLOR: #ff00ff">DOCTYPE&nbsp;beans&nbsp;PUBLIC&nbsp;"-//SPRING//DTD&nbsp;BEAN//EN"&nbsp;"http://www.springframework.org/dtd/spring-beans.dtd"&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">beans</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">bean&nbsp;</SPAN><SPAN style="COLOR: #ff0000">id</SPAN><SPAN style="COLOR: #0000ff">="customer"</SPAN><SPAN style="COLOR: #ff0000">&nbsp;class</SPAN><SPAN style="COLOR: #0000ff">="AdvisorTest.Customer"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">constructor-arg&nbsp;</SPAN><SPAN style="COLOR: #ff0000">index</SPAN><SPAN style="COLOR: #0000ff">="0"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">value</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000">gaoxiang</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">value</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">constructor-arg</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">constructor-arg&nbsp;</SPAN><SPAN style="COLOR: #ff0000">index</SPAN><SPAN style="COLOR: #0000ff">="1"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">value</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000">26</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">value</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">constructor-arg</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">bean</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;<BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">bean&nbsp;</SPAN><SPAN style="COLOR: #ff0000">id</SPAN><SPAN style="COLOR: #0000ff">="shoppingImpl"</SPAN><SPAN style="COLOR: #ff0000">&nbsp;class</SPAN><SPAN style="COLOR: #0000ff">="AdvisorTest.ShoppingImpl"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">property&nbsp;</SPAN><SPAN style="COLOR: #ff0000">name</SPAN><SPAN style="COLOR: #0000ff">="customer"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">ref&nbsp;</SPAN><SPAN style="COLOR: #ff0000">local</SPAN><SPAN style="COLOR: #0000ff">="customer"</SPAN><SPAN style="COLOR: #0000ff">/&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">property</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">bean</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">&lt;!--</SPAN><SPAN style="COLOR: #008000">&nbsp;前置通知&nbsp;</SPAN><SPAN style="COLOR: #008000">--&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">bean&nbsp;</SPAN><SPAN style="COLOR: #ff0000">id</SPAN><SPAN style="COLOR: #0000ff">="welcomeAdvice"</SPAN><SPAN style="COLOR: #ff0000">&nbsp;class</SPAN><SPAN style="COLOR: #0000ff">="AdvisorTest.WelcomeAdvice"</SPAN><SPAN style="COLOR: #0000ff">/&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">bean&nbsp;</SPAN><SPAN style="COLOR: #ff0000">id</SPAN><SPAN style="COLOR: #0000ff">="welcomeAdviceShop"</SPAN><SPAN style="COLOR: #ff0000">&nbsp;class</SPAN><SPAN style="COLOR: #0000ff">="org.springframework.aop.framework.ProxyFactoryBean"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">property&nbsp;</SPAN><SPAN style="COLOR: #ff0000">name</SPAN><SPAN style="COLOR: #0000ff">="proxyInterfaces"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">value</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000">AdvisorTest.Shopping</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">value</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">property</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">property&nbsp;</SPAN><SPAN style="COLOR: #ff0000">name</SPAN><SPAN style="COLOR: #0000ff">="target"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">ref&nbsp;</SPAN><SPAN style="COLOR: #ff0000">local</SPAN><SPAN style="COLOR: #0000ff">="shoppingImpl"</SPAN><SPAN style="COLOR: #0000ff">/&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">property</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">property&nbsp;</SPAN><SPAN style="COLOR: #ff0000">name</SPAN><SPAN style="COLOR: #0000ff">="interceptorNames"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN]]></description>
</item><item>
<title><![CDATA[xml的四种解析方法 比较 sax，dom，jdom，dom4j]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=25635</link>
<author>littcricket</author>
<pubDate>2007/6/20 14:42:50</pubDate>
<description><![CDATA[<A>　
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">在平时工作中，难免会遇到把</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> XML </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">作为数据存储格式。面对目前种类繁多的解决方案，哪个最适合我们呢？在这篇文章中，我对这四种主流方案做一个不完全评测，仅仅针对遍历</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> XML </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">这块来测试，因为遍历</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> XML </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">是工作中使用最多的（至少我认为）。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR><BR><BR></SPAN><B><SPAN style="FONT-SIZE: 13.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">预</SPAN></B><B><SPAN style="FONT-SIZE: 13.5pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt; mso-bidi-font-family: 宋体"> </SPAN></B><B><SPAN style="FONT-SIZE: 13.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">备</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR><BR>&nbsp;&nbsp;&nbsp; </SPAN><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">测试环境：</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR>&nbsp;&nbsp;&nbsp; AMD </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">毒龙</SPAN><?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><st1:chmetcnv w:st="on" UnitName="g" SourceValue="1.4" HasSpace="False" Negative="False" NumberType="1" TCSC="0"><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">1.4G</SPAN></st1:chmetcnv><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> OC <st1:chmetcnv w:st="on" UnitName="g" SourceValue="1.5" HasSpace="False" Negative="False" NumberType="1" TCSC="0">1.5G</st1:chmetcnv></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">、</SPAN><st1:chmetcnv w:st="on" UnitName="m" SourceValue="256" HasSpace="False" Negative="False" NumberType="1" TCSC="0"><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">256M</SPAN></st1:chmetcnv><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> DDR333</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Windows2000 Server SP4</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Sun JDK <st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False">1.4.1</st1:chsdate>+Eclipse 2.1+Resin 2.1.8</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">，在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> Debug </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">模式下测试。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; </SPAN><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt; mso-bidi-font-family: 宋体">XML </SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">文件格式如下：</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR></SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; &lt;?xml version="1.0" encoding="GB2312"?&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;RESULT&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;VALUE&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;NO&gt;A1234&lt;/NO&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ADDR&gt;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">四川省</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">XX</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">县</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">XX</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">镇</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">XX</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">路</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">X</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">段</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">XX</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">号</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&lt;/ADDR&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/VALUE&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;VALUE&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;NO&gt;B1234&lt;/NO&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ADDR&gt;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">四川省</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">XX</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">市</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">XX</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">乡</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">XX</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">村</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">XX</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">组</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&lt;/ADDR&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/VALUE&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/RESULT&gt; <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; </SPAN><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">测试方法：</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR></SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">采用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> JSP </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">端调用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Bean</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">（至于为什么采用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JSP</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">来调用，请参考：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"></A><A href="http://blog.csdn.net/rosen/archive/2004/10/15/138324.aspx"><SPAN style="COLOR: navy; TEXT-DECORATION: none; text-underline: none">http://blog.csdn.net/rosen/archive/2004/10/15/138324.aspx</SPAN></A><A></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">），让每一种方案分别解析</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">10K</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">100K</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">1000K</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">10000K</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> XML </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">文件，计算其消耗时间（单位</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">:</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">毫秒）。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; <B>JSP </B></SPAN><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">文件：</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR>&nbsp;&nbsp;&nbsp; &lt;%@ page contentType="text/html; charset=gb2312" %&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;%@ page import="com.test.*"%&gt;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; &lt;html&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;body&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;%<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String args[]={""};<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MyXMLReader.main(args);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/body&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/html&gt;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><B><SPAN lang=EN-US style="FONT-SIZE: 13.5pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR></SPAN></B><B><SPAN style="FONT-SIZE: 13.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">测</SPAN></B><B><SPAN style="FONT-SIZE: 13.5pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt; mso-bidi-font-family: 宋体"> </SPAN></B><B><SPAN style="FONT-SIZE: 13.5pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">试</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 13.5pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR>&nbsp;&nbsp;&nbsp; </SPAN><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">首先出场的是</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> DOM</SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">（</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JAXP Crimson </SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">解析器）</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; <o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; DOM </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">是用与平台和语言无关的方式表示</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> XML </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">文档的官方</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> W<st1:chmetcnv w:st="on" UnitName="C" SourceValue="3" HasSpace="False" Negative="False" NumberType="1" TCSC="0">3C</st1:chmetcnv> </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">标准。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOM </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构，然后才能做任何工作。由于它是基于信息层次的，因而</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> DOM </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">被认为是基于树或基于对象的。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOM </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">以及广义的基于树的处理具有几个优点。首先，由于树在内存中是持久的，因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航，而不是像</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> SAX </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">那样是一次性的处理。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOM </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">使用起来也要简单得多。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">另一方面，对于特别大的文档，解析和加载整个文档可能很慢且很耗资源，因此使用其他手段来处理这样的数据会更好。这些基于事件的模型，比如</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> SAX</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; <B>Bean</B></SPAN><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">文件：</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR>&nbsp;&nbsp;&nbsp; package com.test;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; import java.io.*;<BR>&nbsp;&nbsp;&nbsp; import java.util.*;<BR>&nbsp;&nbsp;&nbsp; import org.w<st1:chmetcnv w:st="on" UnitName="C" SourceValue="3" HasSpace="False" Negative="False" NumberType="1" TCSC="0">3c</st1:chmetcnv>.dom.*;<BR>&nbsp;&nbsp;&nbsp; import javax.xml.parsers.*;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; public class MyXMLReader{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static void main(String arge[]){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long lasting =System.currentTimeMillis();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try{&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File f=new File("data_10k.xml");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DocumentBuilder builder=factory.newDocumentBuilder();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Document doc = builder.parse(f);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NodeList nl = doc.getElementsByTagName("VALUE");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i=0;i&lt;nl.getLength();i++){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.print("</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">车牌号码</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">:" +&nbsp; doc.getElementsByTagName("NO").item(i).getFirstChild().getNodeValue());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(" </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">车主地址</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">:" + doc.getElementsByTagName("ADDR").item(i).getFirstChild().getNodeValue());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }catch(Exception e){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">运行时间：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">"+(System.currentTimeMillis() - lasting)+" </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">毫秒</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp; &nbsp;&nbsp; 10k</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">消耗时间：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">265 203 219 172<BR>&nbsp;&nbsp;&nbsp; 100k</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">消耗时间：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">9172 9016 8891 9000<BR>&nbsp; 1000k</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">消耗时间：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">691719 675407 708375 739656<BR>10000k</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">消耗时间：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">OutOfMemoryError<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR>&nbsp;&nbsp;&nbsp; </SPAN><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">接着是</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> SAX</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">这种处理的优点非常类似于流媒体的优点。分析能够立即开始，而不是等待所有的数据被处理。而且，由于应用程序只是在读取数据时检查数据，因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上，应用程序甚至不必解析整个文档；它可以在某个条件得到满足时停止解析。一般来说，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">SAX </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">还比它的替代者</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> DOM </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">快许多。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; </SPAN><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">选择</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> DOM </SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">还是选择</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> SAX </SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">？</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">对于需要自己编写代码来处理</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> XML </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">文档的开发人员来说，选择</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> DOM </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">还是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> SAX </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">解析模型是一个非常重要的设计决策。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> <BR>&nbsp;&nbsp;&nbsp; DOM </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">采用建立树形结构的方式访问</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> XML </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">文档，而</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> SAX </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">采用的事件模型。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> <BR>&nbsp;&nbsp;&nbsp; DOM </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">解析器把</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> XML </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">文档转化为一个包含其内容的树，并可以对树进行遍历。用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> DOM </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">解析模型的优点是编程容易，开发人员只需要调用建树的指令，然后利用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">navigation APIs</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> DOM </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">解析器的时候需要处理整个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> XML </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">文档，所以对性能和内存的要求比较高，尤其是遇到很大的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> XML </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">文件的时候。由于它的遍历能力，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOM </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">解析器常用于</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> XML </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">文档需要频繁的改变的服务中。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> <BR>&nbsp;&nbsp;&nbsp; SAX </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">解析器采用了基于事件的模型，它在解析</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> XML </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">文档的时候可以触发一系列的事件，当发现给定的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">tag</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的时候，它可以激活一个回调方法，告诉该方法制定的标签已经找到。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">SAX </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">对内存的要求通常会比较低，因为它让开发人员自己来决定所要处理的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">tag</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">。特别是当开发人员只需要处理文档中所包含的部分数据时，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">SAX </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">这种扩展能力得到了更好的体现。但用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> SAX </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">解析器的时候编码工作会比较困难，而且很难同时访问同一个文档中的多处不同数据。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> <BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; <B>Bean</B></SPAN><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">文件：</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR>&nbsp;&nbsp;&nbsp; package com.test;<BR>&nbsp;&nbsp;&nbsp; import org.xml.sax.*;<BR>&nbsp;&nbsp;&nbsp; import org.xml.sax.helpers.*;<BR>&nbsp;&nbsp;&nbsp; import javax.xml.parsers.*;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; public class MyXMLReader extends DefaultHandler {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.util.Stack tags = new java.util.Stack();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public MyXMLReader() {<BR>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static void main(String args[]) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long lasting = System.currentTimeMillis();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAXParserFactory sf = SAXParserFactory.newInstance();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAXParser sp = sf.newSAXParser();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MyXMLReader reader = new MyXMLReader();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sp.parse(new InputSource("data_10k.xml"), reader);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (Exception e) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">运行时间：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">" + (System.currentTimeMillis() - lasting) + " </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">毫秒</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void characters(char ch[], int start, int length)&nbsp;throws SAXException {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String tag = (String) tags.peek();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (tag.equals("NO")) { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.print("</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">车牌号码：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">" + new String(ch, start, length));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (tag.equals("ADDR")) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">地址</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">:" + new String(ch, start, length));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void startElement(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String uri,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String localName,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String qName,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Attributes attrs) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tags.push(qName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;10k</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">消耗时间：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">110 47 109 78<BR>&nbsp;&nbsp;&nbsp; 100k</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">消耗时间：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">344 406 375 422<BR>&nbsp; 1000k</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">消耗时间：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">3234 3281 3688 3312<BR>10000k</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">消耗时间：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">32578 34313 31797 31890 30328<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR>&nbsp;&nbsp;&nbsp; </SPAN><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">然后是</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> JDOM </SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"></A><A href="http://www.jdom.org/"><B><SPAN style="COLOR: navy; TEXT-DECORATION: none; text-underline: none">http://www.jdom.org/</SPAN></B></A><A><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; JDOM </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的目的是成为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> Java </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">特定文档模型，它简化与</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> XML </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的交互并且比使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> DOM </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">实现更快。由于是第一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> Java </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">特定模型，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JDOM </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">一直得到大力推广和促进。正在考虑通过</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">“Java </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">规范请求</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> JSR<st1:chmetcnv w:st="on" UnitName="”" SourceValue="102" HasSpace="False" Negative="True" NumberType="1" TCSC="0">-102”</st1:chmetcnv></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">将它最终用作</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">“Java </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">标准扩展</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">”</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">。从</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> 2000 </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">年初就已经开始了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> JDOM </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">开发。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; JDOM </SPAN><SPAN style="FONT-SIZE: 10pt;]]></description>
</item><item>
<title><![CDATA[xml的Jdom解析过程详解]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=25634</link>
<author>littcricket</author>
<pubDate>2007/6/20 14:41:49</pubDate>
<description><![CDATA[<A>　
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">与</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">类似，也是一组用于解析</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">API</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">，它本身不是一个解析器，默认的它内置了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Apache</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Xerces</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">解析器；</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JDOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">与</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">不同的是，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">是跨语言的一套</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">API</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">世界中有很多</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的解析器，同样的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">.Net</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">中也一样内置了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的实现，但是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JDOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">是专门为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">打造的一批</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">API</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JDOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">采用了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">中的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Collection</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">架构来封装集合，是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">爱好者更加熟悉的模式。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JDOM</SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的核心类</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JDOMException<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Document &lt;- DocType<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;- Comment<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;- ProcessingInstruction<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;- Element &lt;- Attribute<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;- Comment<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;- ProcessingInstruction<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;- CDATA<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;- Text<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;- EntityRef<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JDOM</SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">对外都是具体类，无需工厂</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Element</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Attribute</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">ProcessingInstruction</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Comment</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">和其他类都可以直接通过</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">new</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">来声明实例，不需要工厂了，具有使用方便的一面，但同时也限制了扩展，这些暂且不做讨论，我们关心的如何使用，而不是如何优化它的设计。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; Eement rootElem = new Element("root");<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; Document doc = new Document(rootElem);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">就这么简单，一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JDOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Document</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">对象产生了。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JDOM</SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的输入</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JDOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的输入允许各种类型，如</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">SAX</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">事件、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">文档、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JDBC</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">ResultSet</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">、文件、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Stream</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">、远程</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">URI</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">等等，这里先研究最简单也是最常用的两种（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">SAXBuilder</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOMBuilder</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">）。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">//SAXBuilder</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">构建一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JDOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Document<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">SAXBuilder builder = new SAXBuilder();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Document doc = builder.build(new FileInputStream("text.xml"));<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">//DOMBuilder</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">构建一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JDOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Document<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOMBuilder builder = new DOMBuilder();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Document doc = builder.build(aDOMDocument);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">记住：只有当输入是一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Document</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的时候，才采用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOMBuilder</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">，否则</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">SAXBuilder</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">是首选。原因不是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOMBuilder</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">不能接受其他参数，而是性能问题。在实现中与</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">SAXBuilder</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">比起来，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOMBuilder</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">绕了一个圈子，所以理论上说性能必有影响。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JDOM</SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的输出</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JDOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">有专门的输入类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">XMLOutputer,SAXOutputer,DOMOutputer</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">。与允许各种输入一样，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JDOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">通过这些类允许各种输出。如输出一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Document</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">，输出</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">文件，输入</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Stream</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">等等，方法很简单，都是通过</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">output()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的重载方法来实现，具体产看</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JavaDoc</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">即可。一个简单的例子：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">XMLOutputer outputer = new XMLOutputer("&nbsp; ",true,"UTF-8");<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">outputer.output(jdomDocument, new FileOutputStream("result.xml"));<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">这里的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">XMLOutputer</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的构造有几种：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; public XMLOutputer();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;public XMLOutputer(String indent);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;public XMLOutputer(String indent, boolean newLines);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;public XMLOutputer(String indent, boolean newLines,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String encoding);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">其中</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">indent</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">为每行的缩进字符；</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">newLines</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">自动换行，如果为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">false</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">则所有的输出都在一行，可读性很差；</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">encoding</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">为编码，即</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&lt;?xml version=1.0 encoding="UTF-8"&gt;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">中的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">UTF-8</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JDOM</SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的常用</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">API</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">1. Document<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">doc.getContent()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">与</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">doc.setContent(child)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">可以为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Document</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">添加任何类型的节点，其实不止是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Document</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">可以，其他可以有子节点的节点都可以，如</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Element</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">2. Element<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">与</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">不同，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Element</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">下无需获得</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Text</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">就可以直接获取元素文本，尽管</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JDOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的内部实现依然是存在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Text</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">节点的，但是从使用这个角度来说</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">elem.getText()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">与</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">elem.setText("val")</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">这样的方式还是方便了很多。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">与</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">一样，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Element</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">中可以不通过</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Attribute</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">节点直接操作属性，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">elem.getAttribute("key")</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">elem.setAttribte("key","value")<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">3. </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">其他</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">其他的参照</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">JavaDoc</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">即可了，没有什么特别的。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">-----</SPAN><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">值得注意的地方</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">-----<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">1.</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">关于添加节点的顺序</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">通过如下代码为根元素添加一个注释：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Element rootElem = new Element("Root");<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Document doc = new Document(rootElem);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Comment comm = new Comment("This is a comment Test");<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">doc.addContent(comm);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">表面看上去没什么问题，但是结果会是如下状况：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; <SPAN style="COLOR: #660099">&lt;?xml version = "1.0 encoding="UTF-8"&gt;</SPAN><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: #660099; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; &lt;Root&gt;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: #660099; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: #660099; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Root&gt;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: #660099; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;&nbsp;&nbsp; &lt;!--This is a comment Test--&gt;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">问题应该可以看出来了，原因是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">doc.addContent(comm)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">comm</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">doc</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">之后。但是没有</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">doc</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">又无法添加</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">comm</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">，这似乎有些矛盾，怎么办呢？我们可以采用如下办法：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">doc.getContent.add(0,comment);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">这与</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">List</SPAN><SPAN style="FONT-SIZE: 10]]></description>
</item><item>
<title><![CDATA[xml的SAX解析过程详解]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=25633</link>
<author>littcricket</author>
<pubDate>2007/6/20 14:41:24</pubDate>
<description><![CDATA[<A>　
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Xml</SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">技术简介</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR></SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Xml</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">文件有两种约束类型，包括文档类型定义（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DTD</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">）和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Xml </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">模式（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Schema</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">）。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Xml DTD</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">被包含在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">xml1</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的标准里。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Xml </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">模式被包含在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">W<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><st1:chmetcnv w:st="on" UnitName="C" SourceValue="3" HasSpace="False" Negative="False" NumberType="1" TCSC="0">3C</st1:chmetcnv></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">的标准中。在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">xml </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">数据和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">xml </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">模式两者之间有很多的区别。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR>A</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">．</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> xml</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">模式支持的数据类型比</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">xml DTD</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">多；</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR>B</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">．</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> xml</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">模式在无序的情况下使用起来比</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">xml DTD</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">更方便；</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR>C</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">．</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> xml</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">模式支持名字空间，可以在不同的文件中定义相同的方法等。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR>D</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">．</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"> xml</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">模式形成的文档可以被多种标准解析，如</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">dom</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">sax</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">或者</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">jdom</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">等，而</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">xml DTD</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">方式下确不行。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR></SPAN><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">SAX</SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">解析方式</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR></SPAN></B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">上面我简要介绍了几种解析</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">xml</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">文件的技术，这里我们使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">SAX</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">技术给出一个小例子，大家可以从这个例子中发现如果你能够掌握一些开源软件包，你就可以很快掌握解析</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">xml</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">数据的技术。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR></SPAN><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">制作一个简单的</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">xml</SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">文件</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">component.xml</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align=left><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&lt;?xml version="1.0"?&gt;<BR>&lt;XmlComponents&gt;<BR><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>&lt;XmlComponent&gt;<BR><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>&lt;ComNo&gt;1&lt;/ComNo&gt;<BR><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>&lt;/XmlComponent&gt;<BR>&lt;/XmlComponents&gt;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">下载</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">xerces.jar</SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">软件包</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Apache</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">网站上</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">×××</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">下载</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">xerces.jar</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">软件包，这个包中包含了上面我们列举的几种解析</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">xml</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">数据的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">API</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">。然后将这个软件包加入到程序的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">classpath</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">中。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR></SPAN><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">制作解析类</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">MySaxParser.java</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align=left><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">import java.io.IOException;<BR>import org.xml.sax.*;<BR>import org.xml.sax.helpers.*;<BR>import javax.xml.parsers.*;<BR><BR>public class MySaxParser extends DefaultHandler {<BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>private static int INDENT = 2;<BR><BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>// </SPAN><SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">运行主方法<SPAN lang=EN-US><BR>public static void main(String[] argv) {<BR>//<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>if (argv.length != 1) {<BR>//<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("Usage: java ds.MySaxParser [URI]");<BR>//<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.exit(0);<BR>//<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>}<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>System.setProperty("javax.xml.parsers.SAXParserFactory", "org.apache.xerces.jaxp.SAXParserFactoryImpl");<BR>//<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>String uri = argv[0];<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>String uri = "Components.xml";<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>try {<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>SAXParserFactory parserFactory = SAXParserFactory.newInstance();<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>parserFactory.setValidating(false);<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;</SPAN>parserFactory.setNamespaceAware(false);<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>MySaxParser MySaxParserInstance = new MySaxParser();<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>SAXParser parser = parserFactory.newSAXParser();<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>parser.parse(uri, MySaxParserInstance);<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>}<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>catch(IOException ex) {<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>ex.printStackTrace();<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>}<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>catch(SAXException ex) {<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>ex.printStackTrace();<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>}<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>catch(ParserConfigurationException ex) {<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>ex.printStackTrace();<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>}<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>catch(FactoryConfigurationError ex) {<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>ex.printStackTrace();<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>}<BR><BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>}<BR><BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>private int idx = 0; //indent<BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>// </SPAN>处理各种分隔符号<SPAN lang=EN-US><BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public void characters(char[] ch, int start, int length) throws SAXException {<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>//instantiates s, indents output, prints character values in element<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>String s = new String(ch, start, length);<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>if (!s.startsWith("\n")) //</SPAN>空的<SPAN lang=EN-US>value</SPAN>不打印<SPAN lang=EN-US><BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>System.out.println(getIndent()+ " Value: " + s);<BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>}<BR><BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>// </SPAN>处理文档尾<SPAN lang=EN-US><BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public void endDocument() throws SAXException {<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>idx -= INDENT;<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>System.out.println(getIndent() + "end document");<BR><BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("...PARSING ends");<BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>}<BR><BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>// </SPAN>处理标记尾<SPAN lang=EN-US><BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public void endElement(String uri, String localName, String qName) throws SAXException {<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>idx -= INDENT;<BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>}<BR><BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>// </SPAN>处理文档的起始点<SPAN lang=EN-US><BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public void startDocument() throws SAXException {<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>idx += INDENT;<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("PARSING begins...");<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>System.out.println(getIndent() + "start document: ");<BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>}<BR><BR>// </SPAN>处理标记头<SPAN lang=EN-US><BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>idx += INDENT;<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>System.out.println('\n' + getIndent() + "start element: " + qName);<BR><BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>}<BR><BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>private String getIndent() {<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>StringBuffer sb = new StringBuffer();<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>for (int i = 0; i &lt; idx; i++)<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>sb.append(" ");<BR><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>return sb.toString();<BR><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>}<BR><BR>}<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">总结，虽然解析</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">xml</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">数据很复杂，因为涉及了很多的递归算法，但是我们可以使用业界比较成熟的解析</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">API</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">来进行</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">xml</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">数据处理。我现在只是给出了一个非常简单的例子，但是在真实系统中远比这个要复杂的多，大家以后在使用的使用会发现还是有很多的工作要做的。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&nbsp;<BR><BR style="mso-special-character: line-break"><BR style="mso-special-character: line-break"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1592786<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P></A>]]></description>
</item><item>
<title><![CDATA[xml的dom解析过程详解]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=25632</link>
<author>littcricket</author>
<pubDate>2007/6/20 14:40:48</pubDate>
<description><![CDATA[<A>　
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">一、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">前言</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">解<SPAN class=noted>析</SPAN></SPAN><SPAN class=noted><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">XML</SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">文档，最常<SPAN class=noted>用的有两种</SPAN>方法：使用基于事件的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">简单</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">API</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Simple&nbsp;API&nbsp;for&nbsp;XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）称为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">SAX</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">和基于树和节点的文档对象模型（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Document&nbsp;Object&nbsp;Module</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）称为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Sun</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">公司提供了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Java&nbsp;API&nbsp;for&nbsp;XML&nbsp;Parsing</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">JAXP</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）接口来使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">SAX</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">，通过</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">JAXP</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">，我们可以使用任何与</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">JAXP</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">兼容的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">解析器。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR>JAXP</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">接口包含了三个包：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">1</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;org.w<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><st1:chmetcnv w:st="on" UnitName="C" SourceValue="3" HasSpace="False" Negative="False" NumberType="1" TCSC="0">3c</st1:chmetcnv>.d<SPAN class=noted>om</SPAN>&nbsp;&nbsp;W<st1:chmetcnv w:st="on" UnitName="C" SourceValue="3" HasSpace="False" Negative="False" NumberType="1" TCSC="0">3C</st1:chmetcnv></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">推荐的用于</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">标准规划文档对象模型的接口。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">2</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;org.xml.<SPAN class=noted>sax</SPAN>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">用于对</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">进行语法分析的事件驱动的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">简单</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">API</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">SAX</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">3</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;javax.xml.parsers</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">解析器工厂工具，程序员获得并配置特殊的特殊语法分析器。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">二、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">前提</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR><BR><BR>DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">编程不要其它的依赖包，因为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">JDK</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">里自带的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">JDK</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">里含有的上面提到的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">org.w<st1:chmetcnv w:st="on" UnitName="C" SourceValue="3" HasSpace="False" Negative="False" NumberType="1" TCSC="0">3c</st1:chmetcnv>.dom</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">org.xml.sax&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">javax.xml.parsers</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">包就可以满意条件了。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">三、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">解析</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">文档</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">我们现在来看看</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">是如何解析</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">的吧！同样的，我将从一个简单的不能再简单的例子来说明</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">是如何解析</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">文档的，先让我们看看</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">是什么内容吧：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR>&lt;?xml&nbsp;version="1.0"&nbsp;encoding="gb2312"?&gt;<BR><BR><BR><BR>&lt;books&gt;<BR><BR><BR><BR>&nbsp;&nbsp;&lt;book&nbsp;email="zhoujunhui"&gt;<BR><BR><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;rjzjh&lt;/name&gt;<BR><BR><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;price&gt;jjjjjj&lt;/price&gt;<BR><BR><BR><BR>&nbsp;&nbsp;&lt;/book&gt;<BR><BR><BR><BR>&lt;/books&gt;<BR><BR><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">简单的不能再简单了。但是该有的都有了，根元素、属性、子节点。好了，能反应问题就行了，下面来看看解析这个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">文件的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">代码吧！</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR>1&nbsp;public&nbsp;class&nbsp;DomParse&nbsp;{<BR><BR>2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;DomParse(){&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR><BR>3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DocumentBuilderFactory&nbsp;domfac=DocumentBuilderFactory.newInstance();<BR><BR>4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<BR><BR>5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DocumentBuilder&nbsp;dombuilder=domfac.newDocumentBuilder();<BR><BR>6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InputStream&nbsp;is=new&nbsp;FileInputStream("bin/library.xml");<BR><BR>7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Document&nbsp;doc=dombuilder.parse(is);<BR><BR>8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR><BR>9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Element&nbsp;root=doc.getDocumentElement();<BR><BR>10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NodeList&nbsp;books=root.getChildNodes();<BR><BR>11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(books!=null){<BR><BR>12&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;for(int&nbsp;i=0;i&lt;books.getLength();i++){<BR><BR>13&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;Node&nbsp;book=books.item(i);<BR><BR>14&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;if(book.getNodeType()==Node.ELEMENT_NODE){<BR><BR>15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;email=book.getAttributes().getNamedItem("email").getNodeValue();<BR><BR>16&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(email);<BR><BR>17&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(Node&nbsp;node=book.getFirstChild();node!=null;node=node.getNextSibling()){<BR><BR>18&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(node.getNodeType()==Node.ELEMENT_NODE){<BR><BR>19&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(node.getNodeName().equals("name")){<BR><BR>20&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;&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;String&nbsp;name=node.getNodeValue();<BR><BR>21&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;&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;String&nbsp;name1=node.getFirstChild().getNodeValue();<BR><BR>22&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;&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;System.out.println(name);<BR><BR>23&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;&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;System.out.println(name1);<BR><BR>24&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>25&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(node.getNodeName().equals("price")){<BR><BR>26&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;&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;String&nbsp;price=node.getFirstChild().getNodeValue();<BR><BR>27&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;&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;System.out.println(price);<BR><BR>28&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>29&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>30&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>31&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;}<BR><BR>32&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;}<BR><BR>33&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>34&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(ParserConfigurationException&nbsp;e)&nbsp;{<BR><BR>35&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<BR><BR>36&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(FileNotFoundException&nbsp;e)&nbsp;{<BR><BR>37&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<BR><BR>38&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(SAXException&nbsp;e)&nbsp;{<BR><BR>39&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<BR><BR>40&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(IOException&nbsp;e)&nbsp;{<BR><BR>41&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<BR><BR>42&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>43&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>44&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;{<BR><BR>45&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;DomParse();<BR><BR>46&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>47&nbsp;}<BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">四、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">代码解释</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">先看看这个程序引用类：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR>import&nbsp;java.io.FileInputStream;<BR><BR>import&nbsp;java.io.FileNotFoundException;<BR><BR>import&nbsp;java.io.IOException;<BR><BR>import&nbsp;java.io.InputStream;<BR><BR>import&nbsp;javax.xml.parsers.DocumentBuilder;<BR><BR>import&nbsp;javax.xml.parsers.DocumentBuilderFactory;<BR><BR>import&nbsp;javax.xml.parsers.ParserConfigurationException;<BR><BR>//</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">下面主要是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">org.xml.sax</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">包的类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR>import&nbsp;org.w<st1:chmetcnv w:st="on" UnitName="C" SourceValue="3" HasSpace="False" Negative="False" NumberType="1" TCSC="0">3c</st1:chmetcnv>.dom.Document;<BR><BR>import&nbsp;org.w<st1:chmetcnv w:st="on" UnitName="C" SourceValue="3" HasSpace="False" Negative="False" NumberType="1" TCSC="0">3c</st1:chmetcnv>.dom.Element;<BR><BR>import&nbsp;org.w<st1:chmetcnv w:st="on" UnitName="C" SourceValue="3" HasSpace="False" Negative="False" NumberType="1" TCSC="0">3c</st1:chmetcnv>.dom.Node;<BR><BR>import&nbsp;org.w<st1:chmetcnv w:st="on" UnitName="C" SourceValue="3" HasSpace="False" Negative="False" NumberType="1" TCSC="0">3c</st1:chmetcnv>.dom.NodeList;<BR><BR>import&nbsp;org.xml.sax.SAXException;<BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">上面那么简单的代码一看就明白了，但是为了介绍个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">编程的大概还是来看看这个程序吧：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">1</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">得到</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">解析器的工厂实例</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DocumentBuilderFactory&nbsp;domfac=DocumentBuilderFactory.newInstance();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">得到</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">javax.xml.parsers.DocumentBuilderFactory;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">类的实例就是我们要的解析器工厂</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">2</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">从</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">工厂获得</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">解析器</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><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;DocumentBuilder&nbsp;dombuilder=domfac.newDocumentBuilder();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">通过</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">javax.xml.parsers.DocumentBuilderFactory</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">实例的静态方法</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">newDocumentBuilder()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">得到</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">解析器</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">3</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">把要解析的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">文档转化为输入流，以便</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">解析器解析它</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InputStream&nbsp;is=new&nbsp;FileInputStream("bin/library.xml");<BR><BR>InputStream</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">是一个接口。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">4</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">解析</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">文档的输入流，得到一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Document<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Document&nbsp;doc=dombuilder.parse(is);<BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">由</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">文档的输入流得到一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">org.w<st1:chmetcnv w:st="on" UnitName="C" SourceValue="3" HasSpace="False" Negative="False" NumberType="1" TCSC="0">3c</st1:chmetcnv>.dom.Document</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">对象，以后的处理都是对</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Document</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">对象进行的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">5</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">得到</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">文档的根节点</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Element&nbsp;root=doc.getDocumentElement();<BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">中只有根节点是一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">org.w<st1:chmetcnv w:st="on" UnitName="C" SourceValue="3" HasSpace="False" Negative="False" NumberType="1" TCSC="0">3c</st1:chmetcnv>.dom.Element</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">对象。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">6</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）得到节点的子节点</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NodeList&nbsp;&nbsp;books=root.getChildNodes();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(int&nbsp;i=0;i&lt;books.getLength();i++){<BR><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;Node&nbsp;book=books.item(i);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">这是用一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">org.w<st1:chmetcnv w:st="on" UnitName="C" SourceValue="3" HasSpace="False" Negative="False" NumberType="1" TCSC="0">3c</st1:chmetcnv>.dom.NodeList</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">接口来存放它所有子节点的，还有一种轮循子节点的方法，后面有介绍</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">7</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">取得节点的属性值</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;email=book.getAttributes().getNamedItem("email").getNodeValue();<BR><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(email);<BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">注意，节点的属性也是它的子节点。它的节点类型也是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Node.ELEMENT_NODE<BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">8</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）轮循子节点</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(Node&nbsp;node=book.getFirstChild();node!=null;node=node.getNextSibling()){<BR><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(node.getNodeType()==Node.ELEMENT_NODE){<BR><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(node.getNodeName().equals("name")){<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;&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;String&nbsp;name=node.getNodeValue();<BR><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;&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;String&nbsp;name1=node.getFirstChild().getNodeValue();<BR><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;&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;System.out.println(name);<BR><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;&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;System.out.println(name1);<BR><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(node.getNodeName().equals("price")){<BR><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;&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;String&nbsp;price=node.getFirstChild().getNodeValue();<BR><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;&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;System.out.println(price);<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">这段代码的打印输出为：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR>null<BR><BR><BR><BR>alterrjzjh<BR><BR><BR><BR>jjjjjj<BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">从上面可以看出</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><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;String&nbsp;name=node.getNodeValue();&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">是一个空值。而</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><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;String&nbsp;name1=node.getFirstChild().getNodeValue();&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">才是真正的值，这是因为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">把</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&lt;name&gt;rjzjh&lt;/name&gt;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">也当作是两层结构的节点，其父节点为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&lt;name&gt;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">节点本身，且它只有一个子节点（如果有属性的话就不止一个了！），子节点是它的值</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">“rjzjh”</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">，所以我们看到上面的结果。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">还有，子节点的节点类型也是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Node.ELEMENT_NODE</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">型的，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">node.getNextSibling()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">方法是取下一个相邻的节点。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">五、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">结点</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR><BR><BR>DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">是一些节点的集合，由于文档中可能包含有不同类型的信息，所以定义了几种不同类型的节点。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">中最常见的节点类型有：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">1</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）元素：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">元素是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">的基本构件。元素的子节点可以是其它元素、文本节点或两者都有。元素节点还可以只含有属性这一唯一类型的节点。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">2</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）属性：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">属性节点包含关于元素节点的信息，但它不是元素的子节点</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">3</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）文本：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">文本节点文本信息，或干脆是空白的文本。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">4</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）文档：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">文档节点是整个文档中所有其它节点的父节点</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">元素是一种很重要的类型节点，元素节点可以是其他节点的容器。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">六、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">DOM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">解析</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">XML</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">文档的步骤：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><BR><BR><BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">主要几步见第四点的（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">1</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">），（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">2</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">），（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">3</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">），（</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">4</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）步骤</SPAN></P></A>]]></description>
</item><item>
<title><![CDATA[使用SAX解析XML]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=25631</link>
<author>littcricket</author>
<pubDate>2007/6/20 14:39:01</pubDate>
<description><![CDATA[<A>　
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><B><SPAN style="FONT-SIZE: 22pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 22pt; mso-bidi-font-size: 12.0pt"><FONT face="Times New Roman">SAX</FONT></SPAN></B><B><SPAN style="FONT-SIZE: 22pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">解析</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 22pt; mso-bidi-font-size: 12.0pt"><FONT face="Times New Roman">XML</FONT></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一、</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">前言</SPAN><SPAN lang=EN-US><FONT face="Times New Roman"> </FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">解析</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">XML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文档，最常用的有两种方法：使用基于事件的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">XML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">简单</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">API</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Simple API for XML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）称为</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SAX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和基于树和节点的文档对象模型（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Document Object Module</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）称为</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DOM</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Sun</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">公司提供了</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Java API for XML Parsing</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">JAXP</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）接口来使用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SAX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DOM</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，通过</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">JAXP</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，我们可以使用任何与</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">JAXP</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">兼容的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">XML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">解析器。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">JAXP</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口包含了三个包：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">1</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; org.w<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><st1:chmetcnv w:st="on" UnitName="C" SourceValue="3" HasSpace="False" Negative="False" NumberType="1" TCSC="0">3c</st1:chmetcnv>.dom<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>W<st1:chmetcnv w:st="on" UnitName="C" SourceValue="3" HasSpace="False" Negative="False" NumberType="1" TCSC="0">3C</st1:chmetcnv></FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">推荐的用于</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">XML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">标准规划文档对象模型的接口。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">2</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; org.xml.sax<SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN></FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用于对</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">XML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进行语法分析的事件驱动的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">XML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">简单</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">API</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SAX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">3</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; javax.xml.parsers</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">解析器工厂工具，程序员获得并配置特殊的特殊语法分析器。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">二、</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">前提</SPAN><SPAN lang=EN-US><FONT face="Times New Roman"> </FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">DOM</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">编程不要其它的依赖包，因为</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">JDK</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">里自带的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">JDK</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">里含有的上面提到的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">org.w<st1:chmetcnv w:st="on" UnitName="C" SourceValue="3" HasSpace="False" Negative="False" NumberType="1" TCSC="0">3c</st1:chmetcnv>.dom</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">org.xml.sax </FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">javax.xml.parsers</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包就可以满意条件了。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">三、</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SAX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">解析</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">XML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文档</SPAN><SPAN lang=EN-US><FONT face="Times New Roman"> </FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">SAX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是基于事件的简单</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">API</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，同样的我们也是用一个最简单的例子来看看</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SAX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是如何解析</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">XML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">先来看看我们要解析的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">XML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">代码吧</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT face="Times New Roman"><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white">&lt;?xml version="1.0" encoding="gb2312"?&gt;</SPAN><SPAN lang=EN-US> </SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT face="Times New Roman"><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white">&lt;books&gt;</SPAN><SPAN lang=EN-US> </SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT face="Times New Roman"><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>&lt;book email="zhoujunhui"&gt;</SPAN><SPAN lang=EN-US> </SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT face="Times New Roman"><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>&lt;name addr="address"&gt;rjzjh&lt;/name&gt;</SPAN><SPAN lang=EN-US> </SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT face="Times New Roman"><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>&lt;price&gt;jjjjjj&lt;/price&gt;</SPAN><SPAN lang=EN-US> </SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT face="Times New Roman"><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>&lt;/book&gt;</SPAN><SPAN lang=EN-US> </SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: white; mso-highlight: white"><FONT face="Times New Roman">&lt;/books&gt;</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">简单的不能再简单了。但是该有的都有了，根元素、属性、子节点。好了，能反应问题就行了，下面来看看解析这个</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">XML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">代码吧！</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">1 public class SaxParse {</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">2<SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public SaxParse(){</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">3<SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>SAXParserFactory saxfac=SAXParserFactory.newInstance();</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">4<SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>try {</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">5<SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>SAXParser saxparser=saxfac.newSAXParser();</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">6<SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>InputStream is=new FileInputStream("bin/library.xml");</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">7<SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>saxparser.parse(is,new MySAXHandler());</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">8<SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>} catch (ParserConfigurationException e) {</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">9<SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>e.printStackTrace();</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">10<SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>} catch (SAXException e) {</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">11<SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>e.printStackTrace();</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">12<SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>} catch (FileNotFoundException e) {</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">13<SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>e.printStackTrace();</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">14<SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>} catch (IOException e) {</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">15<SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>e.printStackTrace();</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">16<SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">17<SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">18<SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </SPAN>public static void main(String[] args) {</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">19<SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>new SaxParse();</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">20<SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">21<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这段代码比较短，因为</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SAX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是事件驱动的，它的大部分实现在在另一个</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件中，先别管另一个文件，我们来一个个地分析吧！</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">1</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）得到</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SAX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">解析器的工厂实例</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">3<SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>SAXParserFactory saxfac=SAXParserFactory.newInstance();</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这是一个</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">javax.xml.parsers.SAXParserFactory</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类的实例</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">2</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）从</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SAX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">工厂实例中获得</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SAX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">解析器</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">5<SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>SAXParser saxparser=saxfac.newSAXParser();</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">javax.xml.parsers.SAXParserFactory</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">工厂的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">newSAXParser()</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">3</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）把要解析的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">XML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文档转化为输入流，以便</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DOM</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">解析器解析它</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">6<SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>InputStream is=new FileInputStream("bin/library.xml");</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">InputStream</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是一个接口。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">4</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）解析</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">XML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文档</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">7<SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>saxparser.parse(is,new MySAXHandler());</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">后面就不用看了，都是些没用的代码（相对而言），够简单的吧！</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">注意了，我们新建了一个实例</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">new MySAXHandler()</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个实例里面又有什么东西呢？</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个实例就是</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SAX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的精华所在。我们使用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SAX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">解析器时，必须实现内容处理器</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ContentHandler</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口中的一些回调方法，然而我们不须要全部地实现这些方法，还好，我们有</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">org.xml.sax.helpers.DefaultHandler</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类，看它的类申明：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">public class DefaultHandler</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实现了这么多接口啊，其它的先不管了，至少它实现了</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ContentHandler</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这一接口。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">好了，看看这个类有些什么吧？下面是它的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">代码！</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">public class MySAXHandler extends DefaultHandler {</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>boolean hasAttribute=false;</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Attributes attributes=null;</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>/* </FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（非</SPAN><SPAN lang=EN-US><FONT face="Times New Roman"> Javadoc</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>* @see org.xml.sax.helpers.DefaultHandler#startDocument()</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>*/</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public void startDocument() throws SAXException {</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>System.out.println("</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文档开始打印了</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">");</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>/* </FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（非</SPAN><SPAN lang=EN-US><FONT face="Times New Roman"> Javadoc</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>* @see org.xml.sax.helpers.DefaultHandler#endDocument()</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>*/</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public void endDocument() throws SAXException {</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文档打印结束了</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">");</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>/* </FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（非</SPAN><SPAN lang=EN-US><FONT face="Times New Roman"> Javadoc</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>* @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>*/</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public void startElement(String uri, String localName, String qName,</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Attributes attributes) throws SAXException {</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>if(qName.equals("books")){</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>return;</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>if(qName.equals("book")){</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println(attributes.getQName(0)+attributes.getValue(0));</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>if(attributes.getLength()&gt;0){</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>this.attributes=attributes;</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>this.hasAttribute=true;</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>/* </FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（非</SPAN><SPAN lang=EN-US><FONT face="Times New Roman"> Javadoc</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>* @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>*/</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public void endElement(String uri, String localName, String qName)</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>throws SAXException {</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>if(hasAttribute&amp;&amp;(attributes!=null)){</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>for(int i=0;i&lt;attributes.getLength();i++){</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 4">&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; </SPAN>System.out.println(attributes.getQName(0)+attributes.getValue(0));</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>/* </FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（非</SPAN><SPAN lang=EN-US><FONT face="Times New Roman"> Javadoc</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>* @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>*/</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public void characters(char[] ch, int start, int length)</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>throws SAXException {</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println(new String(ch,start,length));</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">&nbsp;</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">&nbsp;</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman">}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不要看它一大堆，我一一分解给大家看。我们说</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SAX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是基于事件的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">API</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，我们这个类实到了</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ContentHandler</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口中的如下方法：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">1</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">startDocument()<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用于处理文档解析开始事件</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public void startDocument() throws SAXException {</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>System.out.println("</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文档开始打印了</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">");</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">2</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">endDocument()<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用于处理文档解析结束事件</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public void endDocument() throws SAXException {</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文档打印结束了</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">");</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">3</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">startElement<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用于处理元素开始事件</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public void startElement(String uri, String localName, String qName,</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Attributes attributes) throws SAXException {</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>if(qName.equals("books")){</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>return;</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>if(qName.equals("book")){</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println(attributes.getQName(0)+attributes.getValue(0));</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>if(attributes.getLength()&gt;0){</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>this.attributes=attributes;</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>this.hasAttribute=true;</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">第二个参数</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">String qName</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表示这个元素的名字，如：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">根节点</SPAN><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN><SPAN style="BACKGROUND: white; mso-highlight: white">&lt;books&gt;</SPAN>&lt;/books&gt;<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它的</SPAN>]]></description>
</item><item>
<title><![CDATA[【低调朋友和我聊架构师】中国架构师，名符其实有多少？]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=25605</link>
<author>littcricket</author>
<pubDate>2007/6/19 13:56:18</pubDate>
<description><![CDATA[
<P><SPAN style="FONT-SIZE: 12pt">一个多月前，我在博客上发布了一篇阐述编程心得的原创文章——“</SPAN><A href="http://blog.csdn.net/ljc3046/archive/2007/05/08/1600426.aspx"><SPAN style="FONT-SIZE: 12pt"><SPAN>十年编程经验凝结</SPAN></SPAN><SPAN style="FONT-SIZE: 12pt"> <SPAN>与新人们分享</SPAN></SPAN></A><SPAN style="FONT-SIZE: 12pt">”，该文在网上被广为转载，这让我感叹：虽然互联网上信息浩如烟海，但真正原创的有分量的文章却极其少见。这篇原创的最大功劳自不属于我，而是文中那位低调的朋友，朋友跟我说“一般情况下技术人员是不太愿意接受那种很正规的采访的，做人要低调，呵呵”，但很多人因这篇文章对朋友产生了浓厚的兴趣，想与其有更多更深入的交流。</SPAN></P>
<P><SPAN style="FONT-SIZE: 12pt"></SPAN><SPAN style="FONT-SIZE: 12pt">然而朋友说，“不要单独采访我个人，但若有合适的话题，我可以告诉你我的理解”。恰好，我们</SPAN><SPAN style="FONT-SIZE: 12pt">CSDN</SPAN><SPAN style="FONT-SIZE: 12pt">最近在策划一个名为“架构师”的栏目；更恰好，朋友最近技术领域稍微转了下，开始朝企业软件架构方向迈进。于是我找到朋友聊起了架构师。。。</SPAN></P>
<P><SPAN style="FONT-SIZE: 12pt"></SPAN><SPAN style="FONT-SIZE: 12pt">架构师，听起来一个响当当的头衔，但是你能分得清它跟项目经理，产品经理，项目负责人，</SPAN><SPAN style="FONT-SIZE: 12pt">CTO</SPAN><SPAN style="FONT-SIZE: 12pt">等头衔的细微区别吗？参加什么技术活动，一看人家名片亮出来，卡！系统架构师！自己都不好意思回赠名片了，因为自己才印着一软件工程师啊！以后一定换成个“高级软件工程师”再说！要说架构师这词也是翻译过来的，英文是</SPAN><SPAN style="FONT-SIZE: 12pt; COLOR: black">Architect</SPAN><SPAN style="FONT-SIZE: 12pt; COLOR: black">，那么中国的架构师和国外的架构师相比到底怎么样呢？不妨听听我朋友的说法吧（我特地进行了摘录）：</SPAN>&nbsp;</P>
<DIV align=left><SPAN style="FONT-SIZE: 12pt">“系统架构师不是科学家。科学家的工作可以说是非常难得的工作（技术含量高），而架构师的工作主要是非常庞杂，在庞杂的技术要求中寻求最优雅，简洁的解决方案。”</SPAN></DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt"></SPAN>&nbsp;</DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt">“架构师的面临的问题通常有下面几个特征：</SPAN><SPAN style="FONT-SIZE: 12pt">1</SPAN><SPAN style="FONT-SIZE: 12pt">）要解决的问题非常庞杂</SPAN><SPAN style="FONT-SIZE: 12pt">2</SPAN><SPAN style="FONT-SIZE: 12pt">）技术实践的途径非常庞杂</SPAN><SPAN style="FONT-SIZE: 12pt">3</SPAN><SPAN style="FONT-SIZE: 12pt">）系统环境与约束比较复杂。在这一系列凌乱又庞大的要求中，有能力分辨问题的本质，并能给出大家认可的——简洁且具有伸缩性的解决方案的人通常被称为架构师。”</SPAN></DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt"></SPAN>&nbsp;</DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt">“现在</SPAN><SPAN style="FONT-SIZE: 12pt">web</SPAN><SPAN style="FONT-SIZE: 12pt">应用服务器这一块比较火，涉及的技术内容非常多，所以这个领域顶着系统架构师头衔的人特别多。</SPAN><SPAN style="FONT-SIZE: 12pt">”</SPAN></DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt"></SPAN>&nbsp;</DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt">“不能说国内的架构师的总体素质不如国外。关键是国内公司所面临的问题与国外公司面临的问题差距太大。你不能指望在小河里面游泳的人去穿越英吉利海峡。”</SPAN></DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt"></SPAN>&nbsp;</DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt">“不能说国内架构师的能力与‘架构师’这个头衔名不符实。其实是名符其实的，只不过符合的是国内现状的‘实’。”</SPAN></DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt"></SPAN>&nbsp;</DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt">“架构师的职责是提出最佳实践的解决方案。所以有时候需要验证方案的可实践性。只不过大多时候，在熟悉的领域，‘验证方案的可实践性’通过对方案的论述足以证明。”</SPAN></DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt"></SPAN>&nbsp;</DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt">“架构师的另外一个职责是保证‘解决方案’的实践过程不走样。这个需要架构师在团队工作中提供协作。至于协作方式，未必需要编程。但是不排除出现较困难的问题时，动手编程解决的情况。”</SPAN></DIV>
<DIV align=left>&nbsp;</DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt">“从某种意义上说，最下层的架构师和以前的技术负责人差不太多。或者另一种情况，或者架构师的地位相当高，下面的是技术负责人。技术负责人需要负责技术工作的质量因素，需要参与细节；架构师更多负责方案质量，很多时候不需要过多的参与细节。”</SPAN></DIV>
<DIV align=left>&nbsp;</DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt">“架构师也要从技术负责人过渡而来，不可能不参与细节直接成为架构师。没有足够的细节工作积累，不能保证方案的可实践度。提解决方案时就容易出现空中楼阁，看着好看，实施起来特别困难。”</SPAN></DIV>
<DIV align=left>&nbsp;</DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt">“说白了，架构师和技术负责人到底有多大。更多取决于公司的安排，不取决于这个架构师和技术负责人的</SPAN><SPAN style="FONT-SIZE: 12pt">Title</SPAN><SPAN style="FONT-SIZE: 12pt">。”</SPAN></DIV>
<DIV align=left>&nbsp;</DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt">“</SPAN><SPAN style="FONT-SIZE: 12pt">CTO</SPAN><SPAN style="FONT-SIZE: 12pt">是和技术有关系的最高负责人，要承担与公司技术相关问题的行政责任。”</SPAN></DIV>
<DIV align=left>&nbsp;</DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt">总而言之，朋友把这个“架构师”的定义是剖析得淋漓尽致了，就看大家如何对号入座了：）</SPAN></DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt"></SPAN>&nbsp;</DIV>
<DIV align=left><SPAN style="FONT-SIZE: 12pt">（完）</SPAN></DIV>]]></description>
</item><item>
<title><![CDATA[学习JavaEE所必需的]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=24568</link>
<author>littcricket</author>
<pubDate>2007/5/9 13:57:31</pubDate>
<description><![CDATA[<A>　1.你需要精通面向对象分析与设计(OOA/OOD)、涉及模式(GOF，J2EEDP)以及综合模式。你应该十分了解UML，尤其是class，object，interaction以及statediagrams。 
<P>　　2.你需要学习JAVA语言的基础知识以及它的核心类库(collections，serialization，streams，networking， multithreading，reflection，event，handling，NIO，localization，以及其他)。</P>
<P>　　3.你应该了解JVM，classloaders，classreflect，以及垃圾回收的基本工作机制等。你应该有能力反编译一个类文件并且明白一些基本的汇编指令。</P>
<P>　　4.如果你将要写客户端程序，你需要学习WEB的小应用程序(applet)，必需掌握GUI设计的思想和方法，以及桌面程序的SWING，AWT， SWT。你还应该对UI部件的JAVABEAN组件模式有所了解。JAVABEANS也被应用在JSP中以把业务逻辑从表现层中分离出来。</P>
<P>　　5.你需要学习java数据库技术，如JDBCAPI并且会使用至少一种persistence/ORM构架，例如Hibernate，JDO， CocoBase，TopLink，InsideLiberator(国产JDO红工厂软件)或者iBatis。</P>
<P>　　6.你还应该了解对象关系的阻抗失配的含义，以及它是如何影响业务对象的与关系型数据库的交互，和它的运行结果，还需要掌握不同的数据库产品运用，比如:oracle，mysql，mssqlserver。</P>
<P>　　7.你需要学习JAVA的沙盒安全模式(classloaders，bytecodeverification，managers，policyandpermissions，<BR>codesigning， digitalsignatures，cryptography，certification，Kerberos，以及其他)还有不同的安全/认证 API，例如JAAS(JavaAuthenticationandAuthorizationService)，JCE (JavaCryptographyExtension)，JSSE(JavaSecureSocketExtension)，以及JGSS (JavaGeneralSecurityService)。</P>
<P>　　8.你需要学习Servlets，JSP，以及JSTL(StandardTagLibraries)和可以选择的第三方TagLibraries。</P>
<P>　　9.你需要熟悉主流的网页框架，例如JSF，Struts，Tapestry，Cocoon，WebWork，以及他们下面的涉及模式，如MVC/MODEL2。</P>
<P>　　10.你需要学习如何使用及管理WEB服务器，例如tomcat，resin，Jrun，并且知道如何在其基础上扩展和维护WEB程序。</P>
<P>　11.你需要学习分布式对象以及远程API，例如RMI和RMI/IIOP。 <BR>　　12.你需要掌握各种流行中间件技术标准和与java结合实现，比如Tuxedo、CROBA，当然也包括javaEE本身。</P>
<P>　　13.你需要学习最少一种的XMLAPI，例如JAXP(JavaAPIforXMLProcessing)，JDOM(JavaforXMLDocumentObjectModel)，DOM4J，或JAXR(JavaAPIforXMLRegistries)。</P>
<P>　　14.你应该学习如何利用JAVAAPI和工具来构建WebService。例如JAX-RPC(JavaAPIforXML/RPC)，SAAJ (SOAPwithAttachmentsAPIforJava)，JAXB(JavaArchitectureforXMLBinding)，JAXM(JavaAPIforXMLMessaging)， JAXR(JavaAPIforXMLRegistries)，或者JWSDP(JavaWebServicesDeveloperPack)。</P>
<P>　　15.你需要学习一门轻量级应用程序框架，例如Spring，PicoContainer，Avalon，以及它们的IoC/DI风格(setter，constructor，interfaceinjection)。</P>
<P>　　16.你需要熟悉不同的J2EE技术，例如JNDI(JavaNamingandDirectoryInterface)，JMS (JavaMessageService)，JTA/JTS(JavaTransactionAPI/JavaTransactionService)，JMX (JavaManagementeXtensions)，以及JavaMail。</P>
<P>　　17.你需要学习企业级JavaBeans(EJB)以及它们的不同组件模式：Stateless/StatefulSessionBeans，EntityBeans(包含Bean- ManagedPersistence[BMP]或者Container-ManagedPersistence[CMP]和它的EJB-QL)，或者 Message-DrivenBeans(MDB)。</P>
<P>　　18.你需要学习如何管理与配置一个J2EE应用程序服务器，如WebLogic，JBoss等，并且利用它的附加服务，例如簇类，连接池以及分布式处理支援。你还需要了解如何在它上面封装和配置应用程序并且能够监控、调整它的性能。</P>
<P>　　19.你需要熟悉面向方面的程序设计以及面向属性的程序设计(这两个都被很容易混淆的缩写为AOP)，以及他们的主流JAVA规格和执行。例如AspectJ和AspectWerkz。</P>
<P>　　20.你需要熟悉对不同有用的API和frame work等来为你服务。例如Log4J(logging/tracing)，Quartz (scheduling)，JGroups(networkgroupcommunication)，JCache(distributedcaching)， Lucene(full-textsearch)，JakartaCommons等等。</P>
<P>21.如果你将要对接或者正和旧的系统或者本地平台，你需要学习JNI (JavaNativeInterface) and JCA (JavaConnectorArchitecture)。</P>
<P>　　22.你需要熟悉JINI技术以及与它相关的分布式系统，比如掌握CROBA。</P>
<P>　　23.你需要JavaCommunityProcess(JCP)以及他的不同JavaSpecificationRequests(JSRs)，例如Portlets(168)，JOLAP(69)，DataMiningAPI(73)，等等。</P>
<P>　　24.你应该熟练掌握一种JAVAIDE例如sunOne，netBeans，IntelliJIDEA或者Eclipse。(有些人更喜欢VI或EMACS来编写文件。随便你用什么了：)</P>
<P>　　25.JAVA(精确的说是有些配置)是冗长的，它需要很多的人工代码(例如EJB)，所以你需要熟悉代码生成工具，例如XDoclet。</P>
<P>　　26.你需要熟悉一种单元测试体系(JNunit)，并且学习不同的生成、部署工具(Ant，Maven)。</P>
<P>　　27.你需要熟悉一些在JAVA开发中经常用到的软件工程过程。例如RUP(RationalUnifiedProcess)andAgilemethodologies。</P>
<P>　　28.你需要能够深入了解加熟练操作和配置不同的操作系统，比如GNU/linux，sunsolaris，macOS等，做为跨平台软件的开发者。</P>
<P>　　29.你还需要紧跟java发展的步伐，比如现在可以深入的学习javaME，以及各种java新规范，技术的运用，如新起的web富客户端技术。</P>
<P>　　30.你必需要对opensource有所了解，因为至少java的很多技术直接是靠开源来驱动发展的，如java3D技术。</P></A>]]></description>
</item><item>
<title><![CDATA[高效读书心得(转)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=24566</link>
<author>littcricket</author>
<pubDate>2007/5/9 13:26:22</pubDate>
<description><![CDATA[
<H2>五、高效读书心得</H2>
<P>&nbsp;&nbsp; 刚好Head First系列开头都有一段教人如何读书的话，再加工整理如下：<BR><BR><STRONG>1.尽量阅读中文版</STRONG><BR>&nbsp; 虽然有人英文很强，有的翻译很差，但AnyWay 中文阅读与理解的时间，略读与快速定位的速度还是要快一些。<BR>&nbsp; <BR><STRONG>2.即时批注、总结笔记与交流</STRONG><BR>&nbsp; 虽然爱书，但发现最有效的读书方式还是不断的制造脂批本，读书时在重要的文字下划线，把自己的心得写在页旁。<BR>&nbsp; 在明天复习一次批注，最好可以有空重新整理笔记，或者拿来与人讨论。&nbsp;<BR>&nbsp;<BR><STRONG>3.大量思考或重复记忆</STRONG><BR>&nbsp; 看书最郁闷的事情就是看完之后脑袋空空了。技术书还好点，虽然看的时候可能很辛苦，但就像学会了骑单车，之后再骑的时候总是会的；而偏设计与管理的书，最容易的事情就是看的时候很快，看完没什么留下到实践中。<BR>&nbsp; 所以，我们不能以看小说的速度来看设计书，要寻找思考的机会，思考是最好的记忆。<BR>&nbsp; 又或者，大量的重复记忆，重复多遍直到无意识的记忆。&nbsp;<BR>&nbsp; <BR><STRONG>4.人体工学</STRONG><BR>&nbsp;&nbsp;那些见缝插针的时间与地点不是看这个书单的好地方。<BR>&nbsp; 环境不要有电视，音乐等强输入源，而微风阳光鸟语等弱输入源则有助活跃大脑。<BR>&nbsp; 看书时大量的喝水。<BR>&nbsp; 如果发现自己的大脑已经疲累，已经在浮光掠影的翻看，就要休息。<BR>&nbsp; 留给大脑消化的时间，看完书不要接着看其他有难度的书或事情。</P>]]></description>
</item><item>
<title><![CDATA[文章收藏:十年编程经验凝结 与新人们分享]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=24564</link>
<author>littcricket</author>
<pubDate>2007/5/9 10:37:03</pubDate>
<description><![CDATA[<A>　
<DIV>有天和朋友聊天，朋友是国内一家大型互联网企业的一位技术主管，朋友把他将近十年研发工作积累的心血总结成两点，这两点朋友刚一提出来我并没有马上明白，只是大约有这么一个概念，我还没达到朋友在技术领域的那种高度，不能彻底领悟他深刻的思想。但我想与众多刚刚踏入IT技术研发领域的新人们分享一下这位朋友的思想，我尽全力来解释阐述朋友的话语，希望能给大家带来一些启发。</DIV>
<DIV>&nbsp;</DIV>
<DIV>第一点是：不断抽象已知的东西。现实生活总是包括很多零散的东西，待解决的问题不会只有一面，所以抽取零散东西的共同属性，聚合不同角度的同一面向，成为从问题领域进入编程领域的第一步。抽象的层次越高，你架构设计就越简单。</DIV>
<DIV>&nbsp;</DIV>
<DIV>第二点是：面对未知的东西用已有的抽象经验来模拟体验，从而不断调整直至达到可以控制未知东西的程度。有了上面第一点的基础，才可能到达这第二点的境界。现实问题总是不断变化着的推陈出新的，从未知到半知到已知，是人认识客观世界的一个过程，恰如人生从天真到懵懂到成熟的过程。</DIV>
<DIV>&nbsp;</DIV>
<DIV>天才是什么？聊着聊着我们突然说到比尔盖茨，说到那些天才黑客，朋友和我都很兴奋。我问朋友，从他总结的两点来看天才是怎么实践这两点的？朋友想了一下说，天才就是生来就有那种抽象的能力，他并不一定局限于计算机领域的空间来看待问题，他拥有从这个世界其他领域来模拟体验计算机领域的天赋，他甚而可以抽象整个世界。</DIV>
<DIV>&nbsp;</DIV>
<DIV>朋友的思想太博大高深，如我这般入行不久的初级程序员怎能领会？但我还是装作深有体会的不断点头，同时把朋友从山巅拉到山脚下。我说：“你说得太抽象了，不如你告诉一个起步阶段的程序员应该怎么慢慢通过实践来逐步达到这种境界吧。”我知道朋友在这方面颇有体会，他以前曾跟我提起他毕业后在第一家公司是怎么接受锤炼的。果然朋友很快开始阐述：“很简单，起步阶段就是专心的模仿。切记不要被那些乱七八糟的东西晃花了眼，什么j2ee与.net之争，什么soa的革命等等，你不要去关心这些东西。当你在公司上班时，会有这样一个矛盾，当你完成公司交待的一个任务时，你可能为了尽快完成任务用了很多别人现成的框架。这本身没问题，但何谓专心的模仿？就是说你在工作之余，需要来研究这些框架，你可以不用这些框架，而是用最原始的方式来写，你会慢慢体会到框架的约束，进而有对框架进行改进的欲望。但是最终你也会发现：其实任何一个框架都比你自己写的要好。然而在你不断模仿的同时你就得到不断的提高。”朋友越讲越起劲，又开始分析高手和低手在起步阶段的差异，“其实所谓学得快，所谓高手，就是说他在模仿的过程中不断比较自己写的东西和框架本身的差异，不断发现问题，想尽办法解决问题，思考得越多，你碰到的问题就会越多，这是一个正向循环，最终你的技术能力就会螺旋式的上升；而低手只会被动的等待问题，一旦问题自己觉得解决得差不多就放下了，这样自然就不会产生更多的问题，最终技术能力就始终停留在那个菜鸟阶段。”</DIV>
<DIV>&nbsp;</DIV>
<DIV>朋友的话让我惭愧不已，我就是典型的不求甚解啊，问题解决得差不多就行，能运行就万岁，总是不去深究，这样给系统留下多大的隐患啊，而且也是对自己极大的不负责任。</DIV>
<DIV>&nbsp;</DIV>
<DIV>聊完了技术方面的东西，我们想聊点轻松的，但是话题仍然离不开那些搞技术的新人们。朋友正好最近替公司招聘人才，面试了很多名校的计算机相关专业的一些毕业生。朋友说他们技术功底不够扎实，我说他们除了这个，心态也很浮躁，恨不得一参加工作就拿大几千的工资，一进公司就做项目经理，太眼高手低。朋友也深有同感，说面试的时候就有一种怪怪的感觉，而且朋友进一步将这种心态问题提升到编程提升到认识论的高度，“其实我觉得他们本质上是一个不能够正确认识自己的问题。认识论其实很简单，首先认识问题，然后解决问题。你说你想做项目经理，那么你需要具备哪些技能，技术上的，管理上的等，你需要多长时间来磨炼这些技能等。编程不也就是这样嘛，认识问题，抽象问题，进行设计编码最终解决问题，其实做所有的事情都是如此。”</DIV>
<DIV>&nbsp;</DIV>
<DIV>跟朋友的这番聊天让我受益匪浅，而让我感受最深的不是上面提及的这些关于编程和心态两方面的道理，而是我体会到：技术人员并不像人们想象中的那么呆板，每个人都在以自己的方式活着，不断参悟人生的玄妙，而技术人员以一种更为奇特的方式和电脑搏斗，付出了更多的心血，当然体悟得也更加深刻，然而最终每个人都会殊途同归。</DIV>
<P>&nbsp;</P></A>]]></description>
</item><item>
<title><![CDATA[《设计模式》学习笔记--桥接Bridge]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=23554</link>
<author>littcricket</author>
<pubDate>2007/3/30 11:01:19</pubDate>
<description><![CDATA[<A>　
<P class=MsoNormal style="BACKGROUND: whitesmoke; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"></A><A href="http://blog.csdn.net/qinysong/archive/2006/08/10/1048219.aspx"><SPAN lang=EN-US style="COLOR: navy; FONT-FAMILY: 宋体; TEXT-DECORATION: none; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; text-underline: none"><SPAN lang=EN-US>《设计模式》学习笔记</SPAN></SPAN><SPAN style="COLOR: navy; TEXT-DECORATION: none; text-underline: none">--</SPAN><SPAN lang=EN-US style="COLOR: navy; FONT-FAMILY: 宋体; TEXT-DECORATION: none; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; text-underline: none"><SPAN lang=EN-US>桥接</SPAN></SPAN><SPAN style="COLOR: navy; TEXT-DECORATION: none; text-underline: none">Bridge</SPAN></A><A> <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 7.5pt 0cm; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">欢迎转载，请注明出处。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt">1</SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-size: 12.0pt">、核心意图：</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">将抽象部分和实现部分分离，使它们都可以独立的变化。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">该模式的目标是通过把高层的抽象和底层的实现分开，分别构建自己的类层次结构，并通过实现部分的接口将两部分进行桥接，从而达到高层抽象和底层实现可以独立的方便扩展的目的。其核心是分离，和委托。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt">2</SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-size: 12.0pt">、身边实例：</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">语言的一个非常重要的特点是平台的无关性，对于一般的高级语言所编写的程序，如果要在不同的平台上运行，为了适应不同平台所带来的指令集及数据类型等所带来的差异，至少需要编译成不同的目标代码。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">语言通过</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">虚拟机实现了平台的无关性，虚拟机通过对底层平台指令集及数据类型等进行统一的抽象，针对不同的平台用不同的虚拟机进行实现，这样</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">应用程序就可以通过编译成符合虚拟机规范的字节码文件，而在不同的平台上都能正确运行。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">这里的虚拟机正是桥接模式一个很好的展示，它隔离了底层实现（指令</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">/</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">数据类型等）和高层的应用程序，对于新开发的每个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">应用程序，都只需要编译一次；而对于一个新平台的支持，也仅需提供一个相应的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">虚拟机，就可以使所有应用系统正确运行。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">应用程序及虚拟机的大体结构图如下：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><v:shapetype id=_x0000_t75 stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"> <v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></v:path><o:lock aspectratio="t" v:ext="edit"></o:lock></v:shapetype><v:shape id=_x0000_i1025 style="WIDTH: 371.25pt; HEIGHT: 109.5pt" alt="" type="#_x0000_t75"><v:imagedata o:href="http://p.blog.csdn.net/images/p_blog_csdn_net/qinysong/bridgeJvm.gif" src="file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\msohtml1\01\clip_image001.gif"></v:imagedata></v:shape><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt">3</SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-size: 12.0pt">、动机简述：</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">在该模式的动机中，描述了一个平台可移植的用户界面工具箱，在该工具箱中会有多种窗口</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Window</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">类型，为了实现平台的可移植性，把窗口的实现部分从窗口类型中抽取出来，构成一个独立的窗口实现</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">WindowImp</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">类层次，从而使得抽象窗口和窗口实现都可以独立变化，以便于支持新的窗口类型和平台实现。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt">4</SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-size: 12.0pt">、模式效果：</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">桥接</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Bridge</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">模式有两个主要效果：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">1</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）通过分离抽象部分和实现部分，使两者可以独立变化；</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">2</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">）向客户隐藏了实现部分，从而当需要扩展</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">/</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">更改实现部分时，不需要重新编译客户代码。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">对于效果</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">1</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">），当抽象部分和实现部分比较多样时，可以显著的减少类的种类，并提高代码的灵活性。假定高层抽象和底层实现分别有</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">5</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">种类型，如果不采用桥接模式，而用继承实现，那么就需要</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">5*5=25</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">个类（另有一个抽象类）；如果采用桥接模式，将抽象部分和实现部分分离，就只需要</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">5+5=10</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">个类就可以（另有两个抽象类），两种实现的类如以下表格中所示：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">继承方式实现：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<TABLE class=MsoNormalTable style="BORDER-COLLAPSE: collapse; mso-padding-alt: 0cm 0cm 0cm 0cm" cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR style="mso-yfti-irow: 0; mso-yfti-firstrow: yes">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 121.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=162 colSpan=2 rowSpan=2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 304.4pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=406 colSpan=5>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-pagination: widow-orphan" align=center><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Implementor<o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 1">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Imp1<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Imp2<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Imp3<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Imp4<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Imp5<o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 2">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" width=81 rowSpan=5>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-pagination: widow-orphan" align=center><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abstraction<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs1<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs1Imp1<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs1Imp2<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs1Imp3<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs1Imp4<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs1Imp5<o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 3">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs2<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs2Imp1<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs2Imp2<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs2Imp3<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs2Imp4<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs2Imp5<o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 4">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs3<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs3Imp1<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs3Imp2<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs3Imp3<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs3Imp4<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs3Imp5<o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 5">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs4<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs4Imp1<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs4Imp2<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs4Imp3<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs4Imp4<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs4Imp5<o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 6; mso-yfti-lastrow: yes">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs5<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs5Imp1<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs5Imp2<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs5Imp3<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs5Imp4<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs5Imp5<o:p></o:p></SPAN></P></TD></TR></TBODY></TABLE>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">桥接模式实现：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<TABLE class=MsoNormalTable style="BORDER-COLLAPSE: collapse; mso-padding-alt: 0cm 0cm 0cm 0cm" cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR style="mso-yfti-irow: 0; mso-yfti-firstrow: yes">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 121.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=162 colSpan=2 rowSpan=2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 304.4pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=406 colSpan=5>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-pagination: widow-orphan" align=center><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Implementor<o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 1">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Imp1<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Imp2<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Imp3<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Imp4<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Imp5<o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 2">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" width=81 rowSpan=5>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-pagination: widow-orphan" align=center><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abstraction<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs1<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 304.4pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" width=406 colSpan=5 rowSpan=5>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-pagination: widow-orphan" align=center><SPAN style="FONT-SIZE: 11pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">通过桥接关联</SPAN><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 3">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs2<o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 4">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs3<o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 5">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs4<o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 6; mso-yfti-lastrow: yes">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 60.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" vAlign=top width=81>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Abs5<o:p></o:p></SPAN></P></TD></TR></TBODY></TABLE>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt">5</SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-size: 12.0pt">、</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt">Java</SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-size: 12.0pt">代码示例：</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">下面代码演示了一个支持不同平台的图形对象应用，图形</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Shape</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">有多种类型，如三角形正方形等，为了在不同平台中实现图形的绘制，把实现部分进行了分离，构成了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">ShapeImp</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">类层次结构，包括在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Windows</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">中的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">ShapeImpWin</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">，和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Unix</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">中的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">ShapeImpUnix</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">，类结构图如下：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<v:shape id=_x0000_i1026 style="WIDTH: 450pt; HEIGHT: 192pt" alt="" type="#_x0000_t75"> <v:imagedata o:href="http://p.blog.csdn.net/images/p_blog_csdn_net/qinysong/bridgeClass.gif" src="file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\msohtml1\01\clip_image002.gif"></v:imagedata></v:shape><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">代码清单如下：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Point</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana">，同上一篇文章</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"></A><A href="http://blog.csdn.]]></description>
</item><item>
<title><![CDATA[关联和依赖关系的区分]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=23540</link>
<author>littcricket</author>
<pubDate>2007/3/29 14:47:28</pubDate>
<description><![CDATA[
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 13pt 0cm; TEXT-INDENT: 9pt; TEXT-ALIGN: left; mso-char-indent-count: 1.0; mso-pagination: widow-orphan; mso-outline-level: 3" align=left><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma; mso-bidi-font-family: Tahoma">依赖是比关联弱的关系，关联代表一种结构化的关系，体现在生成的代码中，以</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Tahoma">java</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma; mso-bidi-font-family: Tahoma">为例：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Tahoma"> &nbsp; <BR>&nbsp; </SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma; mso-bidi-font-family: Tahoma">若类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Tahoma">A</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma; mso-bidi-font-family: Tahoma">单向关联指向类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Tahoma">B</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma; mso-bidi-font-family: Tahoma">，则在类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Tahoma">A</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma; mso-bidi-font-family: Tahoma">中存在一个属性</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Tahoma">B &nbsp; b</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma; mso-bidi-font-family: Tahoma">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Tahoma"> &nbsp; <BR>&nbsp; </SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma; mso-bidi-font-family: Tahoma">若类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Tahoma">A</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma; mso-bidi-font-family: Tahoma">依赖类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Tahoma">B</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma; mso-bidi-font-family: Tahoma">，则不会有这个属性，类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Tahoma">B</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma; mso-bidi-font-family: Tahoma">的实例可能存在于某个方法调用的参数中，或某个方法的局部变量中。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Tahoma"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 13pt 0cm; TEXT-INDENT: 9pt; TEXT-ALIGN: left; mso-char-indent-count: 1.0; mso-pagination: widow-orphan; mso-outline-level: 3" align=left><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma; mso-bidi-font-family: Tahoma">关联会对关系的类增加属性</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Tahoma"> &nbsp; <BR>&nbsp; </SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma; mso-bidi-font-family: Tahoma">依赖则并不对关系的类增加属性</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Tahoma"> &nbsp;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 13pt 0cm; TEXT-INDENT: 9pt; TEXT-ALIGN: left; mso-char-indent-count: 1.0; mso-pagination: widow-orphan; mso-outline-level: 3" align=left><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma; mso-bidi-font-family: Tahoma">从业务角度来讲：关联表示的是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Tahoma">“</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma; mso-bidi-font-family: Tahoma">拥有</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Tahoma">”</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma; mso-bidi-font-family: Tahoma">关系（根据拥有的程度又可分为一般关联，聚合，合成），依赖表示的是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Tahoma">“</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma; mso-bidi-font-family: Tahoma">涉及</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Tahoma">”</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Tahoma; mso-hansi-font-family: Tahoma; mso-bidi-font-family: Tahoma">关系。如汽车跟轮子，车身的关系是关联，但跟汽油、公路的关系就是依赖。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Tahoma"> &nbsp; <BR>&nbsp;</SPAN><B><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="BACKGROUND: white; MARGIN: 13pt 0cm; TEXT-INDENT: 18pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan; mso-outline-level: 3" align=left><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">关联关系就是两个类谁都知道谁，可以相互通信，也就是说只要存在相互通信的连接，就是关联。关联关系分为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">7</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类：普通、递归、限定、或、有序、三元、聚合关联。如人类和计算机类，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">“</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">”</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">就是他们的关联。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman"> &nbsp; <BR>&nbsp; </FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">依赖：类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">A</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">是独立的，若类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">A</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">的改变将导致类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">B</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">的改变，则说明类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">B</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">依赖于类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">A</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">，他们是依赖关系。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<DIV style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: black 1pt solid; mso-element: para-border-div; mso-border-bottom-alt: solid black .75pt">
<P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-outline-level: 2; mso-border-bottom-alt: solid black .75pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-padding-alt: 0cm 0cm 0cm 0cm" align=left><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">在建立对象模型时，很容易把依赖、关联和聚集关系混淆。当对象</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">A</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">和对象</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">B</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">之间存在依赖、关联或聚集关系时，对象</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">A</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">都有可能调用对象</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">B</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">的方法，这是三种关系之间的相同之处，除此之外，它们有着不同的特征。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-outline-level: 2; mso-border-bottom-alt: solid black .75pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-padding-alt: 0cm 0cm 0cm 0cm" align=left><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">1</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">．依赖关系的特征</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-outline-level: 2; mso-border-bottom-alt: solid black .75pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-padding-alt: 0cm 0cm 0cm 0cm" align=left><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><BR></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">对于两个相对独立的系统，当一个系统负责构造另一个系统的实例，或者依赖另一个系统的服务时，这两个系统之间主要体现为依赖关系，例如生产零件的机器和零件，机器负责构造零件对象。再例如充电电池和充电器，充电电池通过充电器来充电。再例如自行车</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">Bicycle</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">和打气筒</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">Pump</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">，自行车通过打气筒来充气。图</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">1-39</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">Bicycle</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类与</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">Pump</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类的类框图。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman"> <o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-outline-level: 2; mso-border-bottom-alt: solid black .75pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-padding-alt: 0cm 0cm 0cm 0cm" align=left><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><v:shapetype id=_x0000_t75 stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></v:path><o:lock aspectratio="t" v:ext="edit"></o:lock></v:shapetype><v:shape id=_x0000_i1025 style="WIDTH: 202.5pt; HEIGHT: 60pt" alt="" type="#_x0000_t75"><v:imagedata o:href="http://www.javathinker.org/java/qufen_1.gif" src="file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\msohtml1\01\clip_image001.gif"><FONT face="Times New Roman"></FONT></v:imagedata></v:shape><BR><BR></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">图</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">1-39 Bicycle</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类与</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">Pump</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类的依赖关系</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-outline-level: 2; mso-border-bottom-alt: solid black .75pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-padding-alt: 0cm 0cm 0cm 0cm" align=left><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">Bicycle</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">Pump</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类之间是依赖关系，在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">Bicycle</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类中无需定义</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">Pump</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类型的变量。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">Bicycle</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类的定义如下：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-outline-level: 2; mso-border-bottom-alt: solid black .75pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-padding-alt: 0cm 0cm 0cm 0cm" align=left><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">public class Bicycle{<BR>/** </FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">给轮胎充气</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman"> */<BR>public void expand(Pump pump){<BR>pump.blow();<BR>}<BR>}<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-outline-level: 2; mso-border-bottom-alt: solid black .75pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-padding-alt: 0cm 0cm 0cm 0cm" align=left><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><BR></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">在现时生活中，通常不会为某一辆自行车配备专门的打气筒，而是在需要充气的时候，从附近某个修车棚里借个打气筒打气。在程序代码中，表现为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">Bicycle</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">expand()</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">方法有个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">Pump</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类型的参数。以下程序代码表示某辆自行车先后到两个修车棚里充气：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-outline-level: 2; mso-border-bottom-alt: solid black .75pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-padding-alt: 0cm 0cm 0cm 0cm" align=left><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">myBicycle.expand(pumpFromRepairShed1); //</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">到第一个修车棚里充气</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><BR><FONT face="Times New Roman">myBicycle.expand(pumpFromRepairShed2); //</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">若干天后，到第二个修车棚里充气</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-outline-level: 2; mso-border-bottom-alt: solid black .75pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-padding-alt: 0cm 0cm 0cm 0cm" align=left><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">2</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">．关联关系的特征</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><BR></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">对于两个相对独立的系统，当一个系统的实例与另一个系统的一些特定实例存在固定的对应关系时，这两个系统之间为关联关系。例如客户和订单，每个订单对应特定的客户，每个客户对应一些特定的订单；再例如公司和员工，每个公司对应一些特定的员工，每个员工对应一特定的公司；再例如自行车和主人，每辆自行车属于特定的主人，每个主人有特定的自行车，图</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">1-40</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">显示了主人和自行车的关联关系。而充电电池和充电器之间就不存在固定的对应关系，同样自行车和打气筒之间也不存在固定的对应关系。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><BR><BR><v:shape id=_x0000_i1026 style="WIDTH: 252.75pt; HEIGHT: 66.75pt" alt="" type="#_x0000_t75"><v:imagedata o:href="http://www.javathinker.org/java/qufen_2.gif" src="file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\msohtml1\01\clip_image002.gif"></v:imagedata></v:shape><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-outline-level: 2; mso-border-bottom-alt: solid black .75pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-padding-alt: 0cm 0cm 0cm 0cm" align=left><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">图</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">1-40 </FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">主人和自行车的关联关系</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-outline-level: 2; mso-border-bottom-alt: solid black .75pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-padding-alt: 0cm 0cm 0cm 0cm" align=left><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><BR><FONT face="Times New Roman">Person</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类与</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">Bicycle</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类之间存在关联关系，这意味着在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">Person</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类中需要定义一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">Bicycle</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类型的成员变量。以下是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">Person</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类的定义：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-outline-level: 2; mso-border-bottom-alt: solid black .75pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-padding-alt: 0cm 0cm 0cm 0cm" align=left><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">public class Person{<BR>private Bicycle bicycle; //</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">主人的自行车</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><BR><BR><FONT face="Times New Roman">public Bicycle getBicycle(){<BR>return bicycle;<BR>}<BR>public void setBicycle(Bicycle bicycle){<BR>this.bicycle=bicycle;<BR>}<BR>/** </FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">骑自行车去上班</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman"> */<BR>public void goToWork(){<BR>bicycle.run();<BR>}<BR>}<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-outline-level: 2; mso-border-bottom-alt: solid black .75pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-padding-alt: 0cm 0cm 0cm 0cm" align=left><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><BR></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">在现时生活中，当你骑自行车去上班时，只要从家里推出自己的自行车就能上路了，不象给自行车打气那样，在需要打气时，还要四处去找修车棚。因此，在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">Person</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">goToWork()</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">方法中，调用自身的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">bicycle</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">对象的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">run()</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">方法。假如</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">goToWork()</FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">方法采用以下的定义方式：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-outline-level: 2; mso-border-bottom-alt: solid black .75pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-padding-alt: 0cm 0cm 0cm 0cm" align=left><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman">/** </FONT></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">骑自行车去上班</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><FONT face="Times New Roman"> */<BR>public void goToWork(Bicycle bicycle){<BR>bicycle.run();<BR>}<o:p></o:p></FONT></SPAN></P></DIV>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">那就好比去上班前，还要先四处去借一辆自行车，然后才能去上班。</SPAN></P>]]></description>
</item><item>
<title><![CDATA[如何正确使用Java I/O输出和读入数据]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=littcricket&amp;id=23537</link>
<author>littcricket</author>
<pubDate>2007/3/29 13:32:59</pubDate>
<description><![CDATA[
<DIV><STRONG><FONT size=6>前言</FONT></STRONG></DIV>
<DIV style="TEXT-INDENT: 24pt">Java的I/O系统使用“流”来处理各种类型的输入、输出数据的任务。</DIV>
<DIV style="TEXT-INDENT: 24pt">在传输数据的过程中，我们需要判断流中传输的数据何时结束这样的问题。这对于我们正确地发送和接收数据是非常关键的。</DIV>
<DIV style="TEXT-INDENT: 24pt">如何判断流的末尾和批数据的末尾，是解决这个问题的关键。本文就是要深入地分析Java I/O输入输出的工作原理，保证我们能够正确地执行数据的发送和接收！</DIV>
<DIV><STRONG><FONT size=6>Java I/O任务</FONT></STRONG></DIV>
<DIV style="TEXT-INDENT: 24pt">一个Java的I/O任务，创建了一个连接两个系统的数据传输管道。它分为两个部分：输入流和输出流。</DIV>
<DIV style="TEXT-INDENT: 24pt">输入流，指的是通过流向本系统的内存传输数据的单向数据传输通道。</DIV>
<DIV style="TEXT-INDENT: 24pt">输出流，指的是通过流向外部系统传输数据的单向数据传输通道。</DIV>
<DIV>&nbsp;</DIV>
<DIV><STRONG><FONT size=5>输入流</FONT></STRONG></DIV>
<DIV><STRONG>&nbsp;</STRONG></DIV>
<DIV style="TEXT-INDENT: 24.1pt"><STRONG>InputStream</STRONG><STRONG>类是</STRONG>表示字节输入流的所有类的超类。这是一个抽象类。</DIV>
<DIV>我们看它提供的读入数据的方法：</DIV>
<DIV><STRONG><FONT size=4>read</FONT></STRONG></DIV><PRE>public abstract int <STRONG>read</STRONG>()</PRE><PRE><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws <A title="java.io 中的类" href="mk:@MSITStore:E:\_Java实用项目资源\_官方API参考\_JDK5中文API参考%5b沈东良shendl_s@hotmail.com%5d.chm::/java/io/IOException.html">IOException</A></SPAN></PRE>
<DIV style="MARGIN-LEFT: 36pt">从输入流读取下一个数据字节。返回 <CODE>0</CODE> 到 <CODE>255</CODE> 范围内的 <CODE>int</CODE> 字节值。如果因已到达流末尾而没有可用的字节，则返回值 <CODE>-1</CODE>。在输入数据可用、检测到流的末尾或者抛出异常前，此方法一直阻塞。 </DIV>
<DIV style="MARGIN-LEFT: 36pt">子类必须提供此方法的一个实现。 </DIV>
<DIV style="MARGIN-LEFT: 36pt"><STRONG>返回：</STRONG> </DIV>
<DIV style="MARGIN-LEFT: 36pt">下一个数据字节，如果到达流的末尾，则返回 <CODE>-1</CODE>。 </DIV>
<DIV style="MARGIN-LEFT: 36pt"><STRONG>抛出：</STRONG> </DIV>
<DIV style="MARGIN-LEFT: 36pt"><CODE><A title="java.io 中的类" href="mk:@MSITStore:E:\_Java实用项目资源\_官方API参考\_JDK5中文API参考%5b沈东良shendl_s@hotmail.com%5d.chm::/java/io/IOException.html"><SPAN>IOException</SPAN></A></CODE> - 如果发生 I/O 错误。</DIV>
<DIV align=center><SPAN>
<HR align=center width="100%" SIZE=2>
</SPAN></DIV>
<DIV><STRONG><FONT size=4>read</FONT></STRONG></DIV><PRE>public int <STRONG>read</STRONG>(byte[]&nbsp;b)</PRE><PRE><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws <A title="java.io 中的类" href="mk:@MSITStore:E:\_Java实用项目资源\_官方API参考\_JDK5中文API参考%5b沈东良shendl_s@hotmail.com%5d.chm::/java/io/IOException.html">IOException</A></SPAN></PRE>
<DIV style="MARGIN-LEFT: 36pt">从输入流中读取一定数量的字节并将其存储在缓冲区数组 <CODE>b</CODE> 中。以整数形式返回实际读取的字节数。在输入数据可用、检测到文件末尾或者抛出异常前，此方法一直阻塞。 </DIV>
<DIV style="MARGIN-LEFT: 36pt">如果 <CODE>b</CODE> 为 <CODE>null</CODE>，将抛出 <CODE>NullPointerException</CODE>。如果 <CODE>b</CODE> 的长度为 0，则无字节可读且返回 <CODE>0</CODE>；否则，要尝试读取至少一个字节。如果因为流位于文件末尾而没有可用的字节，则返回值 <CODE>-1</CODE>；否则，至少可以读取一个字节并将其存储在 <CODE>b</CODE> 中。 </DIV>
<DIV style="MARGIN-LEFT: 36pt">将读取的第一个字节存储在元素 <CODE>b[0]</CODE> 中，下一个存储在 <CODE>b[1]</CODE> 中，依次类推。读取的字节数最多等于 <CODE>b</CODE> 的长度。让 <EM>k</EM> 为实际读取的字节数；这些字节将存储在元素 <CODE>b[0]</CODE> 至 <CODE>b[</CODE><EM>k</EM><CODE>-1]</CODE> 之间，不影响元素 <CODE>b[</CODE><EM>k</EM><CODE>]</CODE> 至 <CODE>b[b.length-1]</CODE>。 </DIV>
<DIV style="MARGIN-LEFT: 36pt">如果不是因为流位于文件末尾而无法读取读取第一个字节，则抛出 <CODE>IOException</CODE>。特别是，如果输入流已关闭，则抛出 <CODE>IOException</CODE>。 </DIV>
<DIV style="MARGIN-LEFT: 36pt">类 <CODE>InputStream</CODE> 的 <CODE>read(b)</CODE> 方法的效果等同于：</DIV><PRE style="MARGIN-LEFT: 36pt"><CODE>&nbsp;read(b, 0, b.length) </CODE></PRE>
<DIV style="MARGIN-LEFT: 36pt"><STRONG>参数：</STRONG> </DIV>
<DIV style="MARGIN-LEFT: 36pt"><CODE>b</CODE> - 读入数据的缓冲区。 </DIV>
<DIV style="MARGIN-LEFT: 36pt"><STRONG>返回：</STRONG> </DIV>
<DIV style="MARGIN-LEFT: 36pt">读入缓冲区的总字节数，如果由于流末尾已到达而不再有数据，则返回 <CODE>-1</CODE>。 </DIV>
<DIV style="MARGIN-LEFT: 36pt"><STRONG>抛出：</STRONG> </DIV>
<DIV style="MARGIN-LEFT: 36pt"><CODE><A title="java.io 中的类" href="mk:@MSITStore:E:\_Java实用项目资源\_官方API参考\_JDK5中文API参考%5b沈东良shendl_s@hotmail.com%5d.chm::/java/io/IOException.html"><SPAN>IOException</SPAN></A></CODE> - 如果发生 I/O 错误。 </DIV>
<DIV style="MARGIN-LEFT: 36pt"><CODE><A title="java.lang 中的类" href="mk:@MSITStore:E:\_Java实用项目资源\_官方API参考\_JDK5中文API参考%5b沈东良shendl_s@hotmail.com%5d.chm::/java/lang/NullPointerException.html"><SPAN>NullPointerException</SPAN></A></CODE> - 如果 <CODE>b</CODE> 为 <CODE>null</CODE>。 </DIV>
<DIV style="MARGIN-LEFT: 36pt"><STRONG>另请参见：</STRONG> </DIV>
<DIV style="MARGIN-LEFT: 36pt"><A href="mk:@MSITStore:E:\_Java实用项目资源\_官方API参考\_JDK5中文API参考%5b沈东良shendl_s@hotmail.com%5d.chm::/java/io/InputStream.html#read(byte[], int, int)"><CODE>read(byte[], int, int)</CODE></A></DIV>
<DIV align=center><SPAN>
<HR align=center width="100%" SIZE=2>
</SPAN></DIV>
<DIV><STRONG><FONT size=4>read</FONT></STRONG></DIV><PRE>public int <STRONG>read</STRONG>(byte[]&nbsp;b,</PRE><PRE><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;off,</SPAN></PRE><PRE><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;len)</SPAN></PRE><PRE><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws <A title="java.io 中的类" href="mk:@MSITStore:E:\_Java实用项目资源\_官方API参考\_JDK5中文API参考%5b沈东良shendl_s@hotmail.com%5d.chm::/java/io/IOException.html">IOException</A></SPAN></PRE>
<DIV style="MARGIN-LEFT: 36pt">将输入流中最多 <CODE>len</CODE> 个数据字节读入字节数组。尝试读取多达 <CODE>len</CODE> 字节，但可能读取较少数量。以整数形式返回实际读取的字节数。 </DIV>
<DIV style="MARGIN-LEFT: 36pt">在输入数据可用、检测到流的末尾或者抛出异常前，此方法一直阻塞。 </DIV>
<DIV style="MARGIN-LEFT: 36pt">如果 <CODE>b</CODE> 为 <CODE>null</CODE>，则抛出 <CODE>NullPointerException</CODE>。 </DIV>
<DIV style="MARGIN-LEFT: 36pt">如果 <CODE>off</CODE> 为负，或 <CODE>len</CODE> 为负，或 <CODE>off+len</CODE> 大于数组 <CODE>b</CODE> 的长度，则抛出 <CODE>IndexOutOfBoundsException</CODE>。 </DIV>
<DIV style="MARGIN-LEFT: 36pt">如果 <CODE>len</CODE> 为 0，则没有字节可读且返回 <CODE>0</CODE>；否则，要尝试读取至少一个字节。如果因为流位于文件末尾而没有可用的字节，则返回值 <CODE>-1</CODE>；否则，至少可以读取一个字节并将其存储在 <CODE>b</CODE> 中。 </DIV>
<DIV style="MARGIN-LEFT: 36pt">将读取的第一个字节存储在元素 <CODE>b[off]</CODE> 中，下一个存储在 <CODE>b[off+1]</CODE> 中，依次类推。读取的字节数最多等于 <CODE>len</CODE>。让 <EM>k</EM> 为实际读取的字节数；这些字节将存储在元素 <CODE>b[off]</CODE> 至 <CODE>b[off+</CODE><EM>k</EM><CODE>-1]</CODE> 之间，其余元素 <CODE>b[off+</CODE><EM>k</EM><CODE>]</CODE> 至 <CODE>b[off+len-1]</CODE> 不受影响。 </DIV>
<DIV style="MARGIN-LEFT: 36pt">在任何情况下，元素 <CODE>b[0]</CODE> 至 <CODE>b[off]</CODE> 和元素 <CODE>b[off+len]</CODE> 至 <CODE>b[b.length-1]</CODE> 都不会受到影响。 </DIV>
<DIV style="MARGIN-LEFT: 36pt">如果不是因为流位于文件末尾而无法读取第一个字节，则抛出 <CODE>IOException</CODE>。特别是，如果输入流已关闭，则抛出 <CODE>IOException</CODE>。 </DIV>
<DIV style="MARGIN-LEFT: 36pt">类 <CODE>InputStream</CODE> 的 <CODE>read(b,</CODE> <CODE>off,</CODE> <CODE>len)</CODE> 方法只重复调用方法 <CODE>read()</CODE>。如果第一个这样的调用导致 <CODE>IOException</CODE>，则从对 <CODE>read(b,</CODE> <CODE>off,</CODE> <CODE>len)</CODE> 方法的调用中返回该异常。如果对 <CODE>read()</CODE> 的任何后续调用导致 <CODE>IOException</CODE>，则该异常会被捕获并将发生异常时的位置视为文件的末尾；到达该点时读取的字节存储在 <CODE>b</CODE> 中并返回发生异常之前读取的字节数。建议让子类提供此方法的更有效的实现。 </DIV>
<DIV style="MARGIN-LEFT: 36pt"><STRONG>参数：</STRONG> </DIV>
<DIV style="MARGIN-LEFT: 36pt"><CODE>b</CODE> - 读入数据的缓冲区。 </DIV>
<DIV style="MARGIN-LEFT: 36pt"><CODE>off</CODE> - 在其处写入数据的数组 <CODE>b</CODE> 的初始偏移量。 </DIV>
<DIV style="MARGIN-LEFT: 36pt"><CODE>len</CODE> - 要读取的最大字节数。 </DIV>
<DIV style="MARGIN-LEFT: 36pt"><STRONG>返回：</STRONG> </DIV>
<DIV style="MARGIN-LEFT: 36pt">读入缓冲区的总字节数，如果由于已到达流末尾而不再有数据，则返回 <CODE>-1</CODE>。 </DIV>
<DIV style="MARGIN-LEFT: 36pt"><STRONG>抛出：</STRONG> </DIV>
<DIV style="MARGIN-LEFT: 36pt"><CODE><A title="java.io 中的类" href="mk:@MSITStore:E:\_Java实用项目资源\_官方API参考\_JDK5中文API参考%5b沈东良shendl_s@hotmail.com%5d.chm::/java/io/IOException.html"><SPAN>IOException</SPAN></A></CODE> - 如果发生 I/O 错误。 </DIV>
<DIV style="MARGIN-LEFT: 36pt"><CODE><A title="java.lang 中的类" href="mk:@MSITStore:E:\_Java实用项目资源\_官方API参考\_JDK5中文API参考%5b沈东良shendl_s@hotmail.com%5d.chm::/java/lang/NullPointerException.html"><SPAN>NullPointerException</SPAN></A></CODE> - 如果 <CODE>b</CODE> 为 <CODE>null</CODE>。 </DIV>
<DIV style="MARGIN-LEFT: 36pt"><STRONG>另请参见：</STRONG> </DIV>
<DIV style="MARGIN-LEFT: 36pt"><A href="mk:@MSITStore:E:\_Java实用项目资源\_官方API参考\_JDK5中文API参考%5b沈东良shendl_s@hotmail.com%5d.chm::/java/io/InputStream.html#read()"><CODE>read()</CODE></A></DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV><STRONG><FONT size=5>read方法解读</FONT></STRONG></DIV>
<DIV style="TEXT-INDENT: 24pt">这些方法的核心。实际上就是read()方法。</DIV>
<DIV style="TEXT-INDENT: 24pt">这个方法的JavaDoc中指出：</DIV>
<DIV style="TEXT-INDENT: 24pt">“如果因已到达流末尾而没有可用的字节，则返回值 <CODE>-1</CODE>。如果因已到达流末尾而没有可用的字节，则返回值 <CODE>-1</CODE>。在输入数据可用、检测到流的末尾或者抛出异常前，此方法一直阻塞。”</DIV>
<DIV>&nbsp;</DIV>
<DIV>1，read方法会在能够返回流中的字节之前，一直阻塞线程。这就是说，read方法是一个低消耗的监听和读取I/O传输的好方法。</DIV>
<DIV style="TEXT-INDENT: 24pt">这个方法的实现，具有非常高的性能。</DIV>
<DIV>&nbsp;</DIV>
<DIV>2，如果输入流的I/O系统在执行这个read方法时抛出异常，那么显然这个方法会非正常结束，这个也是毫无疑问的。</DIV>
<DIV>&nbsp;</DIV>
<DIV>3，“如果因已到达流末尾而没有可用的字节，则返回值 <CODE>-1</CODE>。”</DIV>
<DIV style="TEXT-INDENT: 24pt">这句话看似没有问题，但实际上有非常大的歧义！什么是流的末尾？只有流的末尾才能返回-1吗？</DIV>
<DIV>&nbsp;</DIV>
<DIV><STRONG><FONT size=4>InputStream类和SocketInputStream类的源码解读</FONT></STRONG></DIV>
<DIV style="TEXT-INDENT: 24pt">通过查看InputStream类的源码，我发现实际上，流，就好比是双向2车道的高速公路。它传输数据是一批一批的。我把它叫做“批数据”。</DIV>
<DIV style="TEXT-INDENT: 24pt">假设A=======B两个系统通过一个I/O流来连接。</DIV>
<DIV style="TEXT-INDENT: 24pt">那么，从B端通向A端的车道，就叫作A的“输入流”。同一条车道，在B这边，叫作B的“输出流”。</DIV>
<DIV style="TEXT-INDENT: 24pt">同理，从A端通向B端的车道，就叫作A的“输出流”。同一条车道，在B这边，就叫作B的“输入流”。</DIV>
<DIV style="TEXT-INDENT: 24pt">&nbsp;</DIV>
<DIV style="TEXT-INDENT: 24pt">数据在这条高速公路上，不是一条一条跑的，而是一批一批跑。</DIV>
<DIV style="TEXT-INDENT: 24pt">&nbsp;</DIV><PRE style="TEXT-INDENT: 24.1pt"><STRONG>OutputStream类，</STRONG>此抽象类是表示输出字节流的所有类的超类。输出流接受输出字节并将这些字节发送到某个接收器。 </PRE><PRE style="TEXT-INDENT: 24pt">&nbsp;</PRE><PRE style="TEXT-INDENT: 24pt">OutputStream类的write方法，每执行一次，就向这条高速公路上发送了一批数据。OutputStream类的一些子类，它们并不是在每次write()方法执行之后立刻把这批数据发送到数据高速公路上的。而是只有在执行flush()方法之后，才把之前write的多批数据真正地发送到数据通道中。</PRE><PRE style="TEXT-INDENT: 24pt">这样，多个write()方法发送的数据就变为了一批数据了！</PRE><PRE style="TEXT-INDENT: 24pt">&nbsp;</PRE><PRE style="TEXT-INDENT: 24pt">通过read()方法读入时，当读完该批数据之后，如果再一次执行read()方法，就会立刻返回-1。</PRE><PRE style="TEXT-INDENT: 24pt">实际上，这是并没有到达流的末尾！仅仅是读完了一批发送的数据而已！</PRE><PRE style="TEXT-INDENT: 24pt">&nbsp;</PRE><PRE style="TEXT-INDENT: 24pt">如果我们又一次执行read()方法，那么，如果：</PRE><PRE>1，流没有结束。也就是说，对面的发送端可能还会发送下一批数据时，就会进入阻塞状态。当前线程暂停，直到读取到输入流中下一批数据的第一个字节。</PRE><PRE>2，流结束了。也就是说，对面的发送端不再发送任何数据，也即：这条数据通道已经没有用了，这时，可以说“到达流的末尾”了！返回-1。</PRE><PRE><SPAN>&nbsp;&nbsp;&nbsp; </SPAN></PRE><PRE style="TEXT-INDENT: 24pt">所以，InputStream及其子类的read()方法的注释是不完整的！</PRE>
<DIV><STRONG><FONT size=5>Read()方法的注释，应该这么说：</FONT></STRONG></DIV>
<DIV><STRONG><FONT size=4>read</FONT></STRONG></DIV><PRE>public abstract int <STRONG>read</STRONG>()</PRE><PRE><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws <A title="java.io 中的类" href="mk:@MSITStore:E:\_Java实用项目资源\_官方API参考\_JDK5中文API参考%5b沈东良shendl_s@hotmail.com%5d.chm::/java/io/IOException.html">IOException</A></SPAN></PRE>
<DIV style="MARGIN-LEFT: 36pt">从输入流读取下一个数据字节。返回 <CODE>0</CODE> 到 <CODE>255</CODE> 范围内的 <CODE>int</CODE> 字节值。</DIV>
<DIV style="MARGIN-LEFT: 36pt">如果在读完一批数据后首次调用read()方法，那么返回-1。表示这批数据已经读完了！</DIV>
<DIV style="MARGIN-LEFT: 36pt">如果因已到达流末尾而没有可用的字节，则返回值 <CODE>-1</CODE>。在输入数据可用、检测到流的末尾或者抛出异常前，此方法一直阻塞。 </DIV>
<DIV style="MARGIN-LEFT: 36pt">子类必须提供此方法的一个实现。 </DIV>
<DIV style="MARGIN-LEFT: 36pt"><STRONG>返回：</STRONG> </DIV>
<DIV style="MARGIN-LEFT: 36pt">下一个数据字节；</DIV>
<DIV style="MARGIN-LEFT: 36pt">如果刚读完一批数据，则返回-1；</DIV>
<DIV style="MARGIN-LEFT: 36pt">如果到达流的末尾，则返回 <CODE>-1</CODE>。 </DIV>
<DIV style="MARGIN-LEFT: 36pt"><STRONG>抛出：</STRONG> </DIV>
<DIV style="MARGIN-LEFT: 36pt"><CODE><A title="java.io 中的类" href="mk:@MSITStore:E:\_Java实用项目资源\_官方API参考\_JDK5中文API参考%5b沈东良shendl_s@hotmail.com%5d.chm::/java/io/IOException.html"><SPAN>IOException</SPAN></A></CODE> - 如果发生 I/O 错误。</DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV><STRONG><FONT size=6>如何正确使用Java I/O输出和读入数据</FONT></STRONG></DIV>
<DIV style="TEXT-INDENT: 24pt">明白了Java的I/O流的工作机理和read方法的执行结果，我们就能够正确地使用Java I/O系统输出和读入数据了。</DIV>
<DIV style="TEXT-INDENT: 24pt">&nbsp;</DIV>
<DIV><STRONG><FONT size=5>如何分批输出数据</FONT></STRONG></DIV>
<DIV style="TEXT-INDENT: 24pt">由于read(…)方法是分批读取数据的，所以，我们应该在输出端正确地分批输出数据。</DIV>
<DIV style="TEXT-INDENT: 24pt">Write(…)方法，然后执行flush()方法能够将多批数据合并成一批数据输出。</DIV>
<DIV style="TEXT-INDENT: 24pt">尽管OutputStream这个基类的flush()方法是无用的，但是由于我们得到的OutputStream类型的输出对象都是这个类的子类的对象，所以，我们还是应该尽量使用flush()方法强制向输出流中物理输出数据，以避免错误。</DIV>
<DIV style="TEXT-INDENT: 24pt">&nbsp;</DIV>
<DIV><STRONG><FONT size=5>如何分批读取数据</FONT></STRONG></DIV><PRE><SPAN>&nbsp;&nbsp;&nbsp; </SPAN>我们常常使用public int <STRONG>read</STRONG>(byte[]&nbsp;b,</PRE>
<DIV style="TEXT-ALIGN: left" align=left><SPAN style="COLOR: windowtext">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;off,</SPAN></DIV>
<DIV style="TEXT-ALIGN: left" align=left><SPAN style="COLOR: windowtext">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;len)</SPAN></DIV>
<DIV><SPAN style="COLOR: windowtext">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws <A title="java.io 中的类" href="mk:@MSITStore:E:\_Java实用项目资源\_官方API参考\_JDK5中文API参考%5b沈东良shendl_s@hotmail.com%5d.chm::/java/io/IOException.html">IOException</A></SPAN></DIV>
<DIV><SPAN style="COLOR: windowtext">这个方法来读取一批数据。</SPAN></DIV>
<DIV style="TEXT-INDENT: 24pt"><SPAN style="COLOR: windowtext">查看这个方法的源代码，我们可以发现，它在读取完一批数据时，又执行了一次read()方法，由于前面论述的原因，这个方法立刻返回-1，然后这个方法退出，返回这次读取的字节数。</SPAN></DIV>
<DIV style="TEXT-INDENT: 24pt">因此，如果我们要读取一批数据，可以采用如下几种方法：</DIV>
<DIV><STRONG><FONT size=4>使用read()判断-1来读完一批数据：</FONT></STRONG></DIV>
<DIV><SPAN>&nbsp;&nbsp;&nbsp; </SPAN>代码示例：</DIV>
<DIV>Int byte;</DIV>
<DIV>While((byte=inputStream.read())!=-1 ){</DIV>
<DIV><SPAN>&nbsp;&nbsp;&nbsp; Byte</SPAN>就是返回的字节。</DIV>
<DIV>&nbsp;</DIV>
<DIV>}</DIV>
<DIV style="TEXT-INDENT: 24pt">如果读完一批数据后再一次执行read方法，将会立刻返回-1，表示这批数据已经读完。</DIV>
<DIV style="TEXT-INDENT: 24pt">&nbsp;</DIV>
<DIV><STRONG><FONT size=4>使用read(byte[] buffer)判断是否返回小于buffer.length或者-1来判断是否读完一批数据</FONT></STRONG></DIV>
<DIV style="TEXT-INDENT: 24pt">上面那样一个一个字节读取数据比较麻烦，我们通常使用一个字节数组来读取数据。</DIV>
<DIV style="TEXT-INDENT: 24pt">read(byte[] buffer)方法返回：</DIV>
<DIV>1，buffer.length，表示从输入流中读取到的数据塞满了这个字节数组。此时，可能已经读完了这批数据，也可能没有读完这批数据。</DIV>
<DIV><SPAN>&nbsp;&nbsp;&nbsp; </SPAN>如果刚好读完，那么再执行一次read()方法，就会返回-1，表示这批数据已经读完，而不是表示流已经结束。</DIV>
<DIV>2，小于buffer.length。表示读完了该批数据。并且执行了一次read()方法，返回-1，表示这批数据已经读完。</DIV>
<DIV>3，-1。这批数据已经读完了。&nbsp;不可能是表示流已经结束。因为之前就会退出while循环。</DIV>
<DIV><SPAN>&nbsp;&nbsp;&nbsp; </SPAN></DIV>
<DIV style="TEXT-INDENT: 24pt">代码示例：</DIV>
<DIV>Byte[] buffer=new byte[1024];</DIV>
<DIV>int size=buffer.length;</DIV>
<DIV>While(size!=-1 || size&gt;=buffer.length){</DIV>
<DIV style="TEXT-INDENT: 24pt">Size=inputStream.read(buffer));</DIV>
<DIV style="TEXT-INDENT: 24pt">将数据读到数组buffer中。</DIV>
<DIV style="TEXT-INDENT: 24pt">如果读到了-1，或者 读出的数据少于buffer的尺寸，表示已经读完该批数据，不再循环读取数据了！</DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV>}</DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV><STRONG><FONT size=4>读入一批数据的操作必须对应输出一批数据的操作</FONT></STRONG></DIV>
<DIV style="TEXT-INDENT: 24pt">读入一批数据的操作必须对应输出一批数据的操作。否则，读入数据的线程会一直阻塞，等待输出端输出下一批数据。</DIV>
<DIV style="TEXT-INDENT: 24pt">如果对方也需要我们提供输出数据，那么就可能会使整个流的两端的线程互相等待，死锁住。并且这个I/O流也会永远不释放，这样就会使系统的资源耗尽。</DIV>
<DIV>&nbsp;</DIV>
<DIV><STRONG><FONT size=6>后记：</FONT></STRONG></DIV>
<DIV style="TEXT-INDENT: 24pt">在前两天的工作中，我使用Socket在服务器和客户端执行操作时，出现了死锁的现象。为了找出问题的根源，我仔细查看了InputStream类和SocketInputStream类的源代码。找出了造成输入、输出流误用的原因。</DIV>
<DIV style="TEXT-INDENT: 24pt">希望这篇文章能够帮助饱受I/O输入、输出流问题困扰的Java程序员！</DIV>]]></description>
</item>
</channel>
</rss>