﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-捕风之巢-文章分类-java高级</title><link>http://www.blogjava.net/zhhp1314520/category/16149.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 02 Mar 2007 07:43:27 GMT</lastBuildDate><pubDate>Fri, 02 Mar 2007 07:43:27 GMT</pubDate><ttl>60</ttl><item><title>事务隔离EJB的使用</title><link>http://www.blogjava.net/zhhp1314520/articles/transaction_iso.html</link><dc:creator>捕风</dc:creator><author>捕风</author><pubDate>Mon, 15 Jan 2007 08:01:00 GMT</pubDate><guid>http://www.blogjava.net/zhhp1314520/articles/transaction_iso.html</guid><wfw:comment>http://www.blogjava.net/zhhp1314520/comments/93972.html</wfw:comment><comments>http://www.blogjava.net/zhhp1314520/articles/transaction_iso.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhhp1314520/comments/commentRss/93972.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhhp1314520/services/trackbacks/93972.html</trackback:ping><description><![CDATA[
		<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">J2EE</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">开发中一个非常重要的功能。</span>
				<span lang="EN-US">
						<br />
				</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'; mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold">这里，主要讲一下事务隔离</span>
				<span lang="EN-US" style="mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold">EJB</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold">的使用。</span>
				<span lang="EN-US" style="mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold">
						<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?>
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt -9pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold"> 为了能在具有事务的</span>
				<span lang="EN-US" style="mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold">action</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold">中调用不允许事务支持的外部系统</span>
				<span lang="EN-US" style="mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold">EJB</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold">，如</span>
				<span lang="EN-US" style="mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold">UMSAO</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold">，增加了事务隔离</span>
				<span lang="EN-US" style="mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold">EJB</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold">。<br /></span>
				<span lang="EN-US" style="mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold">
						<o:p>
						</o:p>
				</span>
		</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">
				<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">Facade4IsolateService.java<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />Facade4IsolateServiceEJB.java<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />Facade4IsolateServiceHome.java<br /><img id="Codehighlighter1_150_222_Open_Image" onclick="this.style.display='none'; Codehighlighter1_150_222_Open_Text.style.display='none'; Codehighlighter1_150_222_Closed_Image.style.display='inline'; Codehighlighter1_150_222_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_150_222_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_150_222_Closed_Text.style.display='none'; Codehighlighter1_150_222_Open_Image.style.display='inline'; Codehighlighter1_150_222_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span style="COLOR: #0000ff">public</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">interface</span>
				<span style="COLOR: #000000"> Facade4IsolateService </span>
				<span style="COLOR: #0000ff">extends</span>
				<span style="COLOR: #000000"> EJBLocalObject…</span>
				<span id="Codehighlighter1_150_222_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">
						<img src="http://www.blogjava.net/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_150_222_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">void</span>
						<span style="COLOR: #000000"> getReadPrivList(List permissionList, List userTypeList);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">
						<br />
						<img id="Codehighlighter1_289_370_Open_Image" onclick="this.style.display='none'; Codehighlighter1_289_370_Open_Text.style.display='none'; Codehighlighter1_289_370_Closed_Image.style.display='inline'; Codehighlighter1_289_370_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
						<img id="Codehighlighter1_289_370_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_289_370_Closed_Text.style.display='none'; Codehighlighter1_289_370_Open_Image.style.display='inline'; Codehighlighter1_289_370_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">public</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> Facade4IsolateServiceEJB </span>
				<span style="COLOR: #0000ff">extends</span>
				<span style="COLOR: #000000"> PafaSlsSessionBean </span>
				<span id="Codehighlighter1_289_370_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">
						<img src="http://www.blogjava.net/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_289_370_Open_Text">
						<span style="COLOR: #000000">{<br /><img id="Codehighlighter1_359_368_Open_Image" onclick="this.style.display='none'; Codehighlighter1_359_368_Open_Text.style.display='none'; Codehighlighter1_359_368_Closed_Image.style.display='inline'; Codehighlighter1_359_368_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_359_368_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_359_368_Closed_Text.style.display='none'; Codehighlighter1_359_368_Open_Image.style.display='inline'; Codehighlighter1_359_368_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">void</span>
						<span style="COLOR: #000000"> getReadPrivList(List permissionList, List userTypeList)</span>
						<span id="Codehighlighter1_359_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">
								<img src="http://www.blogjava.net/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_359_368_Open_Text">
								<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        … …<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">public</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">interface</span>
				<span style="COLOR: #000000"> Facade4IsolateServiceHome </span>
				<span style="COLOR: #0000ff">extends</span>
				<span style="COLOR: #000000"> EJBLocalHome<br /><img id="Codehighlighter1_436_501_Open_Image" onclick="this.style.display='none'; Codehighlighter1_436_501_Open_Text.style.display='none'; Codehighlighter1_436_501_Closed_Image.style.display='inline'; Codehighlighter1_436_501_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_436_501_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_436_501_Closed_Text.style.display='none'; Codehighlighter1_436_501_Open_Image.style.display='inline'; Codehighlighter1_436_501_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_436_501_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">
						<img src="http://www.blogjava.net/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_436_501_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000"> Facade4IsolateService create() </span>
						<span style="COLOR: #0000ff">throws</span>
						<span style="COLOR: #000000"> CreateException;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
				</span>
		</div>
		<br />
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<i style="mso-bidi-font-style: normal">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold">需要在相关文件中配置：</span>
				</i>
				<i style="mso-bidi-font-style: normal">
						<span lang="EN-US" style="mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold">
								<o:p>
								</o:p>
						</span>
				</i>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span lang="EN-US" style="mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold">biz-context.xml<br />"ejb/test/Facade4IsolateService"在weblogic-ejb-jar.xml中配置，必须同名。<br /></span>
		</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">
				<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #0000ff">&lt;</span>
				<span style="COLOR: #800000">bean </span>
				<span style="COLOR: #ff0000">id</span>
				<span style="COLOR: #0000ff">="isolateEJB"</span>
				<span style="COLOR: #ff0000">        class</span>
				<span style="COLOR: #0000ff">="com.test.app.lwc.service.remoting.access.ejb.LocalStatelessSessionProxyFactoryBean"</span>
				<span style="COLOR: #ff0000">     lazy-init</span>
				<span style="COLOR: #0000ff">="true"</span>
				<span style="COLOR: #0000ff">&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
				<span style="COLOR: #0000ff">&lt;</span>
				<span style="COLOR: #800000">property </span>
				<span style="COLOR: #ff0000">name</span>
				<span style="COLOR: #0000ff">="jndiName"</span>
				<span style="COLOR: #0000ff">&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
				<span style="COLOR: #0000ff">&lt;</span>
				<span style="COLOR: #800000">value</span>
				<span style="COLOR: #0000ff">&gt;</span>
				<span style="COLOR: #000000">ejb/test/Facade4IsolateService</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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
				<span style="COLOR: #0000ff">&lt;</span>
				<span style="COLOR: #800000">property </span>
				<span style="COLOR: #ff0000">name</span>
				<span style="COLOR: #0000ff">="businessInterface"</span>
				<span style="COLOR: #0000ff">&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                com.test.biz.service.ejb.Facade4IsolateService<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
				<span style="COLOR: #0000ff">&lt;</span>
				<span style="COLOR: #800000">property </span>
				<span style="COLOR: #ff0000">name</span>
				<span style="COLOR: #0000ff">="jndiTemplate"</span>
				<span style="COLOR: #0000ff">&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
				<span style="COLOR: #0000ff">&lt;</span>
				<span style="COLOR: #800000">ref </span>
				<span style="COLOR: #ff0000">local</span>
				<span style="COLOR: #0000ff">="jndiTemplate"</span>
				<span style="COLOR: #ff0000"> </span>
				<span style="COLOR: #0000ff">/&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
				</span>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<br />
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<i style="mso-bidi-font-style: normal">
						<span lang="EN-US" style="mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold">weblogic-ejb-jar.xml<o:p></o:p></span>
						<br />Facade4IsolateServiceEJB在ejb-jar.xml文件中设置。<br /></i>
		</p>
		<o: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">
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">weblogic-enterprise-bean</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">ejb-name</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">Facade4IsolateServiceEJB</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">ejb-name</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">stateless-session-descriptor</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">pool</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">max-beans-in-free-pool</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">500</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">max-beans-in-free-pool</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">initial-beans-in-free-pool</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">1</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">initial-beans-in-free-pool</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">pool</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">stateless-session-descriptor</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">enable-call-by-reference</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">True</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">enable-call-by-reference</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">local-jndi-name</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">ejb/test/Facade4IsolateService</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">local-jndi-name</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">weblogic-enterprise-bean</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						</span>
				</div>
				<br />
				<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
						<i style="mso-bidi-font-style: normal">
								<span lang="EN-US" style="mso-bidi-font-size: 10.5pt; mso-bidi-font-weight: bold">ejb-jar.xml<br /></span>
						</i>
				</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">
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">session </span>
						<span style="COLOR: #ff0000">id</span>
						<span style="COLOR: #0000ff">="Facade4IsolateServiceEJB"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">ejb-name</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">Facade4IsolateServiceEJB</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">ejb-name</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">local-home</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">com.test.biz.service.ejb.Facade4IsolateServiceHome</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">local-home</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">local</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">com.test.biz.service.ejb.Facade4IsolateService</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">local</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">ejb-class</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">com.test.biz.service.ejb.Facade4IsolateServiceEJB</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">ejb-class</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">session-type</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">Stateless</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">session-type</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">transaction-type</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">Container</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">transaction-type</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">env-entry</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">env-entry-name</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">ejb/BeanFactoryPath</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">env-entry-name</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">env-entry-type</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">java.lang.String</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">env-entry-type</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">env-entry-value</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">biz-context.xml</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">env-entry-value</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">env-entry</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">session</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						</span>
				</div>
				<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
						<o:p> </o:p> 设置事务的隔离属性</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">
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">container-transaction</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">method</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">ejb-name</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">Facade4IsolateServiceEJB</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">ejb-name</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">method-name</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">*</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">method-name</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />              </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">method</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />              </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">trans-attribute</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">NotSupported</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">trans-attribute</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">container-transaction</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						</span>
				</div>
		</o:p>
<img src ="http://www.blogjava.net/zhhp1314520/aggbug/93972.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhhp1314520/" target="_blank">捕风</a> 2007-01-15 16:01 <a href="http://www.blogjava.net/zhhp1314520/articles/transaction_iso.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ant结合junit进行软件自动测试</title><link>http://www.blogjava.net/zhhp1314520/articles/ant_junit.html</link><dc:creator>捕风</dc:creator><author>捕风</author><pubDate>Tue, 28 Nov 2006 09:11:00 GMT</pubDate><guid>http://www.blogjava.net/zhhp1314520/articles/ant_junit.html</guid><wfw:comment>http://www.blogjava.net/zhhp1314520/comments/84098.html</wfw:comment><comments>http://www.blogjava.net/zhhp1314520/articles/ant_junit.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhhp1314520/comments/commentRss/84098.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhhp1314520/services/trackbacks/84098.html</trackback:ping><description><![CDATA[持续集成实践三，灵感来自于Martin Fowler的“持续集成“一文。可以在www.martinfowler.com看到，国内有人翻译成了中文。 
<p>本文假设读者具备如下知识：</p><p>1、熟练ant进行java工程编译（参考本人“ant编译java工程”一文）</p><p>2、junit知识，看看www.junit.org<br /></p><p>准备：</p><p>1、www.junit.org下载junit.jar</p><p>2、xml.apache.org下载xalan.jar（ant 的 juntreport需要用到，xalan最好版本大于2.0，不然你还要下载其他的java库）<br /></p><p>把junit.jar、xalan.jar拷贝到$ANT_HOME/lib/下面，并且最好加到系统CLASSPATH（junit.jar是肯定要的，xalan.jar就不清楚了）。<br /></p><p>对自己的程序添加junit测试程序，此处请参考www.junit.org的文档，很简单的。<br /></p><p>然后在build.xml中添加如下指令,很多东西略过，所以强烈要求读者先完成本人“ant编译java工程”一文）<br /></p><p>&lt;!-- 单元测试，需要完成compile任务 --&gt;</p><p>&lt;target name="test" depends="compile"&gt;</p><p>&lt;junit printsummary="yes"&gt;</p><p>&lt;!-- 需要的classpath --&gt;</p><p>&lt;classpath refid="classpath"/&gt;</p><p>&lt;batchtest&gt;</p><p>&lt;!-- 单元测试文件为所有src目录下的*Test.java文件 --&gt;</p><p>&lt;fileset dir="${srcDir}"&gt;&lt;include name="**/*Test.java"/&gt;&lt;/fileset&gt;</p><p>&lt;!-- 生成格式为xml，也可以用plain或者brief --&gt;</p><p>&lt;!-- 为什么生成xml，是为了下一步做report用 --&gt;</p><p>&lt;formatter type="xml"/&gt;</p><p>&lt;/batchtest&gt;</p><p>&lt;/junit&gt;</p><p>&lt;!-- 对xml文件生成相应的html文件在reports目录下 --&gt;</p><p>&lt;!-- 如果指定于web可访问的目录，就可以使整个项目组看到单元测试情况 --&gt;</p><p>&lt;junitreport todir="reports"&gt;</p><p>&lt;fileset dir="."&gt;</p><p>&lt;include name="TEST-*.xml"/&gt;</p><p>&lt;/fileset&gt;</p><p>&lt;!-- 带有框架，可以用noframes选不带框架 --&gt;</p><p>&lt;report format="frames" todir="reports/html"/&gt;</p><p>&lt;/junitreport&gt;</p><p>&lt;/target&gt;<br /></p><p>现在运行ant test，看看reports/下面是不是有了生成的单元测试结果的文件了？</p><p>如果有问题可以用ant -debug test看看问题出在哪里？</p><p>另外更改源程序，让程序通过测试和通不过测试看看生成的结果如何？</p><img src ="http://www.blogjava.net/zhhp1314520/aggbug/84098.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhhp1314520/" target="_blank">捕风</a> 2006-11-28 17:11 <a href="http://www.blogjava.net/zhhp1314520/articles/ant_junit.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Ant运行本地程序(转) </title><link>http://www.blogjava.net/zhhp1314520/articles/ant123.html</link><dc:creator>捕风</dc:creator><author>捕风</author><pubDate>Tue, 28 Nov 2006 09:09:00 GMT</pubDate><guid>http://www.blogjava.net/zhhp1314520/articles/ant123.html</guid><wfw:comment>http://www.blogjava.net/zhhp1314520/comments/84097.html</wfw:comment><comments>http://www.blogjava.net/zhhp1314520/articles/ant123.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhhp1314520/comments/commentRss/84097.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhhp1314520/services/trackbacks/84097.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: .								使用Ant运行windows的批处理文件																																																																       																				要在																								Ant			...&nbsp;&nbsp;<a href='http://www.blogjava.net/zhhp1314520/articles/ant123.html'>阅读全文</a><img src ="http://www.blogjava.net/zhhp1314520/aggbug/84097.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhhp1314520/" target="_blank">捕风</a> 2006-11-28 17:09 <a href="http://www.blogjava.net/zhhp1314520/articles/ant123.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ant+Tomcat自动部署</title><link>http://www.blogjava.net/zhhp1314520/articles/ant_tomcat.html</link><dc:creator>捕风</dc:creator><author>捕风</author><pubDate>Thu, 23 Nov 2006 00:59:00 GMT</pubDate><guid>http://www.blogjava.net/zhhp1314520/articles/ant_tomcat.html</guid><wfw:comment>http://www.blogjava.net/zhhp1314520/comments/82934.html</wfw:comment><comments>http://www.blogjava.net/zhhp1314520/articles/ant_tomcat.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhhp1314520/comments/commentRss/82934.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhhp1314520/services/trackbacks/82934.html</trackback:ping><description><![CDATA[今天研究对象是Ant，用于对msms系统进行Tomcat的自动部署。<br /><br />遇到一个怪问题，百思不得其解：<br />通过ant depoly可以把msms.war部署到tomcat上。当然，要求这时候webapps下面没有msms目录。<br />看tomcat的纪录，加载msms.war正常，网页也可以打开。<br /><br />通过ant undeploy，可以把msms卸载。Tomcat显示：<br />Undeploying context [/msms]<br />正常卸载了。问题是，去看webapps目录下面，居然有一个msms目录的残骸，里面保留的目录是<br />WEB-INF\lib<br />有以下几个文件残留着：<br />commons-digester.jar<br />commons-validator.jar<br />struts.jar<br /><br />这时候msms目录也无法手工删除，必须停掉tomcat后才能删除。<br /><br />我装的tomcat是5.5。不知道是否还有人遇到过这种情况，我反正是晕了。<br /><br />build.properties文件如下：<br />tomcat.dir=C:/ApacheGroup/Tomcat5.5<br />tomcat.webapps=C:/ApacheGroup/Tomcat5.5/webapps<br />tomcat.manager.url=http://localhost:8080/manager<br />tomcat.manager.username=admin<br />tomcat.manager.password=xxxxxxxx<br /><br />build.xml文件如下：<br />&lt;?xml version="1.0"?&gt;<br />&lt;project name="msms" default="compile" basedir="."&gt;<br />    &lt;!-- Ant Tomcat Task Definition --&gt;<br />    &lt;taskdef name="deploy" classname="org.apache.catalina.ant.DeployTask"&gt;<br />        &lt;classpath&gt;<br />            &lt;path location="${tomcat.dir}/server/lib/catalina-ant.jar" /&gt;<br />        &lt;/classpath&gt;<br />    &lt;/taskdef&gt;<br /><br />    &lt;taskdef name="undeploy" classname="org.apache.catalina.ant.UndeployTask"&gt;<br />        &lt;classpath&gt;<br />            &lt;path location="${tomcat.dir}/server/lib/catalina-ant.jar" /&gt;<br />        &lt;/classpath&gt;<br />    &lt;/taskdef&gt;<br /><br />    &lt;taskdef name="install" classname="org.apache.catalina.ant.InstallTask"&gt;<br />        &lt;classpath&gt;<br />            &lt;path location="${tomcat.dir}/server/lib/catalina-ant.jar" /&gt;<br />        &lt;/classpath&gt;<br />    &lt;/taskdef&gt;<br /><br />    &lt;taskdef name="reload" classname="org.apache.catalina.ant.ReloadTask"&gt;<br />        &lt;classpath&gt;<br />            &lt;path location="${tomcat.dir}/server/lib/catalina-ant.jar" /&gt;<br />        &lt;/classpath&gt;<br />    &lt;/taskdef&gt;<br /><br />    &lt;taskdef name="list" classname="org.apache.catalina.ant.ListTask"&gt;<br />        &lt;classpath&gt;<br />            &lt;path location="${tomcat.dir}/server/lib/catalina-ant.jar" /&gt;<br />        &lt;/classpath&gt;<br />    &lt;/taskdef&gt;<br /><br />    &lt;taskdef name="start" classname="org.apache.catalina.ant.StartTask"&gt;<br />        &lt;classpath&gt;<br />            &lt;path location="${tomcat.dir}/server/lib/catalina-ant.jar" /&gt;<br />        &lt;/classpath&gt;<br />    &lt;/taskdef&gt;<br /><br />    &lt;taskdef name="stop" classname="org.apache.catalina.ant.StopTask"&gt;<br />        &lt;classpath&gt;<br />            &lt;path location="${tomcat.dir}/server/lib/catalina-ant.jar" /&gt;<br />        &lt;/classpath&gt;<br />    &lt;/taskdef&gt;<br /><br />    &lt;property name="build" value="build" /&gt;<br />    &lt;property name="dist" value="dist" /&gt;<br />    &lt;property name="src" value="src/java" /&gt;<br />    &lt;property name="test" value="src/test" /&gt;<br />    &lt;property name="war-config" value="src/config" /&gt;<br />    &lt;property name="report" value="report" /&gt;<br />    &lt;property name="lib" value="lib" /&gt;<br />    &lt;property name="web" value="web" /&gt;<br />    &lt;property name="meta" value="meta" /&gt;<br />    &lt;property name="context-path" value="${ant.project.name}" /&gt;<br />    &lt;property file="build.properties" /&gt;<br /><br />    &lt;path id="build.classpath"&gt;<br />        &lt;fileset file="${lib}/*.jar" /&gt;<br />        &lt;fileset dir="${tomcat.dir}/common/lib"&gt;<br />            &lt;include name="*.jar" /&gt;<br />        &lt;/fileset&gt;<br />        &lt;fileset dir="${tomcat.dir}/common/endorsed"&gt;<br />            &lt;include name="*.jar" /&gt;<br />        &lt;/fileset&gt;<br />        &lt;pathelement path="${build}" /&gt;<br />    &lt;/path&gt;<br /><br />    &lt;!-- Hibernate Tool Task Definition --&gt;<br />    &lt;taskdef name="hibernatetool" classname="org.hibernate.tool.ant.HibernateToolTask" classpathref="build.classpath" /&gt;<br />    <br />    &lt;target name="clean"&gt;<br />        &lt;echo message="Cleaning up the build and dist directories" /&gt;<br />        &lt;delete dir="${build}" /&gt;<br />        &lt;mkdir dir="${build}" /&gt;<br />        &lt;delete dir="${dist}" /&gt;<br />        &lt;mkdir dir="${dist}" /&gt;<br />    &lt;/target&gt;<br /><br />    &lt;target name="copy-resources"&gt;<br />        &lt;copy todir="${build}"&gt;<br />            &lt;fileset dir="${src}"&gt;<br />                &lt;exclude name="**/*.java" /&gt;<br />                &lt;exclude name="**/*.hbm.xml" /&gt;<br />            &lt;/fileset&gt;<br />        &lt;/copy&gt;<br />    &lt;/target&gt;<br /><br />    &lt;target name="compile" depends="copy-resources"&gt;<br />        &lt;javac destdir="${build}" srcdir="${src}:${test}"&gt;<br />            &lt;classpath refid="build.classpath" /&gt;<br />        &lt;/javac&gt;<br />    &lt;/target&gt;<br /><br />    &lt;target name="initdb" depends="compile"&gt;<br />        &lt;hibernatetool destdir="${build}"&gt;<br />            &lt;classpath&gt;<br />                &lt;path location="${build}" /&gt;<br />            &lt;/classpath&gt;<br />            &lt;annotationconfiguration configurationfile="src/java/hibernate.cfg.xml" /&gt;<br /><br />            &lt;hbm2ddl create="true" /&gt;<br />        &lt;/hibernatetool&gt;<br />    &lt;/target&gt;<br /><br />    &lt;target name="run" depends="compile"&gt;<br />        &lt;java fork="true" classname="cn.ac.rcpa.msms.tools.ProjectManager" classpathref="build.classpath"&gt;<br />            &lt;classpath path="${build}" /&gt;<br />            &lt;arg value="${action}" /&gt;<br />            &lt;arg value="${project}" /&gt;<br />            &lt;arg value="${description}" /&gt;<br />        &lt;/java&gt;<br />    &lt;/target&gt;<br /><br />    &lt;target name="test" depends="compile" description="run junit test"&gt;<br />        &lt;delete dir="${report}" /&gt;<br />        &lt;mkdir dir="${report}" /&gt;<br />        &lt;junit dir="." fork="true" printsummary="on" haltonfailure="false" failureproperty="tests.failed" showoutput="true"&gt;<br />            &lt;classpath refid="build.classpath" /&gt;<br />            &lt;formatter type="brief" /&gt;<br />            &lt;batchtest todir="${report}"&gt;<br />                &lt;fileset dir="${build}"&gt;<br />                    &lt;include name="**/*Test.*" /&gt;<br />                    &lt;include name="**/Test*.*" /&gt;<br />                &lt;/fileset&gt;<br />            &lt;/batchtest&gt;<br />        &lt;/junit&gt;<br />        &lt;fail if="tests.failed"&gt;<br />      ***********************************************************<br />      **** One or more tests failed! Check the output ... ****<br />      ***********************************************************<br />    &lt;/fail&gt;<br />    &lt;/target&gt;<br /><br />    &lt;target name="create-war" depends="clean, compile" description="build release war"&gt;<br />        &lt;echo message="creation the WAR file...${context-path}.war" /&gt;<br />        &lt;war destfile="${dist}/${context-path}.war" webxml="${meta}/web.xml"&gt;<br />            &lt;classes dir="${build}"&gt;<br />                &lt;exclude name="**/*Test.*" /&gt;<br />                &lt;exclude name="**/Test*.*" /&gt;<br />                &lt;exclude name="hibernate.cfg.xml" /&gt;<br />            &lt;/classes&gt;<br />            &lt;lib dir="${lib}" /&gt;<br />            &lt;fileset dir="${web}" /&gt;<br />            &lt;zipfileset dir="${war-config}" prefix="WEB-INF/classes" /&gt;<br />        &lt;/war&gt;<br />        &lt;!--        &lt;scp file="${dist}/${context-path}.war" todir="root:${password}@172.16.1.20:/usr/local/tomcat/webapps" trust="true" /&gt; --&gt;<br />    &lt;/target&gt;<br /><br />    &lt;target name="deploy" description="Install application in Tomcat"&gt;<br />        &lt;deploy url="${tomcat.manager.url}" username="${tomcat.manager.username}" password="${tomcat.manager.password}" path="/${context-path}" localWar="file:${dist}/${context-path}.war" /&gt;<br />    &lt;/target&gt;<br /><br />    &lt;target name="undeploy" description="Remove application in Tomcat" if="already.deployed"&gt;<br />        &lt;undeploy url="${tomcat.manager.url}" username="${tomcat.manager.username}" password="${tomcat.manager.password}" path="/${context-path}" /&gt;<br />    &lt;/target&gt;<br /><br />    &lt;target name="reload" description="Reload application in Tomcat"&gt;<br />        &lt;reload url="${tomcat.manager.url}" username="${tomcat.manager.username}" password="${tomcat.manager.password}" path="/${context-path}" /&gt;<br />    &lt;/target&gt;<br /><br />    &lt;target name="start" description="Start Tomcat application"&gt;<br />        &lt;start url="${tomcat.manager.url}" username="${tomcat.manager.username}" password="${tomcat.manager.password}" path="/${context-path}" /&gt;<br />    &lt;/target&gt;<br /><br />    &lt;target name="stop" description="Stop Tomcat application"&gt;<br />        &lt;stop url="${tomcat.manager.url}" username="${tomcat.manager.username}" password="${tomcat.manager.password}" path="/${context-path}" /&gt;<br />    &lt;/target&gt;<br /><br />    &lt;target name="list" description="List Tomcat applications"&gt;<br />        &lt;list url="${tomcat.manager.url}" username="${tomcat.manager.username}" password="${tomcat.manager.password}" /&gt;<br />    &lt;/target&gt;<br /><br />    &lt;target name="deploy-application" description="Compile the web application..."&gt;<br />        &lt;echo message="Undeploying the application only if it's deployed..." /&gt;<br />        &lt;available file="${tomcat.webapps}/${context-path}.war" property="already.deployed" /&gt;<br />        &lt;antcall target="undeploy" /&gt;<br />        &lt;antcall target="create-war" /&gt;<br />        &lt;antcall target="deploy" /&gt;<br />    &lt;/target&gt;<br />&lt;/project&gt;<br /><br /><br />只有Windows上才会有的问题， <br />创建META-INF目录， 在目录里新建context.xml，加入如下内容 <br /><br />&lt;?xml version="1.0" encoding="UTF-8"?&gt; <br />&lt;Context reloadable="true" antiResourceLocking="true"&gt; <br />&lt;/Context&gt; <br /><br /><div class="postText">昨天的错误至今无法修正，即使重装了Tomcat也不行。<br /><br />不过，deploy到两台linux服务器上倒都成功了。<br />    &lt;taskdef name="deploy" classname="org.apache.catalina.ant.DeployTask"&gt;<br />        &lt;classpath&gt;<br />            &lt;path location="${tomcat.dir}/server/lib/catalina-ant.jar" /&gt;<br />        &lt;/classpath&gt;<br />    &lt;/taskdef&gt;<br /><br />    &lt;taskdef name="list" classname="org.apache.catalina.ant.ListTask"&gt;<br />        &lt;classpath&gt;<br />            &lt;path location="${tomcat.dir}/server/lib/catalina-ant.jar" /&gt;<br />        &lt;/classpath&gt;<br />    &lt;/taskdef&gt;<br /><br />    &lt;target name="deploy-web" description="Install application in Local Tomcat"&gt;<br />        &lt;echo message="deploying to web ..." /&gt;<br />        &lt;deploy url="http://172.16.1.20:8080/manager" username="${tomcat.manager.username}" password="${tomcat.manager.password}" path="/${context-path}" war="file:${dist}/${context-path}.war" update="true" /&gt;<br />    &lt;/target&gt;<br /><br />    &lt;target name="list-web"&gt;<br />        &lt;echo message="list web tomcat ..." /&gt;<br />        &lt;list url="http://172.16.1.20:8080/manager" username="${tomcat.manager.username}" password="${tomcat.manager.password}" /&gt;<br />    &lt;/target&gt;<br /><br /><br />这里跟昨天的代码有一点不一样：<br />1、localWar改成了war。<br />原来更新远程服务器的时候，总是显示更新成功，但是到webapps目录下总是没有相应的war文件，通过调用<br />ant list-web<br />发现，有一个context-path是dist/msms，而且是stop状态。哦，原来localWar的意思不是指开发的机器的local path，而是指把这个war被写到服务器的什么地方。改成war就正常了。<br /><br />2、不需要判断是否已经deploy进而调用undeploy了，直接通过update="true"更新就可以了。<br /></div><img src ="http://www.blogjava.net/zhhp1314520/aggbug/82934.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhhp1314520/" target="_blank">捕风</a> 2006-11-23 08:59 <a href="http://www.blogjava.net/zhhp1314520/articles/ant_tomcat.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ant基本使用指南</title><link>http://www.blogjava.net/zhhp1314520/articles/ant_all.html</link><dc:creator>捕风</dc:creator><author>捕风</author><pubDate>Thu, 23 Nov 2006 00:56:00 GMT</pubDate><guid>http://www.blogjava.net/zhhp1314520/articles/ant_all.html</guid><wfw:comment>http://www.blogjava.net/zhhp1314520/comments/82933.html</wfw:comment><comments>http://www.blogjava.net/zhhp1314520/articles/ant_all.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhhp1314520/comments/commentRss/82933.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhhp1314520/services/trackbacks/82933.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1 Ant是什么？		Apache Ant 是一个基于 Java的生成工具。		生成工具在软件开发中用来将源代码和其他输入文件转换为可执行文件的形式（也有可能转换为可安装的产品映像形式）。随着应用程序的生成过程变得更加复杂，确保在每次生成期间都使用精确相同的生成步骤，同时实现尽可能多的自动化，以便及时产生一致的生成版本		2下载、安装Ant 		安装Ant		下载.zip文件，...&nbsp;&nbsp;<a href='http://www.blogjava.net/zhhp1314520/articles/ant_all.html'>阅读全文</a><img src ="http://www.blogjava.net/zhhp1314520/aggbug/82933.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhhp1314520/" target="_blank">捕风</a> 2006-11-23 08:56 <a href="http://www.blogjava.net/zhhp1314520/articles/ant_all.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>了解AOP(一)</title><link>http://www.blogjava.net/zhhp1314520/articles/aop1.html</link><dc:creator>捕风</dc:creator><author>捕风</author><pubDate>Wed, 25 Oct 2006 02:06:00 GMT</pubDate><guid>http://www.blogjava.net/zhhp1314520/articles/aop1.html</guid><wfw:comment>http://www.blogjava.net/zhhp1314520/comments/77133.html</wfw:comment><comments>http://www.blogjava.net/zhhp1314520/articles/aop1.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhhp1314520/comments/commentRss/77133.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhhp1314520/services/trackbacks/77133.html</trackback:ping><description><![CDATA[
		<span class="postbody">原文:http://www.javaworld.com/javaworld/jw-01-2002/jw-0118-aspect.html <br /><br /><span style="COLOR: blue"><span style="FONT-WEIGHT: bold">了解AOP（第一部分）--用面向方面的编程方式分离软件关注点</span></span><br /><br /><span style="FONT-WEIGHT: bold">摘要</span><br /><br />多数软件系统都包含几个跨越多个模块的关注点。用面向对象技术实现这些关注点会使系统难以实现，难以理解，并且不利于软件的演进。新的AOP（面向角度的编程方法）利用模块化来分离软件中横切多模块的关注点。使用AOP，你可以建立容易设计，易于理解和维护的系统。此外，AOP可以带来更高的产出，更好的质量，更好的扩展性，这篇文章是这个系列里三篇文章中的第一章，介绍AOP的概念和它所解决的问题。 <br /><br /><span style="FONT-STYLE: italic">作者：Ramnivas Laddad </span><br /><br />一个关注点就是一个特定的目的、一块我们感兴趣的的区域。从技术的角度来说，一个典型的软件系统包含一些核心的关注点和系统级的关注点。举个例子来说，一个信用卡处理系统的核心关注点是借贷/存入处理，而系统级的关注点则是日志，事务完整性，授权，安全性及性能问题等，许多关注点——我们叫它横切关注点——会在多个模块中出现，使用现有的编程方法，横切关注点会横越多个模块，结果是使系统难以设计、理解、实现和演进。 <br /><br />AOP（面向角度的编程方式）能够比上述方法更好的分离系统关注点，从而提供模块化的横切关注点。 <br /><br />在这篇文章里——关于AOP的三篇文章的第一章，我首先会 解释横切关注点在一些即使是中等复杂度的软件系统中也会引起的问题，接着我会介绍AOP的核心概念并演示AOP是怎样解决横切关注点问题的。 <br /><br /><span style="FONT-WEIGHT: bold">软件编程方法的演进</span><br /><br />在计算机科学的早期阶段，开发人员使用直接的机器级代码来编程，不幸的是，程序员得花费更多时间来考虑一种特定机器的指令集而不是手中需要解决的问题本身。慢慢的我们转而使用允许对底层机器做某种抽象的高级语言。然后是结构化语言，我们可以把问题分解成一些必要的过程来完成任务。但是，随着复杂程度的增加，我们又需要更适合的技术。面向对象的编程方式（OOP）使我们可以把系统看作是一批相互合作的对象。类允许我们把实现细节隐藏在接口下。多态性为相关概念提供公共的行为和接口，并允许特定的组件在无需访问基础实现的前提下改变特定行为。 <br /><br />编程方法和语言决定了我们和计算机交流的方式。每一种新的方法学都提出一种新的分解问题的方法：机器码、伪代码、过程和类等。每种新的方法学都使得从系统需求到编程概念的映射更加自然。编程方法学的发展让我们可以建立更加复杂的系统，这句话反过来说也对，我们能够建立更加复杂的系统是因为这些技术允许我们处理这种复杂度。 <br /><br />现在，大多数软件项目都选择OOP的编程方式。确实，OOP已经表明了它处理一般行为的能力，但是，我们一会儿会看到（或许你已经感觉到了）， OOP不能很好的处理横越多个——经常是不相关的——模块的行为，相比之下，AOP填补了这个空白，它很可能会是编程方法学发展的下一个里程碑。 <br /><br /><span style="FONT-WEIGHT: bold">把系统看作一批关注点</span><br /><br />我们可以把一个复杂的系统看作是由多个关注点来组合实现的，一个典型的系统可能会包括几个方面的关注点，如业务逻辑，性能，数据存储，日志和调试信息，授权，安全，线程，错误检查等，还有开发过程中的关注点，如易懂，易维护，易追查，易扩展等，图一演示了由不同模块实现的一批关注点组成了一个系统。 <br /><br /><img src="http://www.javaworld.com/javaworld/jw-01-2002/images/jw-0118-aspectf1.gif" border="0" /><br /><br />图 1. 把模块作为一批关注点来实现 <br /><br />　 <br />图二把需求比作一束穿过三棱镜的光，我们让需求之光通过关注点鉴别三棱镜，就会区别出每个关注点，同样的方法也适用于开发阶段的关注点。 <br /><br /><img src="http://www.javaworld.com/javaworld/jw-01-2002/images/jw-0118-aspectf2.gif" border="0" /><br />图 2. 关注点分解: 三棱镜法则 <br /><br />开发人员建立一个系统以满足多个需求，我们可以大致的把这些需求分类为核心模块级需求和系统级需求。很多系统级需求一般来说是相互独立的，但它们一般都会横切许多核心模块。举个例子来说，一个典型的企业应用包含许多横切关注点，如验证，日志，资源池，系统管理，性能及存储管理等，每一个关注点都牵涉到几个子系统，如存储管理关注点会影响到所有的有状态业务对象。 <br /><br />让我们来看一个简单，但是具体的例子，考虑一个封装了业务逻辑的类的实现框架： <br /><br /></span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>代码:</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">public class SomeBusinessClass extends OtherBusinessClass { <br />    // 核心数据成员 <br /><br />    // 其它数据成员：日志流，保证数据完整性的标志位等 <br /><br />    // 重载基类的方法 <br /><br />    public void performSomeOperation(OperationInformation info) { <br />        // 安全性验证 <br /><br />        // 检查传入数据是否满足协议 <br /><br />        // 锁定对象以保证当其他线程访问时的数据完整性 <br /><br />        // 检查缓存中是否为最新信息 <br /><br />        // 纪录操作开始执行时间 <br /><br />        // 执行核心操作 <br /><br />        // 纪录操作完成时间 <br /><br />        // 给对象解锁 <br />    } <br /><br />    // 一些类似操作 <br /><br />    public void save(PersitanceStorage ps) { <br />    } <br /><br />    public void load(PersitanceStorage ps) { <br />    } <br />}</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />在上面的代码中，我们注意到三个问题，首先，其它数据成员不是这个类的核心关注点，第二，performSomeOperation()的实现做了许多核心操作之外的事，它要处理日志，验证，线程安全，协议验证和缓存管理等一些外围操作，而且这些外围操作同样也会应用于其他类，第三，save() 和load()执行的持久化操作是否构成这个类的核心清楚的。 <br /><br /><span style="FONT-WEIGHT: bold">横切关注点的问题</span><br /><br />虽然横切关注点会跨越多个模块，但当前的技术倾向于使用一维的方法学来处理这种需求，把对应需求的实现强行限制在一维的空间里。这个一维空间就是核心模块级实现，其他需求的实现被嵌入在这个占统治地位的空间，换句话说，需求空间是一个n维空间，而实现空间是一维空间，这种不匹配导致了糟糕的需求到实现的映射 <br /><br /><span style="FONT-WEIGHT: bold">表现</span><br />用当前方法学实现横切关注点是不好的，它会带来一些问题，我们可以大致把这些问题分为两类: <br /><ul><br /><li>代码混乱：软件系统中的模块可能要同时兼顾几个方面的需要。举例来说，开发者经常要同时考虑业务逻辑，性能，同步，日志和安全等问题，兼顾各方面的需要导致相应关注点的实现元素同时出现，引起代码混乱。 <br /></li><li>代码分散：由于横切关注点，本来就涉及到多个模块，相关实现也就得遍布在这些模块里，如在一个使用了数据库的系统里，性能问题就会影响所有访问数据库的模块。这导致代码分散在各处 <br /></li></ul><br /><span style="FONT-WEIGHT: bold">结果</span><br /><br />混乱和分散的代码会在多个方面影响系统的设计和开发： <br /><ul><br /><li>可读性差：同时实现几个关注点模糊了不同关注点的实现，使得关注点与其实现之间的对应关系不明显。 <br /></li><li>低产出：同时实现几个关注点把开发人员的注意力从主要的转移到外围关注点，导致产能降低。 <br /></li><li>低代码重用率：由于这种情况下，一个模块实现多个关注点，其他需要类似功能的系统不能马上使用该模块，进一步降低了产能。 <br /></li><li>代码质量差：混乱的代码掩盖了代码中隐藏的问题。而且，由于同时要处理多个关注点，应该特别注意的关注点得不到应有的关注 <br /></li><li>难以扩展：狭窄的视角和有限的资源总是产生仅注意当前关注点的设计。新的需求导致从新实现。由于实现不是模块化的，就是说实现牵涉到多个模块，为了新需求修改子系统可能会带来数据的不一致，而且还需相当规模测试来保证这些修改不会带来bug。 <br /><br /><span style="FONT-WEIGHT: bold">当前解决方法</span><br /><br />由于多数系统中都包含横切关注点，自然的已经形成了一些技术来模块化横切关注点的实现，这些技术包括：混入类，设计模式和面向特定问题域的解决方式 <br /><br />使用混入类，你可以推迟关注点的最终实现。基本类包含一个混入类的实例，允许系统的其他部分设置这个实例，举个例子来说，实现业务逻辑的类包含一个混入的logger，系统的其他部分可以设置这个logger已得到合适的日志类型，比如logger可能被设置为使用文件系统或是消息中间件.在这种方式下，虽然日志的具体实现被推迟啦，基本类还是得包含在所有的写日志的点调用日志操作和控制日志信息的代码。 <br /><br />行为型设计模式，如Visitor和Template模式，也允许你推迟具体实现。但是也就像混入类一样，操作的控制——调用visitor或template的逻辑——仍然留给了基本类 <br /><br />面向特定问题域的解决方式，如框架和应用服务器，允许开发者用更模块化的方式处理某些横切关注点。比如EJB(Enterprise JavaBean，企业级javabean)架构,可以处理安全，系统管理，性能和容器管理的持久化（container-managed persistence）等横切关注点。Bean的开发者仅需关心业务逻辑，而部署者仅需关心部署问题，如bean与数据库的映射。但是大多数情况下，开发者还是要了解存储结构。这种方式下，你用基于XML的映射关系描述器来实现于数据持久化相关的横切关注点。 <br /><br />面向特定问题域的解决方式提供了解决特定问题的专门机制，它的缺点是对于每一种这样的解决方式开发人员都必须重新学习，另外，由于这种方式是特定问题域相关的，属于特定问题域之外的横切关注点需要特殊的对待 <br /><br /><span style="FONT-WEIGHT: bold">设计师的两难局面</span><br /><br />好的系统设计师不仅会考虑当前需求，还会考虑到可能会有的需求以避免到处打补丁。这样就存在一个问题，预知将来是很困难的，如果你漏过了将来可能会有的横切关注点的需求，你将会需要修改或甚至是重新实现系统的许多部分；从另一个角度来说，太过于关注不一定需要的需求会导致过分设计（overdesigned）的，难以理解的，臃肿的系统。所以系统设计师处在这么一个两难局面中：怎么设计算是过分设计？应该宁可设计不足还是宁可过分设计？ <br /><br />举个例子来说，设计师是否应该在系统中包含现在并不需要的日志机制？如果是的话，哪里是应该写日志的点？日志应该记录那些信息？相似的例子还有关于性能的优化问题，我们很少能预先知道瓶颈的所在。常用的方法是建立系统，profile它，然后翻新系统以提高性能，这种方式可能会依照 profiling修改系统的很多部分，此外，随着时间的流逝，由于使用方式的变化，可能还会产生新的瓶颈，类库设计师的任务更困难，因为他很难设想出所有对类库的使用方式。 <br /><br />总而言之，设计师很难顾及到系统可能需要处理的所有关注点。即使是在已经知道了需求的前提下，某些建立系统时需要的细节也可能不能全部得到。整体设计就面临着设计不足/过分设计的两难局面。 <br /><br /><span style="FONT-WEIGHT: bold">AOP基础</span><br /><br />到目前为止的讨论说明模块化横切关注点是有好处的。研究人员已经尝试了多种方法来实现这个任务，这些方法有一个共同的主题：分离关注点。AOP是这些方法中的一种，它的目的是清晰的分离关注点来解决以上提到的问题。 <br /><br />AOP，从其本质上讲，使你可以用一种松散耦合的方式来实现独立的关注点，然后，组合这些实现来建立最终系统。用它所建立的系统是使用松散耦合的，模块化实现的横切关注点来搭建的。与之对照，用OOP建立的系统则是用松散耦合的模块化实现的一般关注点来实现的。在AOP终，这些模块化单元叫方面（aspect），而在OOP中，这些一般关注点的实现单元叫做类。 <br /><br />AOP包括三个清晰的开发步骤： <br /><ul><br /><li>方面分解：分解需求提取出横切关注点和一般关注点。在这一步里，你把核心模块级关注点和系统级的横切关注点分离开来。就前面所提到的信用卡例子来说，你可以分解出三个关注点：核心的信用卡处理，日志和验证。 <br /></li><li>关注点实现：各自独立的实现这些关注点，还用上面信用卡的例子，你要实现信用卡处理单元，日志单元和验证单元。 <br /></li><li>方面的重新组合：在这一步里，方面集成器通过创建一个模块单元——方面来指定重组的规则。重组过程——也叫织入或结合——则使用这些信息来构建最终系统，还拿信用卡的那个例子，你可以指定（用某种AOP的实现所提供的语言）每个操作的开始和结束需要纪录，并且每个操作在涉及到业务逻辑之前必须通过验证。 <br /></li></ul><br /><br /><img src="http://www.javaworld.com/javaworld/jw-01-2002/images/jw-0118-aspectf3.gif" border="0" /><br /><br />图 3. AOP 开发的步骤 <br /><br />AOP与OOP的不同关键在于它处理横切关注点的方式，在AOP中，每个关注点的实现都不知道其它关注点是否会‘关注’它，如信用卡处理模块并不知道其它的关注点实现正在为它做日志和验证操作。它展示了一个从OOP转化来的强大的开发范型。 <br /><br />注意：一个AOP实现可以借助其它编程范型作为它的基础，从而原封不动的保留其基础范型的优点。例如，AOP可以选择OOP作为它的基础范型，从而把OOP善于处理一般关注点的好处直接带过来。用这样一种实现，独立的一般关注点可以使用OOP技术。这就像过程型语言是许多OOP语言的基础一样。 <br /><br /><span style="FONT-WEIGHT: bold">织入举例</span><br />织入器——一个处理器——组装一个个关注点（这个过程叫做织入）。就是说，它依照提供给它的规则把不同的执行逻辑段混编起来。 <br /><br />为了说明代码织入，让我们回到信用卡处理的例子，为了简单起见，我们只考虑两个操作：存入和取出，并且我们假设已经有了一个合适的logger. <br /><br />来看一下下面的信用卡模块： <br /><table cellspacing="1" cellpadding="3" width="90%" align="center" border="0"><tbody><tr><td><span class="genmed"><b>代码:</b></span></td></tr><tr><td class="code"><br />public class CreditCardProcessor { <br />    public void debit(CreditCard card, Currency amount) <br />       throws InvalidCardException, NotEnoughAmountException, <br />              CardExpiredException { <br />        // 取出逻辑 <br />    } <br />    <br />    public void credit(CreditCard card, Currency amount) <br />        throws InvalidCardException { <br />        // 存入逻辑 <br /><br />    } <br />}</td></tr></tbody></table><span class="postbody"><br /><br />下面是日志接口 <br /></span><table cellspacing="1" cellpadding="3" width="90%" align="center" border="0"><tbody><tr><td><span class="genmed"><b>代码:</b></span></td></tr><tr><td class="code"><br />public interface Logger { <br />    public void log(String message); <br />}</td></tr></tbody></table><span class="postbody"><br /><br />所需组合需要如下织入规则，这里用自然语言来表达（本文的后面会提供这些织入规则的程序版本）： <br />[list=a] <br /></span></li><li>纪录每个公共操作的开始 <br /></li><li>纪录每个公共操作的结束 <br /></li><li>纪录所有公共方法抛出的异常 <br /></li></ul><br /><br />织入器就会使用这些织入规则和关注点实现来产生与如下代码有相同效果的代码： <br /><br /></span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>代码:</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">public class CreditCardProcessorWithLogging { <br />    Logger _logger; <br /><br />    public void debit(CreditCard card, Money amount) <br />        throws InvalidCardException, NotEnoughAmountException, <br />               CardExpiredException { <br />        _logger.log("Starting CreditCardProcessor.credit(CreditCard, <br />Money) " <br />                    + "Card: " + card + " Amount: " + amount); <br />        // 取出逻辑 <br />        _logger.log("Completing CreditCardProcessor.credit(CreditCard, <br />Money) " <br />                    + "Card: " + card + " Amount: " + amount); <br />    } <br />    <br />    public void credit(CreditCard card, Money amount) <br />        throws InvalidCardException { <br />        System.out.println("Debiting"); <br />        _logger.log("Starting CreditCardProcessor.debit(CreditCard, <br />Money) " <br />                    + "Card: " + card + " Amount: " + amount); <br />        // 存入逻辑 <br />        _logger.log("Completing CreditCardProcessor.credit(CreditCard, <br />Money) " <br />                    + "Card: " + card + " Amount: " + amount); <br /><br />    } <br />}</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<span style="FONT-WEIGHT: bold">AOP语言剖析</span>
				<br />
				<br />就像其他编程范型的实现一样，AOP的实现有两部分组成：语言规范和实现。语言规范描述了语言的基础单元和语法。语言实现则按照语言规范来验证代码的正确性并把代码转成目标机器的可执行形式。这一节，我来解释一下AOP组成部分。 <br /><br /><span style="FONT-WEIGHT: bold">AOP语言规范</span><br />从抽象的角度看来，一种AOP语言要说明下面两个方面： <br /><ul><br /><li>关注点的实现：把每个需求映射为代码，然后，编译器把它翻译成可执行代码，由于关注点的实现以指定过程的形式出现，你可以使用传统语言如C，C++，Java等。 <br /></li><li>织入规则规范：怎样把独立实现的关注点组合起来形成最终系统呢？为了这个目的，需要建立一种语言来指定组合不同的实现单元以形成最终系统的规则，这种指定织入规则的语言可以是实现语言的扩展，也可以是一种完全不同的语言。 <br /></li></ul><br /><br /><span style="FONT-WEIGHT: bold">AOP语言的实现</span><br /><br />AOP的编译器执行两步操作： <br /><ol type="a"><br /><li>组装关注点。 <br /></li><li>把组装结果转成可执行代码 <br /></li></ol><br />AOP实现可以用多种方式实现织入，包括源码到源码的转换。它预处理每个方面的源码产生织入过的源码，然后把织入过的源码交给基础语言的编译器产生最终可执行代码。比如，使用这种方式，一个基于Java的AOP实现可以先把不同的方面转化成Java源代码，然后让Java编译器把它转化成字节码。也可以直接在字节码级别执行织入；毕竟，字节码本身也是一种源码。此外，下面的执行系统——Java虚拟机——也可以是方面认知的，基于Java的AOP 实现如果使用这种方式的话，虚拟机可以先装入织入规则，然后对后来装入的类都应用这种规则，也就是说，它可以执行just-in-time的方面织入。 <br /><br /><span style="FONT-WEIGHT: bold">AOP的好处</span><br /><br />AOP可帮助我们解决上面提到的代码混乱和代码分散所带来的问题，它还有一些别的好处： <br /><ul><br /><li>块化横切关注点：AOP用最小的耦合处理每个关注点，使得即使是横切关注点也是模块化的。这样的实现产生的系统，其代码的冗余小。模块化的实现还使得系统容易理解和维护 <br /></li><li>系统容易扩展：由于方面模块根本不知道横切关注点，所以很容易通过建立新的方面加入新的功能，另外，当你往系统中加入新的模块时，已有的方面自动的横切进来，使系统的易于扩展 <br /></li><li>设计决定的迟绑定：还记得设计师的两难局面吗？使用AOP,设计师可以推迟为将来的需求作决定，因为它可以把这种需求作为独立的方面很容易的实现。 <br /></li><li>更好的代码重用性：由于AOP把每个方面实现为独立的模块，模块之间是松散耦合的，举例来说，你可以用另外一个独立的日志写入器方面（替换当前的）把日志写入数据库，以满足不同的日志写入要求。 <br />总的来说，松散耦合的实现意味着更好的代码重用性， AOP在使系统实现松散耦合这一点上比OOP做得更好。 <br /></li></ul><br /><br /><span style="FONT-WEIGHT: bold">AspectJ:一个Java的AOP实现</span><br /><br />AspectJ是一个可免费获得的由施乐公司帕洛阿尔托研究中心（Xerox PARC）开发Java的AOP实现，它是一个多功能的面向方面的Java扩展。它使用Java作为单个关注点的实现语言，并扩展Java以指定织入规则。这些规则是用切入点（pointcuts）、联结点（join points），通知（advice）和方面（aspect）来说明的。联结点是定义在程序执行过程之间的点，切入点由用来指定联结点的语言构造，通知定义了要在切入点上执行的代码片，而方面则是这些基础元素的组合。 <br /><br />另外，AspectJ允许以多种方式用方面和类建立新的方面，你可以引入新的数据成员和方法，或是声明一个新的类来继承和实现另外的类或接口。 <br /><br />AspectJ的织入器——AspectJ的编译器——负责把不同的方面组合在一起，由于由AspectJ编译器建立的最终系统是纯Java字节码，它可以运行在任何符合Java标准的虚拟机上。而且，AspectJ还提供了一些工具如调试器和Java IDE集成等，我将会在本系列的第二、三部分详细讲解这些。 <br /><br />下面是我在上面用自然语言描述的日志方面的织入规则的AspectJ实现，由于我将会在第二部分详细介绍AspectJ，所以如果你不能透彻的看懂它的话也不必担心。关键是你应该注意到信用卡处理过程本身一点都不知道日志的事。 <br /><br /></span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>代码:</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<br />public aspect LogCreditCardProcessorOperations { <br />    Logger logger = new StdoutLogger(); <br /><br />    pointcut publicOperation(): <br />        execution(public * CreditCardProcessor.*(..)); <br /><br />    pointcut publicOperationCardAmountArgs(CreditCard card, <br />                                           Money amount): <br />        publicOperation() &amp;&amp; args(card, amount); <br /><br />    before(CreditCard card, Money amount): <br />        publicOperationCardAmountArgs(card, amount) { <br />        logOperation("Starting", <br />             thisjoin point.getSignature().toString(), card, amount); <br />    } <br /><br />    after(CreditCard card, Money amount) returning: <br />        publicOperationCardAmountArgs(card, amount) { <br />        logOperation("Completing", <br />            thisjoin point.getSignature().toString(), card, amount); <br />    } <br /><br />    after (CreditCard card, Money amount) throwing (Exception e): <br />        publicOperationCardAmountArgs(card, amount) { <br />        logOperation("Exception " + e, <br />            thisjoin point.getSignature().toString(), card, amount); <br />    } <br /><br />    private void logOperation(String status, String operation, <br />                              CreditCard card, Money amount) { <br />        logger.log(status + " " + operation + <br />                   " Card: " + card + " Amount: " + amount); <br />    } <br />} <br /><br /><br /></td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<span style="FONT-WEIGHT: bold">我需要AOP吗？</span>
				<br />
				<br />AOP仅仅是解决设计上的缺点吗？在AOP里，每个关注点的实现的并不知道是否有其它关注点关注它，这是AOP和OOP的主要区别，在AOP里，组合的流向是从横切关注点到主关注点，而OOP则相反，但是，OOP可以和AOP很好的共存。比如，你可以使用一个混入类来做组合，既可以用AOP实现，也可以用OOP实现，这取决你对AOP的接受程度。在这两种情况下，实现横切关注点的混入类实现都无需知道它自己是被用在类中还是被用在方面中。举个例子来说，你可以把一个日志写入器接口用作某些类的混入类或是用作一个日志方面。因而，从OOP到AOP是渐进的。 <br /><br /><span style="FONT-WEIGHT: bold">了解AOP</span><br /><br />在这篇文章里，你看到了横切关系带来的问题，这些问题的当前解决方法，以及这些方法的缺点。你也看到了AOP是怎样克服这些缺点的。AOP的编程方式试图模块化横切关注点的实现，提供了一个更好更快的软件开发方式。 <br /><br />如果你的系统中涉及到多个横切关注点，你可以考虑进一步了解AOP,它的实现，它的好处。AOP很可能会是编程方式的下一个里程碑。请继续关注本系列的第二、第三部分。 </span>
<img src ="http://www.blogjava.net/zhhp1314520/aggbug/77133.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhhp1314520/" target="_blank">捕风</a> 2006-10-25 10:06 <a href="http://www.blogjava.net/zhhp1314520/articles/aop1.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring AOP中文教程</title><link>http://www.blogjava.net/zhhp1314520/articles/Spring_AOP.html</link><dc:creator>捕风</dc:creator><author>捕风</author><pubDate>Wed, 25 Oct 2006 02:04:00 GMT</pubDate><guid>http://www.blogjava.net/zhhp1314520/articles/Spring_AOP.html</guid><wfw:comment>http://www.blogjava.net/zhhp1314520/comments/77131.html</wfw:comment><comments>http://www.blogjava.net/zhhp1314520/articles/Spring_AOP.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhhp1314520/comments/commentRss/77131.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhhp1314520/services/trackbacks/77131.html</trackback:ping><description><![CDATA[
		<span class="postbody">这是在网上发现的一篇关于Spring AOP编程的教程，读完这篇文章后，Spring AOP不再难以理解，因此我把它译成中文，推荐给Spring AOP的初学者。这是译文的<a class="postlink" href="http://tools.devchannel.org/devtoolschannel/04/04/15/1457223.shtml" target="_blank">链接</a>。 <br /><br />AOP正在成为软件开发的下一个圣杯。使用AOP，你可以将处理aspect的代码注入主程序，通常主程序的主要目的并不在于处理这些aspect。AOP可以防止代码混乱。 <br />为了理解AOP如何做到这点，考虑一下记日志的工作。日志本身不太可能是你开发的主程序的主要任务。如果能将“不可见的”、通用的日志代码注入主程序中，那该多好啊。AOP可以帮助你做到。 <br />Spring framework是很有前途的AOP技术。作为一种非侵略性的，轻型的AOP framework，你无需使用预编译器或其他的元标签，便可以在Java程序中使用它。这意味着开发团队里只需一人要对付AOP framework，其他人还是象往常一样编程。 <br />AOP是很多直觉难以理解的术语的根源。幸运的是，你只要理解三个概念，就可以编写AOP模块。这三个概念是：advice，pointcut和 advisor。advice是你想向别的程序内部不同的地方注入的代码。pointcut定义了需要注入advice的位置，通常是某个特定的类的一个 public方法。advisor是pointcut和advice的装配器，是将advice注入主程序中预定义位置的代码。 <br /><br />既然我们知道了需要使用advisor向主要代码中注入“不可见的”advice，让我们实现一个Spring AOP的例子。在这个例子中，我们将实现一个before advice，这意味着advice的代码在被调用的public方法开始前被执行。以下是这个before advice的实现代码： <br /><br /></span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>代码:</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">package com.company.springaop.test; <br /><br />import java.lang.reflect.Method; <br />import org.springframework.aop.MethodBeforeAdvice; <br /><br />public class TestBeforeAdvice implements MethodBeforeAdvice { <br /><br />  public void before(Method m, Object[] args, Object target) <br />  throws Throwable { <br />    System.out.println("Hello world! (by " <br />        + this.getClass().getName() <br />        + ")"); <br />  } <br />} <br /> </td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />接口MethodBeforeAdvice只有一个方法before需要实现，它定义了advice的实现。before方法共用三个参数，它们提供了相当丰富的信息。参数Method m是advice开始后执行的方法。方法名称可以用作判断是否执行代码的条件。Object[] args是传给被调用的public方法的参数数组。当需要记日志时，参数args和被执行方法的名称，都是非常有用的信息。你也可以改变传给m的参数，但要小心使用这个功能；编写最初主程序的程序员并不知道主程序可能会和传入参数的发生冲突。Object target是执行方法m对象的引用。 <br /><br />在下面的BeanImpl类中，每个public方法调用前，都会执行advice： <br /><br /></span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>代码:</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">package com.company.springaop.test; <br /><br />public class BeanImpl implements Bean { <br /><br />  public void theMethod() { <br />    System.out.println(this.getClass().getName() <br />        + "." + new Exception().getStackTrace()[0].getMethodName() <br />        + "()" <br />        + " says HELLO!"); <br />  } <br />}</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />类BeanImpl实现了下面的接口Bean： <br /><br /></span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>代码:</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">package com.company.springaop.test; <br /><br />public interface Bean { <br />  public void theMethod(); <br />}</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<br />虽然不是必须使用接口，但面向接口而不是面向实现编程是良好的编程实践，Spring也鼓励这样做。 <br /><br />pointcut和advice通过配置文件来实现，因此，接下来你只需编写主方法的Java代码： <br /></span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>代码:</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<br />
										<br />package com.company.springaop.test; <br /><br />import org.springframework.context.ApplicationContext; <br />import org.springframework.context.support.FileSystemXmlApplicationContext; <br /><br />public class Main { <br /><br />  public static void main(String[] args) { <br />    //Read the configuration file <br />    ApplicationContext ctx <br />        = new FileSystemXmlApplicationContext("springconfig.xml"); <br /><br />    //Instantiate an object <br />    Bean x = (Bean) ctx.getBean("bean"); <br /><br />    //Execute the public method of the bean (the test) <br />    x.theMethod(); <br />  } <br />}</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<br />我们从读入和处理配置文件开始，接下来马上要创建它。这个配置文件将作为粘合程序不同部分的“胶水”。读入和处理配置文件后，我们会得到一个创建工厂ctx。任何一个Spring管理的对象都必须通过这个工厂来创建。对象通过工厂创建后便可正常使用。 <br /><br />仅仅用配置文件便可把程序的每一部分组装起来。 <br /></span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>代码:</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<br />&lt;?xml version="1.0" encoding="UTF-8"?&gt; <br />&lt;!DOCTYPE beans PUBLIC  "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"&gt; <br /><br />&lt;beans&gt; <br />  &lt;!--CONFIG--&gt; <br />  &lt;bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean"&gt; <br />    &lt;property name="proxyInterfaces"&gt; <br />      &lt;value&gt;com.company.springaop.test.Bean&lt;/value&gt; <br />    &lt;/property&gt; <br />    &lt;property name="target"&gt; <br />      &lt;ref local="beanTarget"/&gt; <br />    &lt;/property&gt; <br />    &lt;property name="interceptorNames"&gt; <br />      &lt;list&gt; <br />        &lt;value&gt;theAdvisor&lt;/value&gt; <br />      &lt;/list&gt; <br />    &lt;/property&gt; <br />  &lt;/bean&gt; <br /><br />  &lt;!--CLASS--&gt; <br />  &lt;bean id="beanTarget" class="com.company.springaop.test.BeanImpl"/&gt; <br /><br />  &lt;!--ADVISOR--&gt; <br />  &lt;!--Note: An advisor assembles pointcut and advice--&gt; <br />  &lt;bean id="theAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"&gt; <br />    &lt;property name="advice"&gt; <br />      &lt;ref local="theBeforeAdvice"/&gt; <br />    &lt;/property&gt; <br />    &lt;property name="pattern"&gt; <br />      &lt;value&gt;com\.company\.springaop\.test\.Bean\.theMethod&lt;/value&gt; <br />    &lt;/property&gt; <br />  &lt;/bean&gt; <br /><br />  &lt;!--ADVICE--&gt; <br />  &lt;bean id="theBeforeAdvice" class="com.company.springaop.test.TestBeforeAdvice"/&gt; <br />&lt;/beans&gt; <br /> </td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />四个bean定义的次序并不重要。我们现在有了一个advice，一个包含了正则表达式pointcut的advisor，一个主程序类和一个配置好的接口，通过工厂ctx，这个接口返回自己本身实现的一个引用。 <br /><br />BeanImpl和TestBeforeAdvice都是直接配置。我们用一个唯一的ID创建一个bean元素，并指定了一个实现类。这就是全部的工作。 <br /><br />advisor通过Spring framework提供的一个RegexMethodPointcutAdvisor类来实现。我们用advisor的一个属性来指定它所需的 advice-bean。第二个属性则用正则表达式定义了pointcut，确保良好的性能和易读性。 <br /><br />最后配置的是bean，它可以通过一个工厂来创建。bean的定义看起来比实际上要复杂。bean是ProxyFactoryBean的一个实现，它是Spring framework的一部分。这个bean的行为通过一下的三个属性来定义： <br /><br /><ul><br /><li>属性proxyInterface定义了接口类。 <br /></li><li>属性target指向本地配置的一个bean，这个bean返回一个接口的实现。 <br /></li><li>属性interceptorNames是唯一允许定义一个值列表的属性。这个列表包含所有需要在beanTarget上执行的advisor。注意，advisor列表的次序是非常重要的。 <br /></li></ul><br /><br /><span style="FONT-WEIGHT: bold">Spring工具</span><br /><br />虽然你可以手工修改Ant构建脚本，但使用SpringUI（译注：SpringUI现在是Spring framework的一部分，并改名为spring-ide），使用Spring AOP变得很简单，只要点点鼠标即可。你可以把SpringUI安装成Eclipse的一个plug-in。然后，你只需在你的project上右击鼠标，并选择“add Spring Project Nature”。在project属性中，你可以在“Spring Project”下添加Spring配置文件。在编译前把下面的类库加入project：aopalliance.jar，commons- logging.jar，jakarta-oro-2.0.7.jar和spring.jar。运行程序时你会看到下面的信息： <br /><br />... (logging information) <br />Hello world! (by com.company.springaop.test.TestBeforeAdvice) <br />com.company.springaop.test.BeanImpl.theMethod() says HELLO! <br /><br /><br /><span style="FONT-WEIGHT: bold">优点和缺点</span><br /><br />Spring比起其他的framework更有优势，因为除了AOP以外，它提供了更多别的功能。作为一个轻型framework，它在J2EE 不同的部分都可以发挥作用。因此，即使不想使用Spring AOP，你可能还是想使用Spring。另一个优点是，Spring并不要求开发团队所有的人员都会用它。学习Spring应该从Spring reference的第一页开始。读了本文后，你应该可以更好地理解Spring reference了。Spring唯一的缺点是缺乏更多的文档，但它的mailing list是个很好的补充，而且会不断地出现更多的文档。</span>
<img src ="http://www.blogjava.net/zhhp1314520/aggbug/77131.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhhp1314520/" target="_blank">捕风</a> 2006-10-25 10:04 <a href="http://www.blogjava.net/zhhp1314520/articles/Spring_AOP.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于AspectJ 中的pointcut 语法</title><link>http://www.blogjava.net/zhhp1314520/articles/AspectJ_pointcut.html</link><dc:creator>捕风</dc:creator><author>捕风</author><pubDate>Thu, 19 Oct 2006 09:28:00 GMT</pubDate><guid>http://www.blogjava.net/zhhp1314520/articles/AspectJ_pointcut.html</guid><wfw:comment>http://www.blogjava.net/zhhp1314520/comments/76225.html</wfw:comment><comments>http://www.blogjava.net/zhhp1314520/articles/AspectJ_pointcut.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhhp1314520/comments/commentRss/76225.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhhp1314520/services/trackbacks/76225.html</trackback:ping><description><![CDATA[
		<div class="postTitle">
				<a class="postTitle2" id="viewpost1_TitleUrl" href="/zyl/archive/2006/10/17/75732.html">
						<font color="#646464">关于AspectJ 中的pointcut 语法</font>
				</a>
		</div>    这两天忙着看AspectJ in Action 为了补一下AOP知识。看了Spring 2.0的规范，其中AOP部分已经基本融合了AspectJ，看来有必要看一看AspectJ了。<br />   看了很多AOP的文章了，AOP这两年发展的很慢，没有什么新意，现在到处都是SOA，SCA了，不过研究了一下，觉得还是很有帮助的。尤其是增加系统的契约性和模块的独立性来说，很有帮助。<br />   当然，学东西，基础很重要。下面就说说AspectJ中的基本语法，有兴趣的可以看看AspectJ in Action。<br />   先来说说pointcut，从字面的意思说的是切面的意思。也就是横切的时候，会有哪些执行点会被识别。只有先识别了，才能执行相应的Advice。<br />   基本的定义如下：<br />   <br />   public <font color="#ff6600">pointcut </font>accountOperations:call(* Account.*(..))<br />   <br />   <b>1.通配符和pointcut 操作符<br /></b><ul><li><b>   </b><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">*  </span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">表示任何数量的字符，除了(.)</span></li><li><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">    </span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">..</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体"> 表示任何数量的字符包括任何数量的(.)</span></li><li><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">       + </span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">描述指定类型的任何子类或者子接口</span></li></ul><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">    </span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">同</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">java</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">一样，提供了一元和二元的条件表达操作符。<br />    </span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">一元操作符：</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">!<br />      </span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">二元操作符：</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">||</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">和</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">&amp;&amp;<br />      </span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">优先权同</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">java<br /><br />  <b>    2.</b></span><b><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体">签名语法<br /><br />  </span></b><b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">类型签名</span></b><b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">样式<br /><br />  </span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">主要的例子:</span><br /><b><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体">  </span></b><b><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">Account</span></b><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'"><span>                              </span></span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">类型</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">Account<br />    </span><b><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">*Account                             </span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">使用</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">Account</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">名称结束的类型，如</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">SavingsAccount</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">和</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">CheckingAccount<br />    </span><b><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">java.*.Date                         </span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">类型</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">Date</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">在任何直接的</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">java</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">子包中，如</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">java.util.Date</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">和</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">java.sql.Date<br />    </span><b><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">java..*                                 </span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">任何在</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">java</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">包或者所有子包中的类型，如</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">java.awt</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">和</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">java.util</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">或者</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">java.awt.event </span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">和</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">java.util.logging<br />    </span><b><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">javax..*Model+                   </span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">所有</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">javax</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">包或者子包中以</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">Model</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">结尾的类型和其所有子类，如</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">TableModel,TreeModel</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">。<br />  </span><b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">！</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">vector <span>      </span></span></b><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'"><span>                      </span></span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">所有除了</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">Vector</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">的类型<br />  </span><b><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">Vector|| Hashtable<span>              </span></span></b><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">Vector</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">或者</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">Hashtable</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">类型<br />  </span><b><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">java.util.RandomAccess+<span>    </span></span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">实现</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">RandomAccess</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">和</span><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">List</span><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">的所有子类</span><br /><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">   </span><b><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">&amp;&amp; java.util.List+</span></b><br /><span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'">   <br />   </span><b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">方法和构造器签名模式<br /><br />  public void Collection.clear()：<br />  </span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">在Collection中同样签名的clear方法<br /><br /></span><b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">  public void Account.debit(float) throws InsufficientBalanceException：<br />  </span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">Account中同样签名的debit方法<br /><br /></span><b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">  public void Account.set*(*)<br />  </span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">Account中以set开头，并且只有一个参数类型的方法<br /><br /></span><b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">  public void Account.*()<br /> </span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体"> Account中所有的没有参数的public void 方法<br /> <br /></span><b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">  public * Account.*()<br /></span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">  Account中所有没有参数的public 方法<br /><br /></span><b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">  public * Account.*(..)<br />  </span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">Account中所有的public 方法<br /><br /></span><b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">  * Account.*(..)<br /> </span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体"> Account中的所有方法，包括private方法<br /><br /></span><b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">  !public * Account.*(..)<br /> </span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体"> 所有的非public 方法</span><b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体"><br /><br />   * Account+.*(..)<br />   </span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">所有的方法，包括子类的方法<br /><br /></span><b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">   * java.io.Reader.read(..)<br />   </span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">所有的read方法<br /><br /></span><b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">   * java.io.Reader.read(char[],..)<br />   </span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">所有以read(char[])开始的方法，包括read(char[])和read(char[],int,int)<br /><br /></span><b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">   * javax..*.add*Listener(EventListener+)<br />   </span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">命名以add开始，以Listener结尾的方法，参数中为EventListener或子类<br /><br /></span><b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">   * *.*(..) throws RemoteException<br />   </span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">抛出RemoteException的所有方法</span><b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体"><br /><br />   构造器，同上面<br />   public Account.new()<br />   </span></b><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">没有参数的构造器方法<br /><br />    <b>属性签名模式</b><br />    同方法一样，属性也查不多<br />   <b> * Account.*  </b>  <br />    所有的Account属性<br /><br />    <b>!public static * banking..*.*</b><br />    所有的非public static 属性，在banking的包或者子包中<br />    <br />    <b>3.主要的pointcuts类型<br />   <br /></b>    <b>分类pointcuts</b><br />    遵循特定的语法用于捕获每一个种类的可使用连接点。<br />    主要的种类：<br /></span><ul><li><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">方法执行：execution(MethodSignature)</span></li><li><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">方法调用：call(MethodSignature)</span></li><li><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">构造器执行：execution(ConstructorSignature)</span></li><li><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">构造器调用：call(ConstructorSignature)</span></li><li><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">类初始化：staticinitialization(TypeSignature)</span></li><li><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">属性读操作：get(FieldSignature)</span></li><li><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">属性写操作：set(FieldSignature)</span></li><li><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">例外处理执行：handler(TypeSignature)</span></li><li><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">对象初始化：initialization(ConstructorSignature)</span></li><li><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">对象预先初始化：preinitialization(ConstructorSignature)</span></li><li><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体">Advice执行：adviceexecution()</span></li></ul>   <b>基于控制流的pointcuts</b><br />   主要包括两种类型的控制流：<br />   cflow(Pointcut)，捕获所有的连接点在指定的方法执行中，包括执行方法本身。<br />   cflowbelow(Pointcut)，捕获所有的连接点在指定的方法执行中，除了执行方法本身。<br /><br />   如以下的例子：<br />   <b>cflow(call(* Account.debit(..))</b><br />   所有的debit方法中的连接点，包括debit方法本身<br />  <b> cflowbelow(call(* Account.debit(..))</b><br />   所有debit方法中的连接点，除了debit方法本身<br />  <b> cflow(transactedOperations())</b><br />   所有由transactedOperations捕获的连接点<br />   <b>cflowbelow(execution(Account.new(..))</b><br />   所有在Account 构造器中执行的连接点<br /><br />   <b>基于词汇结构的连接点</b><br />   源代码片断。，如within()和withincode()<br />   within ：捕获在指定类或者方面中的程序体中的所有连接点，包括内部类。<br />   Withincode：用于捕获在构造器或者方法中的所有连接点，包括在其中的本地类<br /><br />   <b>执行对象连接点</b><br />   匹配this,和target对象，作为方法被调用的对象。<br />   this(Account)，所有Account的实例的执行点，匹配所有的连接点，如方法调用，属性设置，当前的执行对象为Account，或者其子类。<br />   target(Account)：匹配所有的连接点，目标对象为Account或其子类。<br /><br />   必须执行相应的类型，不能使用*,或者..通配符。当前静态方法，不能被匹配。<br /><br />   在within()和this()中的区别：<br />   一个是程序体，而另一个为对象执行。<br /><br />   <b>参数pointcuts</b><br />   用于捕获参数类型的连接点。<br />   args(String,..,int)<br />   args(RemoteException)<br /><br />   <b>条件检测pointcuts</b><br />   if(System.currentTimeMillis()&gt;triggerTime)<br /><br /><br />   基本的语法就这些，不过AspectJ5 已经增加了不少语法，主要关于Annotation 的，不过这部分还没有仔细研究，以后再讲解吧。希望能有所帮助<br /><img src ="http://www.blogjava.net/zhhp1314520/aggbug/76225.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhhp1314520/" target="_blank">捕风</a> 2006-10-19 17:28 <a href="http://www.blogjava.net/zhhp1314520/articles/AspectJ_pointcut.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>j2ee小应用</title><link>http://www.blogjava.net/zhhp1314520/articles/j2ee_file_rss_search.html</link><dc:creator>捕风</dc:creator><author>捕风</author><pubDate>Fri, 13 Oct 2006 02:08:00 GMT</pubDate><guid>http://www.blogjava.net/zhhp1314520/articles/j2ee_file_rss_search.html</guid><wfw:comment>http://www.blogjava.net/zhhp1314520/comments/74927.html</wfw:comment><comments>http://www.blogjava.net/zhhp1314520/articles/j2ee_file_rss_search.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhhp1314520/comments/commentRss/74927.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhhp1314520/services/trackbacks/74927.html</trackback:ping><description><![CDATA[
		<span style="FONT-SIZE: 13px">附加功能 (目录)<br />实现图片上传 (目录)<br />　　用户必须能够上传图片，因此需要文件上传的功能。比较常见的文件上传组件有Commons FileUpload（<a href="http://jakarta.apache.org/commons/fileupload/a" target="_blank">http://jakarta.apache.org/commons/fileupload/a</a>&gt;）和COS FileUpload（<a href="http://www.servlets.com/cos" target="_blank">http://www.servlets.com/cos</a>），Spring已经完全集成了这两种组件，这里我们选择Commons FileUpload。<br />　　由于Post一个包含文件上传的Form会以multipart/form-data请求发送给服务器，必须明确告诉 DispatcherServlet如何处理MultipartRequest。首先在dispatcher-servlet.xml中声明一个 MultipartResolver：<br /><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"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">bean </span><span style="COLOR: #ff0000">id</span><span style="COLOR: #0000ff">="multipartResolver"</span><span style="COLOR: #ff0000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />       class</span><span style="COLOR: #0000ff">="org.springframework.web.multipart.commons.CommonsMultipartResolver"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #008000">&lt;!--</span><span style="COLOR: #008000"> 设置上传文件的最大尺寸为1MB </span><span style="COLOR: #008000">--&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">property </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="maxUploadSize"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">value</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">1048576</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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">bean</span><span style="COLOR: #0000ff">&gt;</span></div><br /><br />　　这样一旦某个Request是一个MultipartRequest，它就会首先被MultipartResolver处理，然后再转发相应的Controller。<br />　　在UploadImageController中，将HttpServletRequest转型为MultipartHttpServletRequest，就能非常方便地得到文件名和文件内容：<br /><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"><img id="Codehighlighter1_109_445_Open_Image" onclick="this.style.display='none'; Codehighlighter1_109_445_Open_Text.style.display='none'; Codehighlighter1_109_445_Closed_Image.style.display='inline'; Codehighlighter1_109_445_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_109_445_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_109_445_Closed_Text.style.display='none'; Codehighlighter1_109_445_Open_Image.style.display='inline'; Codehighlighter1_109_445_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) </span><span style="COLOR: #0000ff">throws</span><span style="COLOR: #000000"> Exception </span><span id="Codehighlighter1_109_445_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"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_109_445_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 转型为MultipartHttpRequest：</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">    MultipartHttpServletRequest multipartRequest </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (MultipartHttpServletRequest) request;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 获得文件：</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">    MultipartFile file </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> multipartRequest.getFile(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">file</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 获得文件名：</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">    String filename </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> file.getOriginalFilename();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 获得输入流：</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">    InputStream input </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> file.getInputStream();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 写入文件<img src="http://www.blogjava.net/images/dot.gif" /></span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" /></span><span style="COLOR: #000000">}</span></span></div><br /><br />生成缩略图 (目录)<br />　　当用户上传了图片后，必须生成缩略图以便用户能快速浏览。我们不需借助第三方软件，JDK标准库就包含了图像处理的API。我们把一张图片按比例缩放到120X120大小，以下是关键代码：<br /><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"><img id="Codehighlighter1_71_1006_Open_Image" onclick="this.style.display='none'; Codehighlighter1_71_1006_Open_Text.style.display='none'; Codehighlighter1_71_1006_Closed_Image.style.display='inline'; Codehighlighter1_71_1006_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_71_1006_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_71_1006_Closed_Text.style.display='none'; Codehighlighter1_71_1006_Open_Image.style.display='inline'; Codehighlighter1_71_1006_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> createPreviewImage(String srcFile, String destFile) </span><span id="Codehighlighter1_71_1006_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"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_71_1006_Open_Text"><span style="COLOR: #000000">{<br /><img id="Codehighlighter1_81_852_Open_Image" onclick="this.style.display='none'; Codehighlighter1_81_852_Open_Text.style.display='none'; Codehighlighter1_81_852_Closed_Image.style.display='inline'; Codehighlighter1_81_852_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_81_852_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_81_852_Closed_Text.style.display='none'; Codehighlighter1_81_852_Open_Image.style.display='inline'; Codehighlighter1_81_852_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000"> </span><span id="Codehighlighter1_81_852_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"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_81_852_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        File fi </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> File(srcFile); </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> src</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">        File fo </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> File(destFile); </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> dest</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">        BufferedImage bis </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> ImageIO.read(fi);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> w </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> bis.getWidth();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> h </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> bis.getHeight();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000"> scale </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">)w</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">h;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> nw </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> IMAGE_SIZE; </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> final int IMAGE_SIZE = 120;</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> nh </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (nw </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> h) </span><span style="COLOR: #000000">/</span><span style="COLOR: #000000"> w;<br /><img id="Codehighlighter1_440_510_Open_Image" onclick="this.style.display='none'; Codehighlighter1_440_510_Open_Text.style.display='none'; Codehighlighter1_440_510_Closed_Image.style.display='inline'; Codehighlighter1_440_510_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="