﻿<?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-【永恒的瞬间】  -文章分类-Spring</title><link>http://www.blogjava.net/19851985lili/category/18359.html</link><description>☜GivE mE HapPy ☞




</description><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 03:42:59 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 03:42:59 GMT</pubDate><ttl>60</ttl><item><title>Spring网上学习资源,很不错的 </title><link>http://www.blogjava.net/19851985lili/articles/98479.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Wed, 07 Feb 2007 01:01:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/98479.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/98479.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/98479.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/98479.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/98479.html</trackback:ping><description><![CDATA[
		<p>Spring英文资源 <br />Spring官方网站 <br /><a href="http://www.springframework.org/" target="blank"><font color="#002c99">http://www.springframework.org/ </font></a></p>
		<p>Spring专业网站 <br /><a href="http://www.springframework.com/" target="blank"><font color="#002c99">http://www.springframework.com/ </font></a></p>
		<p>Spring 社区 <br /><a href="http://www.thespringexperience.com/" target="blank"><font color="#002c99">http://www.thespringexperience.com </font></a></p>
		<p>SourceForge Spring项目网址 <br /><a href="http://sourceforge.net/projects/springframework/" target="blank"><font color="#002c99">http://sourceforge.net/projects/springframework/ </font></a></p>
		<p>Spring论坛 <br /><a href="http://forum.springframework.org/" target="blank"><font color="#002c99">http://forum.springframework.org/ </font></a></p>
		<p>Spring邮件列表 <br /><a href="http://sourceforge.net/mail/?group_id=73357" target="blank"><font color="#002c99">http://sourceforge.net/mail/?group_id=73357 </font></a></p>
		<p>Spring Confluence <br /><a href="http://opensource.atlassian.com/confluence/spring" target="blank"><font color="#002c99">http://opensource.atlassian.com/confluence/spring </font></a></p>
		<p>Introducing to Spring Framework <br /><a href="http://www.theserverside.com/articles/article.tss?l=SpringFramework" target="blank"><font color="#002c99">http://www.theserverside.com/articles/article.tss?l=SpringFramework </font></a></p>
		<p>CKNY's Very Quick Wiki <br /><a href="http://ckny.eatj.com/wiki/jsp/Wiki?Spring" target="blank"><font color="#002c99">http://ckny.eatj.com/wiki/jsp/Wiki?Spring </font></a></p>
		<p>Spring中文资源 <br />Spring中文论坛 <br /><a href="http://spring.jactiongroup.net/" target="blank"><font color="#002c99">http://spring.jactiongroup.net </font></a></p>
		<p>Introducing to Spring Framework（中文版） <br /><a href="http://spring.jactiongroup.net/viewtopic.php?t=453" target="blank"><font color="#002c99">http://spring.jactiongroup.net/viewtopic.php?t=453 </font></a></p>
		<p>Spring开发指南 <br /><a href="http://www.xiaxin.net/Spring_Dev_Guide.rar" target="blank"><font color="#002c99">http://www.xiaxin.net/Spring_Dev_Guide.rar </font></a></p>
		<p>Spring相关个人 <br />Rod Johnson，Spring之父 <br />个人介绍：http://www.springframework.com/people/rod.html <br />blog：http://blog.springframework.com/rod/ </p>
		<p>Juergen Hoeller，Spring协同创始人 <br />个人介绍：http://www.springframework.com/people/juergen.html <br />blog：http://blog.springframework.com/juergen/ </p>
		<p>Bruce Tate，知名Java/Spring图书作者 <br />个人介绍：http://www.springframework.com/people/bruce.html <br />blog：http://today.java.net/pub/au/186 </p>
		<p>Colin Sampaleanu，Spring核心成员 <br />个人介绍：http://www.springframework.com/people/colin.html <br />blog：http://blog.exis.com/colin/ </p>
		<p>Keith Donald，Spring核心成员，Spring Rich Client Project的创建者 <br />个人介绍：http://www.springframework.com/people/keith.html <br />blog：http://jroller.com/page/kdonald </p>
		<p>Alef Arendsen <br />个人介绍：http://www.springframework.com/people/alef.html </p>
		<p>Spring Live，《Spring Live》作者的Blog <br /><a href="http://jroller.com/page/raible" target="blank"><font color="#002c99">http://jroller.com/page/raible </font></a></p>
		<p>Craig's stack trace，《Spring in action》作者的blog <br /><a href="http://jroller.com/page/habuma" target="blank"><font color="#002c99">http://jroller.com/page/habuma </font></a></p>
		<p>Spring子项目 <br />Spring Rich Client Project <br /><a href="http://sourceforge.net/projects/spring-rich-c" target="blank"><font color="#002c99">http://sourceforge.net/projects/spring-rich-c </font></a></p>
		<p>Spring IDE for Eclipse <br /><a href="http://www.springframework.org/spring-ide/eclipse/" target="blank"><font color="#002c99">http://www.springframework.org/spring-ide/eclipse/ </font></a></p>
		<p>Spring相关项目 <br />Spring For .NET <br /><a href="http://www.springframework.net/" target="blank"><font color="#002c99">http://www.springframework.net/ </font></a></p>
		<p>Acegi Security System <br /><a href="http://acegisecurity.sourceforge.net/" target="blank"><font color="#002c99">http://acegisecurity.sourceforge.net/ </font></a></p>
		<p>JSF-Spring <br /><a href="http://jsf-spring.sourceforge.net/" target="blank"><font color="#002c99">http://jsf-spring.sourceforge.net/ </font></a></p>
		<p>Spring-Validator <br /><a href="http://sourceforge.net/projects/js-validation/" target="blank"><font color="#002c99">http://sourceforge.net/projects/js-validation/</font></a></p>
<img src ="http://www.blogjava.net/19851985lili/aggbug/98479.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-02-07 09:01 <a href="http://www.blogjava.net/19851985lili/articles/98479.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring AOP Review </title><link>http://www.blogjava.net/19851985lili/articles/98477.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Wed, 07 Feb 2007 00:48:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/98477.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/98477.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/98477.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/98477.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/98477.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在阅读此文之前请你熟悉一些IOC的知识，同时了解AOP的概念。						在				Spring				中所有的通知都是以				Java				类的形式编写的。				Spring				是采用运行期的方式来将切面织入到系统中的。														代理						Bean								只有在第一次被应用系统需要的时候才被创建。...&nbsp;&nbsp;<a href='http://www.blogjava.net/19851985lili/articles/98477.html'>阅读全文</a><img src ="http://www.blogjava.net/19851985lili/aggbug/98477.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-02-07 08:48 <a href="http://www.blogjava.net/19851985lili/articles/98477.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入了解struts中的struts-config.xml </title><link>http://www.blogjava.net/19851985lili/articles/98470.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Wed, 07 Feb 2007 00:25:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/98470.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/98470.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/98470.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/98470.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/98470.html</trackback:ping><description><![CDATA[弄清楚struts-config.xml中各项元素的作用，对于我们构建web项目有莫大的好处。&lt;struts-config&gt;是struts的根元素，它主要有8个子元素，DTD定义如下： 
<p>&lt;!ELEMENT struts-config<br />(data-sources?,form-beans?,global-exceptions?,global-forwards?,action-mappings?,controller?,message-resources*,plug-in*)<br />&gt;<br />以上8个元素，下面一一描述：<br /><font color="#ff0000"><strong>1. date-sources元素<br /></strong></font><font color="#000000"><strong>　　</strong>date-sources元素用来配置应用程序所需要的数据源。java语言提供了javax.sql.DateSource接口，所有数据源必须实现该接口。如下配置：<br />&lt;data-sources&gt;<br />　　&lt;data-source type="org.apached.commons.dbcp.BasicDataSource"&gt;<br />　　　　………………<br />　　&lt;/data-source&gt;<br /></font>&lt;/data-sources&gt;<br />在Action中访问方式如：<br />javax.sql.DataSource dataSource;<br />java.sql.Connection myConnection;<br />try<br />{<br />　　dataSource = getDataSource(request);<br />　　myConnection　＝　dataSource.getConnection();<br />}<br />…………<br />　　如果是多数据源，可用如下配置：<br />&lt;data-sources&gt;<br />　　&lt;data-source key="a"  type="org.apached.commons.dbcp.BasicDataSource"&gt;<br />　　　　………………<br />　　&lt;/data-source&gt;<br />　　&lt;data-source key="b"   type="org.apached.commons.dbcp.BasicDataSource"&gt;<br />　　　　……………… <br />　　&lt;/data-source&gt;<br />&lt;/data-sources&gt;<br />访问方式：dataSource = getDataSource(request,"a");</p><p><strong><font color="#ff0000"> 2. form-beans元素</font></strong><br />　　该元素主要用来配置表单验证的类。它包含如下属性：<br />　　1. classname：一般用得少，指定和form-bean无素对应的配置类，默认为org.apache.struts.config.FormBeanConfig，如果自定义，则必须扩展FormBeanConfig类。可有可无。<br />　　2. name：ActionForm Bean的惟一标识。必须。<br />　　3. type：ActionForm的完整类名。必须。<br />如下所示：<br />&lt;form-beans&gt;<br />　　&lt;form-bean <br />　　　　　　name="Loign"<br />　　　　　　type="com.ha.login"&gt;<br />　　&lt;/form-bean&gt;<br />&lt;/form-beans&gt;<br />　　如果是动态Action FormBean，还必须配置form-bean元素的form-property子元素。它包含四个属性，上面三个，还有一个initial 元素：以字符串的形式设置表单字段的初始值，如果没有设置该属性，则是基本类型为0，如果是对象则为null。可有可无。如下所示：<br />&lt;form-beans&gt;<br />　　&lt;form-bean <br />　　　　　　name="Loign"<br />　　　　　　type="com.ha.login"&gt;<br />　　　　　&lt;form-property name="ok"  type="java.lang.String"/&gt;<br />　　　　　&lt;form-property name="oks"  type="java.lang.String"/&gt;<br />　　　　　&lt;form-property name="okss"  type="java.lang.Integer" initial="20"/&gt;<br />　　&lt;/form-bean&gt;<br />&lt;/form-beans&gt;</p><p><strong><font color="#ff0000"> 3. global-exceptions元素</font></strong><br />　　该元素主要配置异常处理，它的exception子元素代表全局的异常配置。struts采取配置的方式来处理异常。它用来设置java异常和异常处理类org.apache.struts.action.ExceptionHandler之间的映射。它有七个属性，如下所示：<br />　　1. className：指定和exception元素对应的配置类，默认为：org.apache.struts.config.ExceptionConfig。可有可无。<br />　　2. Handler：指定异常得理类，默认为：org.apache.struts.action.ExceptionHandler。可有可无<br />　　3. key：指定在Resource Bundle中描述该异常的消息key<br />　　4. path：指定当异常发生时的转发路径。<br />　　5. scope：指定ActionMessages实例的存放范围，可选值包括：request和session，默认为request。可有可无。<br />　　6. type：指定所需处理异常类的名字，必须。<br />　　7. bundle：指定Resource Bundle<br />如下所示：<br />&lt;global-exceptions&gt;<br />　　&lt;exception <br />　　　　　　key="global.error.invalidlogin"<br />　　　　　　path="/error.jsp"<br />　　　　　　scope="request"<br />　　　　　　type="com.hn.tree"<br />　　/&gt;<br />&lt;/global-exceptions&gt;</p><p><font color="#ff0000"><strong> 4. global-forwards元素<br /></strong></font>　　该元素主要用来声明全局的转发关系，它具有以下四个属性：<br />　　1. className：和forward元素对应的配置类，默认为：org.apache.struts.action.ActionForward。可有可无。<br />　　2. contextRelative：此项为true时，表时path属性以＂/＂开头，相对于当前上下文的URL，默认为false．可有可无。　<br />　　3. name：转发路径的逻辑名．必填。<br />　　4. path：转发或重定向的URL，当contextRelative=false时，URL路径相对于当前应用（application），当为ture时，表示URL路径相对于当前上下文（context）。<br />　　5.  redirect：当此项为ture时，表示执行重定向操作。当此项为false时表示转向操作。默认为false。<br />如下所示：<br />&lt;global-forwards&gt;<br />　　&lt;forward  name="forms1"  path="/a.do"/&gt;<br />　　&lt;forward  name="forms2"  path="/nb.jsp"/&gt;<br />&lt;global-forwards&gt;</p><p><font color="#ff0000"><strong> 5. action-mappings元素</strong></font><br />　　描述从特定的请求路径到相应的Action类的映射。它具有以下几个属性：<br />　　1. attribute：设置和Action关联的ActionForm Bean在request和session范围内的key。如：Form Bean存在于request范围内，此项设为“myBenas”，则在request.getAttribute("myBenas")就可以返回该Bean的实例。<br />　　2. classsName：和action元素对应的配置元素，默认为：org.apache.struts.action.ActionMapping.<br />　　3. forward：转发的URL路径。<br />　　4. include：指定包含的URL路径。<br />　　5. input：输入表单的URL路径，当表单验证失败时，将把请求转发到该URL。<br />　　6. name：指定和Action关联的Action FormBean的名字，该名字必须在Form-Bean定义过。<br />　　7. path：指定访问Action的路径，以“/”开头，无扩展名。<br />　　8. parameter：指定Actgion的配置参数，在Action类的execute()方法中，可以调用ActionMapping对象的getParameter()方法来读取该配置参数。<br />　　9. roles：指定允许调用该Action的安全角色，多个角色之间用，隔开，在处理请求时，RequestProcessor会根据该配置项来决定用户是否有权限调用Action权限。<br />　　10. scope：指定ActionForm Bean的存在范围，可选取为request和session，默认为session。<br />　　11. type：指定Action类的完整类名。<br />　　12. unknown：如果此项为true，表示可以处理用户发出的所有无效的Action URL，默认为false；<br />　　13. validate：指定是否要调用Action FormBean的validate方法，默认值为ture.<br />注：forward、include、type属性只能选中其中一项。<br />如下：<br />&lt;action path="/search"<br />　　　　type="zxj.okBean"<br />　　　　name="a1"<br />　　　　scope="request"<br />　　　　validate="true"<br />　　　　input="/b.jsp"&gt;<br />　　&lt;forward name="tig" path="/aa.jsp"/&gt;<br />&lt;/action&gt;<br />注：此中的forward是指局部的转发路径。global-forwards表示全局的转发路径。</p><p><font color="#ff0000"><strong> 6. controller元素<br /></strong></font>　　该元素用于配置ActionServlet。它具有以下属性。<br />　　1. bufferSize：指定上载文件的输入缓冲大小，可选，默认为4096<br />　　2. className：指定和controller元素对应的配置类，默认为org.apache.struts.config.ControllerConfig<br />　　3. conentType：字符编码，如果在Action和JSP网页中设置了，则覆盖该设置。<br />　　4. locale：指定是否把Locale对象保存到当前用户的session中，默认值为false.<br />　　5. processorClass：指定负责请求的java类完整路径。<br />　　6. tempDir：指定处理文件的临时工作目录，如果此项没有设置，将采用Servlet容器为web应用分配的临时工作目录。<br />　　7. nochache：如果为true：在响应结果中将加入特定的头参数：Pragma,Cache-Control和Expise，防止页面被保存在客户端的浏览器中，默认为false<br />如下：<br />&lt;controller<br />　　contentType="text/html;charset="UTF-8""<br />　　locale="true"<br />　　processorClass="con.ok"/&gt;</p><p><font color="#ff0000"><strong> 7. message-resources元素</strong></font><br />　　主要配置本地化消息文本，它具有以下属性。<br />　　1. className：和message-resources元素对应的配置类，默认为org.apache.struts.config.MessageResourcesConfig。<br />　　2. factory：指定消息资源的工厂类，默认为：org.apache.struts.util.PropertyMessageResourcesFactory类<br />　　3. key：指定Resource Bundle存放的ServletContext对象中时采用的属性Key，默认由Globals.MESSAGES_KEY定义的字符串常量，只允许一个Resource Bundle采用默认的属性Key。<br />　　4. null：指定MessageSources类如何处理未知消息的key，如果为true，则返回空字符串，如果为false，则返回相关字串，默认为false<br />　　5. prameter：指定MessageSources的资源文件名，如果为：a.b.ApplicationResources，则实际对应的文件路径为：WEB-INF/classes/a/b/ApplicationResources.properties.<br />如：<br />&lt;message-resources null="false" parameter="defaultResource"/&gt;<br />&lt;message-resources key="num1" null="false" parameter="test"/&gt;<br />访问为：<br />&lt;bean:message  key="zxj"/&gt;<br />&lt;bean:message  key="zxj"  bundle="num1"/&gt;<br />其中，zxj表法，messagesource资源文件中的一个字符串。</p><p><font color="#ff0000"><strong> 8. plugin-in元素</strong></font><br />　　配置Struts的插件，属性如下：<br />　　1. className：指定的Struts插件类，必须实现org.apache.struts.action.PlugiIn接口。如：<br />&lt;plug-in<br />　　className="a.b.c."&gt;<br />　　&lt;set-property property="xxx" value="/WEB-INF/aa.xml"  /&gt;<br />&lt;/plug-in&gt;</p><p> 后记，多模块的配置，可以供多个应用应用不同的struts-config.xml</p><img src ="http://www.blogjava.net/19851985lili/aggbug/98470.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-02-07 08:25 <a href="http://www.blogjava.net/19851985lili/articles/98470.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Sunny框架的AOP- -</title><link>http://www.blogjava.net/19851985lili/articles/97646.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Fri, 02 Feb 2007 12:35:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/97646.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/97646.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/97646.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/97646.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/97646.html</trackback:ping><description><![CDATA[
		<p>AOP最近被炒得非常的热，各种各样的AOP框架层出不穷。在AOP方面，我无意于去做一个完整的框架，支持各种AOP的特性，其实从实际我们项目经历上来分析。可以得出，在绝大多数情况下，AOP的很多高级特性是用不上的，比如静态代码注入。为类添加运行时的构造函数，改变类的继承关系等等。其实我们最常用的还是拦截器，关于这个话题，可能是比较有争议的，毕竟每个人的立场和观点是不同的。针对我目前所涉及的应用域来讲，一个完整的拦截器框架已经足够了。</p>
		<p>一个典型的拦截器框架至少应该包括三个部分：</p>
		<p>1、可声明的拦截点；</p>
		<p>2、灵活的拦截器序列；</p>
		<p>3、对拦截对象的代理封装；</p>
		<p>拦截点可以基于具体的应用环境去灵活申明，这点可以参考Cocoon里的Pipeline。这里不用多说，大家看了后续的拦截点的定义代码就一目了然了。关于拦截器的具体定义，也在随后的部分提供，这里首先探讨被拦截对象的代理的实现机制。</p>
		<p>所谓代理，就是对被拦截对象的一个包装，通过该包装类，可以非常自然的对被包装对象添加我们自定义的行为，比如调用拦截器进行拦截操作。</p>
		<p>我们来看AOP的代理接口的定义：</p>
		<table cellspacing="0" cellpadding="0" background="" border="0">
				<tbody>
						<tr>
								<td class="code">
										<br />
										<font color="#0000ff">package</font>
										<font color="#000000">org.sunny.core.aop;</font>
										<br />
										<br />
										<font color="#0000ff">import</font>
										<font color="#000000">java.lang.reflect.InvocationHandler;</font>
										<br />
										<font color="#0000ff">import</font>
										<font color="#000000">org.sunny.exception.SunnyException;</font>
										<br />
										<font color="#0000ff">import</font>
										<font color="#000000">java.util.List;</font>
										<br />
										<br />
										<font color="#008000">/**</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">该类是一个拦截器的处理中心，所有的业务逻辑的方法调用都会被该类拦截。通过这种机制，</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">在这里就可以统一的实现如下的过滤器：</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">1、方法级鉴权；</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">2、业务日志；</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">3、静态属性过滤。</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">等等功能。此外，你可以实现自己的拦截器，通过如下的接口：</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">&lt; code&gt;</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">&lt; br&gt;org.sunny.core.aop.interceptor.Interceptor</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">&lt; /code&gt;</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">并在全局配置文件里完成拦截器的配置。该拦截器就可以生效。</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">&lt; p&gt;Copyright:</font>
										<font color="#008000">Copyright</font>
										<font color="#008000">(c)</font>
										<font color="#008000">2005&lt; /p&gt;</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">&lt; p&gt;Company:</font>
										<font color="#008000">Sunny虚拟开发组&lt; /p&gt;</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">@author</font>
										<font color="#008000">高雁冰</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">@version</font>
										<font color="#008000">1.0</font>
										<br />
										<font color="#008000">*/</font>
										<br />
										<font color="#0000ff">public</font>
										<font color="#000000">interface</font>
										<font color="#000000">AopProxy</font>
										<br />
										<font color="#000000">{</font>
										<br />    <font color="#008000">/**</font><br />    <font color="#008000">*</font><font color="#008000">设置该<a name="baidusnap0"></a><b style="COLOR: black; BACKGROUND-COLOR: #ffff66">动态代理</b>需要代理的对象</font><br />    <font color="#008000">*</font><font color="#008000">@param</font><font color="#008000">delegate</font><font color="#008000">具体被代理的对象（实例）</font><br />    <font color="#008000">*/</font><br />    <font color="#0000ff">public</font><font color="#0000ff">void</font><font color="#000000">setDelegate(Object</font><font color="#000000">delegate);</font><br />    <br />    <font color="#008000">/**</font><br />    <font color="#008000">*</font><font color="#008000">获取通过该<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">动态代理</b>处理后的业务代理对象</font><br />    <font color="#008000">*</font><font color="#008000">@return</font><font color="#008000">该代理处理后的代理业务对象</font><br />    <font color="#008000">*</font><font color="#008000">@throws</font><font color="#008000">SunnyException</font><br />    <font color="#008000">*/</font><br />    <font color="#0000ff">public</font><font color="#ff0000">Object</font><font color="#000000">getProxy()</font><font color="#0000ff">throws</font><font color="#000000">SunnyException;</font><br />    <br />    <font color="#008000">/**</font><br />    <font color="#008000">*</font><font color="#008000">设置该代理类需要处理的所有拦截器。</font><br />    <font color="#008000">*</font><font color="#008000">@param</font><font color="#008000">interceptors</font><font color="#008000">拦截器集合</font><br />    <font color="#008000">*/</font><br />    <font color="#0000ff">public</font><font color="#0000ff">void</font><font color="#000000">setInterceptors(List</font><font color="#000000">interceptors);</font><br />    <br /><font color="#000000">}</font></td>
						</tr>
				</tbody>
		</table>
		<p>－－－－－－－－－－－－－－－－－－－－－－－－－－－－－</p>
		<p>
				<font color="#ff0099">Sunny目前提供了两种代理的实现方式：</font>
		</p>
		<p>
				<font color="#ff0099">1、基于Java的<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">动态代理</b>，原理大家可以到java.sun.com站点上去研究一番；</font>
		</p>
		<p>
				<font color="#ff0099">2、基于Cglib的字节码映射的方式，这点大家也可以关注Cglig来找到具体的答案。</font>
		</p>
		<p>
				<font color="#ff0099">需要说明的是，这两种代理各自有不同的应用域，某些情况是不能通用的。基于Java的<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">动态代理</b>要求被代理对象必须基于接口编程，即每个被代理对象有一个明确的接口。而基于Cglib的代理则不在此限制。</font>
		</p>
		<p>
				<font color="#ff0099">下面贴出源代码：</font>
		</p>
		<p>
				<font color="#000000">－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－</font>
		</p>
		<table cellspacing="0" cellpadding="0" background="" border="0">
				<tbody>
						<tr>
								<td class="code">
										<br />
										<font color="#0000ff">package</font>
										<font color="#000000">org.sunny.core.aop;</font>
										<br />
										<br />
										<font color="#008000">//import</font>
										<font color="#008000">java.lang.reflect.*;</font>
										<br />
										<font color="#0000ff">import</font>
										<font color="#000000">org.sunny.exception.SunnyException;</font>
										<br />
										<font color="#0000ff">import</font>
										<font color="#000000">org.sunny.cfg.PltMessage;</font>
										<br />
										<font color="#0000ff">import</font>
										<font color="#000000">org.sunny.core.aop.interceptor.InterceptorUtil;</font>
										<br />
										<font color="#0000ff">import</font>
										<font color="#000000">java.lang.reflect.InvocationHandler;</font>
										<br />
										<font color="#0000ff">import</font>
										<font color="#000000">java.lang.reflect.Method;</font>
										<br />
										<font color="#0000ff">import</font>
										<font color="#000000">java.util.List;</font>
										<br />
										<br />
										<font color="#008000">/**</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">采用Java<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">动态代理</b>的方式<a name="baidusnap2"></a><b style="COLOR: black; BACKGROUND-COLOR: #99ff99">实现拦截器</b>机制。</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">Copyright:</font>
										<font color="#008000">Copyright</font>
										<font color="#008000">(c)</font>
										<font color="#008000">2005</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">&lt; p&gt;Company:</font>
										<font color="#008000">Sunny虚拟开发组&lt; /p&gt;</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">@author</font>
										<font color="#008000">高雁冰({@link</font>
										<font color="#008000">mailto:haiger@163.com})</font>
										<br />
										<font color="#008000">*</font>
										<font color="#008000">@version</font>
										<font color="#008000">1.0</font>
										<br />
										<font color="#008000">*/</font>
										<br />
										<font color="#0000ff">public</font>
										<font color="#0000ff">class</font>
										<font color="#000000">DynamicProxy</font>
										<font color="#000000">implements</font>
										<font color="#000000">AopProxy,InvocationHandler</font>
										<br />
										<font color="#000000">{</font>
										<br />    <font color="#0000ff">private</font><font color="#ff0000">Object</font><font color="#000000">delegate;</font><font color="#008000">//具体代理的业务逻辑对象</font><br />    <font color="#0000ff">private</font><font color="#000000">InterceptorUtil</font><font color="#000000">interceptorUtil;</font><br />    <br />    <font color="#008000">/**</font><br />    <font color="#008000">*</font><font color="#008000">默认构造函数，由于该<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">动态代理</b>的实现需要通过Class.newInstance来调用（被框架），所以需要</font><br />    <font color="#008000">*</font><font color="#008000">提供该默认构造函数，需要注意的是。在这之后，需要调用该类的setDelegate方法来具体设置该</font><br />    <font color="#008000">*</font><font color="#008000">类具体代理哪个对象。</font><br />    <font color="#008000">*/</font><br />    <font color="#0000ff">public</font><font color="#000000">DynamicProxy()</font><br />    <font color="#000000">{</font><br />        <font color="#008000">//...</font><br />    <font color="#000000">}</font><br />    <br />    <br />    <font color="#008000">/**</font><br />    <font color="#008000">*</font><font color="#008000">IOC机制，通过运行时传入需要代理的业务逻辑对象。</font><br />    <font color="#008000">*</font><font color="#008000">@param</font><font color="#008000">delegate</font><font color="#008000">需要代理的业务逻辑对象</font><br />    <font color="#008000">*/</font><br />    <font color="#0000ff">public</font><font color="#000000">DynamicProxy(Object</font><font color="#000000">delegate)</font><br />    <font color="#000000">{</font><br />        <font color="#000000">setDelegate(delegate);</font><br />    <font color="#000000">}</font><br />    <br />    <font color="#008000">/**</font><br />    <font color="#008000">*</font><font color="#008000">设置该<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">动态代理</b>需要代理的对象</font><br />    <font color="#008000">*</font><font color="#008000">@param</font><font color="#008000">delegate</font><font color="#008000">具体被代理的对象（实例）</font><br />    <font color="#008000">*/</font><br />    <font color="#0000ff">public</font><font color="#0000ff">void</font><font color="#000000">setDelegate(Object</font><font color="#000000">delegate)</font><br />    <font color="#000000">{</font><br />        <font color="#000000">this.delegate</font><font color="#000000">=</font><font color="#000000">delegate;</font><br />    <font color="#000000">}</font><br />    <br />    <font color="#008000">/**</font><br />    <font color="#008000">*</font><font color="#008000">设置该代理类需要处理的所有拦截器。</font><br />    <font color="#008000">*</font><font color="#008000">@param</font><font color="#008000">interceptors</font><font color="#008000">拦截器集合</font><br />    <font color="#008000">*/</font><br />    <font color="#0000ff">public</font><font color="#0000ff">void</font><font color="#000000">setInterceptors(List</font><font color="#000000">interceptors)</font><br />    <font color="#000000">{</font><br />        <font color="#000000">interceptorUtil</font><font color="#000000">=</font><font color="#0000ff">new</font><font color="#000000">InterceptorUtil(interceptors);</font><br />    <font color="#000000">}</font><br />    <br />    <font color="#008000">/**</font><br />    <font color="#008000">*</font><font color="#008000">获取通过该<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">动态代理</b>处理后的业务代理对象</font><br />    <font color="#008000">*</font><font color="#008000">@return</font><font color="#008000">该代理处理后的代理业务对象</font><br />    <font color="#008000">*</font><font color="#008000">@throws</font><font color="#008000">SunnyException</font><br />    <font color="#008000">*/</font><br />    <font color="#0000ff">public</font><font color="#ff0000">Object</font><font color="#000000">getProxy()</font><font color="#0000ff">throws</font><font color="#000000">SunnyException</font><br />    <font color="#000000">{</font><br />        <font color="#000000">if(null</font><font color="#000000">==</font><font color="#000000">delegate)</font><br />        <font color="#000000">{</font><br />            <font color="#0000ff">throw</font><font color="#0000ff">new</font><font color="#000000">SunnyException(PltMessage.getInstance().getMessage(</font><br />            <font color="#000000">"</font><font color="#c0c0c0">BLA_IMPL_DELEGATE_NOT_SET</font><font color="#000000">"));</font><br />        <font color="#000000">}</font><br />        <br />        <font color="#008000">//构造该业务逻辑的包装类</font><br />        <font color="#ff0000">Object</font><font color="#000000">proxy</font><font color="#000000">=</font><font color="#000000">java.lang.reflect.Proxy.newProxyInstance</font><font color="#000000">(</font><br />        <font color="#000000">delegate.getClass().getClassLoader(),</font><br />        <font color="#000000">delegate.getClass().getInterfaces()</font><br />        <font color="#000000">,</font><font color="#000000">this);</font><br />        <br />        <font color="#0000ff">return</font><font color="#000000">proxy;</font><br />    <font color="#000000">}</font><br />    <br />    <br />    <font color="#008000">/**</font><br />    <font color="#008000">*</font><font color="#008000">拦截器的方法实现，该方法调用代理的业务逻辑的方法。</font><br />    <font color="#008000">*</font><font color="#008000">@param</font><font color="#008000">proxy</font><font color="#008000">被代理的类</font><br />    <font color="#008000">*</font><font color="#008000">@param</font><font color="#008000">method</font><font color="#008000">被调用的业务方法</font><br />    <font color="#008000">*</font><font color="#008000">@param</font><font color="#008000">args</font><font color="#008000">调用业务方法的输入参数</font><br />    <font color="#008000">*</font><font color="#008000">@return</font><font color="#008000">Object</font><font color="#008000">业务方法调用的返回值</font><br />    <font color="#008000">*</font><font color="#008000">@throws</font><font color="#008000">Throwable</font><font color="#008000">业务方法抛出的异常，该异常目前在外围系统去捕获的时候需要一些</font><br />    <font color="#008000">*</font><font color="#008000">技巧，你应该这样（用getCause()方法）来捕获原始抛出的异常（范例代码）</font><br />    <font color="#008000">*</font><font color="#008000">&lt; code&gt;</font><br />    <font color="#008000">*</font><font color="#008000">&lt; br&gt;try</font><br />    <font color="#008000">*</font><font color="#008000">&lt; br&gt;{</font><br />    <font color="#008000">*</font><font color="#008000">&lt; br&gt;</font><font color="#008000">...</font><br />    <font color="#008000">*</font><font color="#008000">&lt; br&gt;}catch(Throwable</font><font color="#008000">tb)</font><br />    <font color="#008000">*</font><font color="#008000">&lt; br&gt;{</font><br />    <font color="#008000">*</font><font color="#008000">&lt; br&gt;</font><font color="#008000">System.out.println(tb.getCause().getMessage());</font><br /><font color="#008000">*</font><font color="#008000">&lt; br&gt;}</font><br /><font color="#008000">*</font><font color="#008000">&lt; /code&gt;</font><font color="#008000">岁</font><br /><font color="#008000">*/</font><br /><font color="#0000ff">public</font><font color="#ff0000">Object</font><font color="#000000">invoke(Object</font><font color="#000000">proxy,</font><font color="#000000">Method</font><font color="#000000">method,</font><font color="#000000">Object[]</font><font color="#000000">args)</font><font color="#0000ff">throws</font><br /><font color="#000000">Throwable</font><br /><font color="#000000">{</font><br />    <font color="#008000">//调用所有的拦截器，对方法行为进行拦截操作</font><br />    <font color="#000000">interceptorUtil.before(delegate,method,args);</font><br />    <br />    <font color="#008000">//具体业务逻辑方法的调用</font><br />    <font color="#ff0000">Object</font><font color="#000000">result</font><font color="#000000">=</font><font color="#000000">null;</font><br />    <font color="#0000ff">try</font><br />    <font color="#000000">{</font><br />        <font color="#000000">result</font><font color="#000000">=</font><font color="#000000">method.invoke(delegate,</font><font color="#000000">args);</font><br />    <font color="#000000">}</font><font color="#0000ff">catch</font><font color="#000000">(Throwable</font><font color="#000000">e)</font><br />    <font color="#000000">{</font><br />        <font color="#008000">//对日志进行拦截操作</font><br />        <font color="#000000">interceptorUtil.exception(delegate,method,args,e);</font><br />    <font color="#000000">}</font><br />    <br />    <font color="#008000">//业务逻辑调用完成，对结果进行拦截操作</font><br />    <font color="#000000">interceptorUtil.after(delegate,method,args,result);</font><br />    <br />    <font color="#0000ff">return</font><font color="#000000">result;</font><br /><font color="#000000">}</font><br /><font color="#000000">}</font><br /></td>
						</tr>
				</tbody>
		</table>－－－－－－－－－－－－－－－Cglib代理类－－－－－－－－－－－－－－－－－－－－ 
<table cellspacing="0" cellpadding="0" background="" border="0"><tbody><tr><td class="code"><br /><font color="#0000ff">package</font><font color="#000000">org.sunny.core.aop;</font><br /><br /><font color="#0000ff">import</font><font color="#000000">java.lang.reflect.Method;</font><br /><font color="#0000ff">import</font><font color="#000000">net.sf.cglib.proxy.MethodInterceptor;</font><br /><font color="#0000ff">import</font><font color="#000000">net.sf.cglib.proxy.Enhancer;</font><br /><font color="#0000ff">import</font><font color="#000000">net.sf.cglib.proxy.MethodProxy;</font><br /><font color="#0000ff">import</font><font color="#000000">org.sunny.exception.SunnyException;</font><br /><font color="#0000ff">import</font><font color="#000000">org.sunny.cfg.PltMessage;</font><br /><font color="#0000ff">import</font><font color="#000000">org.sunny.core.aop.interceptor.InterceptorUtil;</font><br /><font color="#0000ff">import</font><font color="#000000">java.util.List;</font><br /><font color="#008000">/**</font><br /><font color="#008000">*</font><font color="#008000">采用Cglib代理的方式<b style="COLOR: black; BACKGROUND-COLOR: #99ff99">实现拦截器</b>机制。需要注意的是：</font><br /><font color="#008000">*</font><font color="#008000">由于目前EJB的实现方式是采用静态－动态Stub的实现。Cgblib在这种对象的代理生成上有一</font><br /><font color="#008000">*</font><font color="#008000">些问题，（EJB的Object的Stub是一个Finnal的类，不能完成代理），因此，如果系统采用EJB作为</font><br /><font color="#008000">*</font><font color="#008000">业务逻辑，则拦截器引擎只能使用：</font><br /><font color="#008000">*</font><font color="#008000">&lt; code&gt;</font><br /><font color="#008000">*</font><font color="#008000">org.sunny.blaccess.impl.DynanicProxyReactor</font><br /><font color="#008000">*</font><font color="#008000">&lt; /code&gt;</font><br /><font color="#008000">*</font><font color="#008000">Copyright:</font><font color="#008000">Copyright</font><font color="#008000">(c)</font><font color="#008000">2005</font><br /><font color="#008000">*</font><font color="#008000">&lt; p&gt;Company:</font><font color="#008000">Sunny虚拟开发组&lt; /p&gt;</font><br /><font color="#008000">*</font><font color="#008000">@author</font><font color="#008000">高雁冰({@link</font><font color="#008000">mailto:haiger@163.com})</font><br /><font color="#008000">*</font><font color="#008000">@version</font><font color="#008000">1.5</font><br /><font color="#008000">*/</font><br /><br /><font color="#0000ff">public</font><font color="#0000ff">class</font><font color="#000000">CglibProxy</font><font color="#000000">implements</font><font color="#000000">MethodInterceptor,AopProxy</font><br /><font color="#000000">{</font><br />    <font color="#0000ff">private</font><font color="#ff0000">Object</font><font color="#000000">delegate;</font><font color="#008000">//被代理的业务对象</font><br />    <font color="#0000ff">private</font><font color="#000000">Enhancer</font><font color="#000000">enhancer=new</font><font color="#000000">Enhancer();</font><br />    <font color="#0000ff">private</font><font color="#000000">InterceptorUtil</font><font color="#000000">interceptorUtil;</font><br />    <br />    <font color="#008000">/**</font><br />    <font color="#008000">*</font><font color="#008000">设置该<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">动态代理</b>需要代理的对象</font><br />    <font color="#008000">*</font><font color="#008000">@param</font><font color="#008000">delegate</font><font color="#008000">具体被代理的对象（实例）</font><br />    <font color="#008000">*/</font><br />    <font color="#0000ff">public</font><font color="#0000ff">void</font><font color="#000000">setDelegate(Object</font><font color="#000000">delegate)</font><br />    <font color="#000000">{</font><br />        <font color="#000000">this.delegate</font><font color="#000000">=</font><font color="#000000">delegate;</font><br />    <font color="#000000">}</font><br />    <br />    <font color="#008000">/**</font><br />    <font color="#008000">*</font><font color="#008000">设置该代理类需要处理的所有拦截器。</font><br />    <font color="#008000">*</font><font color="#008000">@param</font><font color="#008000">interceptors</font><font color="#008000">拦截器集合</font><br />    <font color="#008000">*/</font><br />    <font color="#0000ff">public</font><font color="#0000ff">void</font><font color="#000000">setInterceptors(List</font><font color="#000000">interceptors)</font><br />    <font color="#000000">{</font><br />        <font color="#000000">interceptorUtil</font><font color="#000000">=</font><font color="#0000ff">new</font><font color="#000000">InterceptorUtil(interceptors);</font><br />    <font color="#000000">}</font><br />    <br />    <font color="#008000">/**</font><br />    <font color="#008000">*</font><font color="#008000">获取通过该<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">动态代理</b>处理后的业务代理对象</font><br />    <font color="#008000">*</font><font color="#008000">@return</font><font color="#008000">该代理处理后的代理业务对象</font><br />    <font color="#008000">*</font><font color="#008000">@throws</font><font color="#008000">SunnyException</font><br />    <font color="#008000">*/</font><br />    <font color="#0000ff">public</font><font color="#ff0000">Object</font><font color="#000000">getProxy()</font><font color="#0000ff">throws</font><font color="#000000">SunnyException</font><br />    <font color="#000000">{</font><br />        <font color="#000000">if(null</font><font color="#000000">==</font><font color="#000000">delegate)</font><br />        <font color="#000000">{</font><br />            <font color="#0000ff">throw</font><font color="#0000ff">new</font><font color="#000000">SunnyException(PltMessage.getInstance().getMessage(</font><br />            <font color="#000000">"</font><font color="#c0c0c0">BLA_IMPL_DELEGATE_NOT_SET</font><font color="#000000">"));</font><br />        <font color="#000000">}</font><br />        <font color="#000000">if(-1</font><font color="#000000">!=</font><font color="#000000">delegate.getClass().getName().indexOf("</font><font color="#c0c0c0">$$</font><font color="#000000">"))</font><br />        <font color="#000000">{</font><br />            <font color="#000000">enhancer.setSuperclass(delegate.getClass().getSuperclass());</font><br />            <font color="#000000">}else</font><br />            <font color="#000000">{</font><br />                <font color="#000000">enhancer.setSuperclass(delegate.getClass());</font><br />            <font color="#000000">}</font><br />            <font color="#000000">enhancer.setCallback(this);</font><br />            <font color="#0000ff">return</font><font color="#000000">enhancer.create();</font><br />        <font color="#000000">}</font><br />        <br />        <font color="#008000">/**</font><br />        <font color="#008000">*</font><font color="#008000">实现对业务逻辑方法的具体拦截操作。在该操作里，可以在业务逻辑方法调用前后或者抛出异常的</font><br />        <font color="#008000">*</font><font color="#008000">时候添加自己的控制，这里则选择执行系统配置的拦截器。</font><br />        <font color="#008000">*</font><font color="#008000">@param</font><font color="#008000">o</font><font color="#008000">被代理对象</font><br />        <font color="#008000">*</font><font color="#008000">@param</font><font color="#008000">method</font><font color="#008000">访问的具体方法</font><br />        <font color="#008000">*</font><font color="#008000">@param</font><font color="#008000">args</font><font color="#008000">方法输入参数</font><br />        <font color="#008000">*</font><font color="#008000">@param</font><font color="#008000">proxy</font><font color="#008000">方法代理</font><br />        <font color="#008000">*</font><font color="#008000">@return</font><font color="#008000">方法执行结果</font><br />        <font color="#008000">*</font><font color="#008000">@throws</font><font color="#008000">java.lang.Throwable</font><br />        <font color="#008000">*/</font><br />        <font color="#0000ff">public</font><font color="#ff0000">Object</font><font color="#000000">intercept(Object</font><font color="#000000">o,Method</font><font color="#000000">method,Object[]</font><font color="#000000">args,MethodProxy</font><font color="#000000">proxy)</font><br />        <font color="#0000ff">throws</font><font color="#000000">Throwable</font><br />        <font color="#000000">{</font><br />            <font color="#008000">//调用所有的拦截器，对方法行为进行拦截操作</font><br />            <font color="#000000">interceptorUtil.before(delegate,method,args);</font><br />            <br />            <font color="#008000">//具体业务逻辑方法的调用</font><br />            <font color="#ff0000">Object</font><font color="#000000">result</font><font color="#000000">=</font><font color="#000000">null;</font><br />            <font color="#0000ff">try</font><br />            <font color="#000000">{</font><br />                <font color="#000000">result</font><font color="#000000">=</font><font color="#000000">proxy.invokeSuper(o,args);</font><br />            <font color="#000000">}</font><font color="#0000ff">catch</font><font color="#000000">(Throwable</font><font color="#000000">e)</font><br />            <font color="#000000">{</font><br />                <font color="#008000">//对日志进行拦截操作</font><br />                <font color="#000000">interceptorUtil.exception(delegate,method,args,e);</font><br />            <font color="#000000">}</font><br />            <br />            <font color="#008000">//业务逻辑调用完成，对结果进行拦截操作</font><br />            <font color="#000000">interceptorUtil.after(delegate,method,args,result);</font><br />            <br />            <font color="#0000ff">return</font><font color="#000000">result;</font><br />        <font color="#000000">}</font><br />        <br /></td></tr></tbody></table><img src ="http://www.blogjava.net/19851985lili/aggbug/97646.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-02-02 20:35 <a href="http://www.blogjava.net/19851985lili/articles/97646.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>初探quartz scheduler </title><link>http://www.blogjava.net/19851985lili/articles/93515.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Fri, 12 Jan 2007 11:32:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/93515.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/93515.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/93515.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/93515.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/93515.html</trackback:ping><description><![CDATA[quartz是opensymphony提供的用来做SCHEDULE的框架 <br /><br />在spring中通过org.springframework.scheduling.quartz.SchedulerFactoryBean来获得Schedule类 <br /><table cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><font color="#555555"><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></pre></font></td><td valign="top" align="left" bgcolor="#ffffff"><pre>	&lt;bean id=<font color="#00ed0">"quartzSchedulerFactory"</font> class=<font color="#00ed0">"org.springframework.scheduling.quartz.SchedulerFactoryBean"</font> scope=<font color="#00ed0">"singleton"</font>&gt;
		&lt;!-- set quartz scheduler factory configuration location --&gt;
		&lt;!-- &lt;property name=<font color="#00ed0">"configLocation"</font> value=<font color="#00ed0">""</font> /&gt; --&gt;
		&lt;!-- 系统会在启动时加载 --&gt;
		&lt;property name=<font color="#00ed0">"autoStartup"</font> value=<font color="#00ed0">"true"</font> /&gt;
	&lt;/bean&gt;
	&lt;bean id=<font color="#00ed0">"taskManage"</font> class=<font color="#00ed0">"com.sumit.task.TaskManage"</font> scope=<font color="#00ed0">"singleton"</font>&gt;
		&lt;property name=<font color="#00ed0">"taskDAO"</font> ref=<font color="#00ed0">"taskDao"</font> /&gt;
		<font color="red">
		&lt;property name=<font color="#00ed0">"scheduler"</font> ref=<font color="#00ed0">"quartzSchedulerFactory"</font> /&gt;
		</font>
	&lt;/bean&gt;
</pre></td></tr></tbody></table><br /><br /><br />QUARTZ中有Job与Trigger两种概念 <br /><br />一.Job详细描述具体的任务运行代码实现 <br />1.新增一个任务到scheduler <br /><br /><table cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><font color="#555555"><pre>1<br />2<br />3<br />4<br />5<br />6<br /></pre></font></td><td valign="top" align="left" bgcolor="#ffffff"><pre>JobDetail job = <font color="#00a000"><b>new</b></font> JobDetail(taskName, Scheduler.DEFAULT_GROUP,DefaultQuartzJob.class);
JobDataMap jobDataMap = job.getJobDataMap();
<font color="#0d00e0">//根据PUT不同的TASK而运行不同的任务</font>
jobDataMap.put(<font color="#00ed0">"Task"</font>, task);
job.setDurability(<font color="#00a000"><b>true</b></font>);
scheduler.addJob(job, <font color="#00a000"><b>true</b></font>);
</pre></td></tr></tbody></table><br /><br /><br />==&gt;DefaultQuartzJob <br /><br /><table cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><font color="#555555"><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br /></pre></font></td><td valign="top" align="left" bgcolor="#ffffff"><pre><font color="#00a000"><b>public</b></font><font color="#00a000"><b>class</b></font> DefaultQuartzJob <font color="#00a000"><b>implements</b></font> Job <font color="#00a000">{</font>
 
	<font color="#00a000"><b>private</b></font><font color="#00a000"><b>static</b></font> Logger logger = Logger.getLogger(DefaultQuartzJob.class);
 
	<font color="#00a000"><b>public</b></font><font color="#00a000"><b>void</b></font> execute(JobExecutionContext ctx) <font color="#00a000"><b>throws</b></font> JobExecutionException <font color="#00a000">{</font>
		JobDataMap jobDataMap = ctx.getJobDetail().getJobDataMap();
		TaskTO task = (TaskTO) jobDataMap.get(<font color="#00ed0">"Task"</font>);
 
		Task entryTask = task.getEntryTask();
 
		<font color="#00a000"><b>if</b></font> (entryTask == <font color="#00a000"><b>null</b></font>) <font color="#00a000">{</font>
			logger
					.error(<font color="#00ed0">"Task "</font> + task.getName()
							+ <font color="#00ed0">" couldn't be initialized!"</font>);
			<font color="#00a000"><b>return</b></font>;
		<font color="#00a000">}</font>
 
		TaskContext taskContext = <font color="#00a000"><b>new</b></font> DefaultTaskContext();
 
		<font color="#0d00e0">// 将触发任务的Trigger中所有的参数添加到上下文中</font>
		JobDataMap triggerDataMap = ctx.getTrigger().getJobDataMap();
		String[] keys = triggerDataMap.getKeys();
		<font color="#00a000"><b>if</b></font> (keys != <font color="#00a000"><b>null</b></font>) <font color="#00a000">{</font><font color="#00a000"><b>for</b></font> (<font color="#00a000"><b>int</b></font> i = 0; i &lt; keys.length; i++) <font color="#00a000">{</font>
				Object obj = triggerDataMap.get(keys[i]);
				<font color="#00a000"><b>if</b></font> (obj <font color="#00a000"><b>instanceof</b></font> String[]) <font color="#00a000">{</font>
					String [] data=(String[]) obj;
					<font color="#00a000"><b>if</b></font>(data.length&gt;0)<font color="#00a000">{</font>
					taskContext.setParameter(keys[i], data[0]);
					<font color="#00a000">}</font><font color="#00a000">}</font><font color="#00a000"><b>else</b></font><font color="#00a000"><b>if</b></font>(obj <font color="#00a000"><b>instanceof</b></font> String)<font color="#00a000">{</font>
					taskContext.setParameter(keys[i], (String)obj);
				<font color="#00a000">}</font><font color="#00a000">}</font><font color="#00a000">}</font><font color="#00a000"><b>try</b></font><font color="#00a000">{</font><font color="#0d00e0">// 为任务时间执行次数加1</font>
			TaskManage tm = (TaskManage) triggerDataMap
					.get(TaskManage.TASKMANAGE_ATTRIBUTE_NAME);
			tm.addTriggerExecuteTimes(triggerDataMap
					.getString(TaskManage.TRIGGER_ATTRIBUTE_NAME));
		<font color="#00a000">}</font><font color="#00a000"><b>catch</b></font> (TaskException e) <font color="#00a000">{</font>
			logger.error(
					<font color="#00ed0">"catch exception while process task "</font> + task.getName(), e);
		<font color="#00a000">}</font><font color="#00a000"><b>try</b></font><font color="#00a000">{</font><font color="#0d00e0">//根据实例化不同的TASK而运行不同的任务</font>
			entryTask.process(taskContext);
		<font color="#00a000">}</font><font color="#00a000"><b>catch</b></font> (TaskException e) <font color="#00a000">{</font>
			logger.error(
					<font color="#00ed0">"catch exception while process task "</font> + task.getName(), e);
		<font color="#00a000">}</font><font color="#00a000">}</font><font color="#00a000">}</font></pre></td></tr></tbody></table><br />==&gt;TASK接口,继承它可以实现不同的任务实现 <br /><br /><table cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><font color="#555555"><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br /></pre></font></td><td valign="top" align="left" bgcolor="#ffffff"><pre><font color="#0d00e0">/**
 * 定时任务的基本接口
 */</font><font color="#00a000"><b>public</b></font><font color="#00a000"><b>interface</b></font> Task
<font color="#00a000">{</font>
 
	<font color="#0d00e0">/**
	 * 任务执行
	 * 
	 * @param request
	 *            请求参数
	 * @param response
	 *            返回参数
	 * @param cxt
	 * @roseuid 4535938002AC
	 */</font><font color="#00a000"><b>public</b></font><font color="#00a000"><b>void</b></font> process(TaskContext cxt) <font color="#00a000"><b>throws</b></font> TaskException;
 
	<font color="#0d00e0">/**
	 * 任务名称
	 * 
	 * @return java.lang.String
	 * @roseuid 453DB0AB01B5
	 */</font><font color="#00a000"><b>public</b></font> String getName();
<font color="#00a000">}</font></pre></td></tr></tbody></table><br /><br />2.从scheduler中删除一个任务 <br /><br /><table cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><font color="#555555"><pre>1<br /></pre></font></td><td valign="top" align="left" bgcolor="#ffffff"><pre>scheduler.deleteJob(taskName, Scheduler.DEFAULT_GROUP);
</pre></td></tr></tbody></table><br /><br /><br />二.Trigger定时器,任务与定时器是一对多的关系 <br />1.新建Trigger,初步分为CRONTRIGGER,SIMPLETRIGGER <br /><table cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><font color="#555555"><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br /></pre></font></td><td valign="top" align="left" bgcolor="#ffffff"><pre><font color="#00a000"><b>if</b></font> (TRIGGER_CRON.equals(triggerType)) <font color="#00a000">{</font><font color="#0d00e0">//创建CRONTRIGGER</font>
				trigger = <font color="#00a000"><b>new</b></font> CronTrigger(triggerName, Scheduler.DEFAULT_GROUP,
						taskName, Scheduler.DEFAULT_GROUP, validStartTime,
						validEndTime, triggerPattern);
				trigger.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING);
			<font color="#00a000">}</font><font color="#00a000"><b>else</b></font><font color="#00a000">{</font><font color="#0d00e0">//创建SIMPLETRIGGER</font>
				trigger = <font color="#00a000"><b>new</b></font> SimpleTrigger(triggerName,
						Scheduler.DEFAULT_GROUP, taskName,
						Scheduler.DEFAULT_GROUP, validStartTime, validEndTime,
						repeatCount, repeatInterval);
				trigger.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT);
			<font color="#00a000">}</font>
 
		<font color="#00a000"><b>try</b></font><font color="#00a000">{</font><font color="#0d00e0">//添加trigger到scheduler</font>
			scheduler.scheduleJob(trigger);
			logger.debug(<font color="#00ed0">"trigger "</font> + trigger.getName()
					+ <font color="#00ed0">" have been loaded to scheduler!"</font>);
		<font color="#00a000">}</font><font color="#00a000"><b>catch</b></font> (SchedulerException e) <font color="#00a000">{</font>
			logger.error(<font color="#00ed0">"Catch exception "</font> + e.getMessage()
					+ <font color="#00ed0">" while adding trigger "</font> + triggerName
					+ <font color="#00ed0">" into scheduler"</font>, e);
			<font color="#00a000"><b>throw</b></font><font color="#00a000"><b>new</b></font> TaskException(<font color="#00ed0">"0096"</font>, <font color="#00ed0">"Catch exception "</font> + e.getMessage()
					+ <font color="#00ed0">" while adding trigger "</font> + triggerName
					+ <font color="#00ed0">" into scheduler"</font>, e);
		<font color="#00a000">}</font>
 
</pre></td></tr></tbody></table><br /><br />2.删除Trigger <br /><table cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><font color="#555555"><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></pre></font></td><td valign="top" align="left" bgcolor="#ffffff"><pre><font color="#00a000"><b>try</b></font><font color="#00a000">{</font>
			scheduler.unscheduleJob(triggerName, Scheduler.DEFAULT_GROUP);
		<font color="#00a000">}</font><font color="#00a000"><b>catch</b></font> (SchedulerException e) <font color="#00a000">{</font>
			logger.error(<font color="#00ed0">"Catch exception "</font> + e.getMessage()
					+ <font color="#00ed0">" while remove trigger "</font> + triggerName
					+ <font color="#00ed0">" from scheduler"</font>, e);
			<font color="#00a000"><b>throw</b></font><font color="#00a000"><b>new</b></font> TaskException(<font color="#00ed0">"0096"</font>, <font color="#00ed0">"Catch exception "</font> + e.getMessage()
					+ <font color="#00ed0">" while removing trigger "</font> + triggerName
					+ <font color="#00ed0">" from scheduler"</font>, e);
</pre></td></tr></tbody></table><img src ="http://www.blogjava.net/19851985lili/aggbug/93515.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-01-12 19:32 <a href="http://www.blogjava.net/19851985lili/articles/93515.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring applicationContext在web容器中加载过程 </title><link>http://www.blogjava.net/19851985lili/articles/93484.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Fri, 12 Jan 2007 08:53:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/93484.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/93484.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/93484.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/93484.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/93484.html</trackback:ping><description><![CDATA[web.xml <br /><br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre>&lt;context-param&gt;
    &lt;param-name&gt;webAppRootKey&lt;/param-name&gt;
    &lt;param-value&gt;task.root&lt;/param-value&gt;
  &lt;/context-param&gt;
  &lt;!-- 定义SPRING配置文件 --&gt;
  <font color="red">
   &lt;context-param&gt;
    &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
    &lt;param-value&gt;/WEB-INF/taskContext*.xml&lt;/param-value&gt;
  &lt;/context-param&gt;
  </font>
  &lt;context-param&gt;
    &lt;param-name&gt;log4jConfigLocation&lt;/param-name&gt;
    &lt;param-value&gt;/WEB-INF/log4j.properties&lt;/param-value&gt;
  &lt;/context-param&gt;
  &lt;!-- 定义LOG4J监听器 --&gt;
  &lt;listener&gt;
    &lt;listener-class&gt;org.springframework.web.util.Log4jConfigListener&lt;/listener-class&gt;
  &lt;/listener&gt;
 
  &lt;!-- 定义SPRING监听器 --&gt;
<font color="red">
  &lt;listener&gt;
    &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
  &lt;/listener&gt;
</font></pre></td></tr></tbody></table><br />进入contextLoaderListener看看到底加载时做了甚么 <br />==&gt;org.springframework.web.context.ContextLoaderListener <br /><br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre><font class="java-reserved_word"><b>public</b></font><font class="java-reserved_word"><b>class</b></font> ContextLoaderListener <font class="java-reserved_word"><b>implements</b></font> ServletContextListener <font class="java-bracket">{</font>
 
  <font class="java-reserved_word"><b>private</b></font> ContextLoader contextLoader;
 
  <font class="java-comment">/**
   * Initialize the root web application context.
   */</font><font class="java-comment">//当WEB上下文初始化时,系统会调用此方法</font><font class="java-reserved_word"><b>public</b></font><font class="java-reserved_word"><b>void</b></font> contextInitialized(ServletContextEvent event) <font class="java-bracket">{</font>
    this.contextLoader = createContextLoader();
 
<font color="red"><font class="java-comment">//监听到WEB上下文初始化的时候执行SPRING上下文contextLoader的初始化工作</font>
    this.contextLoader.initWebApplicationContext(event.getServletContext());
</font><font class="java-bracket">}</font>
 
  <font class="java-comment">/**
   * Create the ContextLoader to use. Can be overridden in subclasses.
   * @return the new ContextLoader
   */</font><font class="java-reserved_word"><b>protected</b></font> ContextLoader createContextLoader() <font class="java-bracket">{</font><font class="java-reserved_word"><b>return</b></font><font class="java-reserved_word"><b>new</b></font> ContextLoader();
  <font class="java-bracket">}</font>
 
  <font class="java-comment">/**
   * Return the ContextLoader used by this listener.
   */</font><font class="java-reserved_word"><b>public</b></font> ContextLoader getContextLoader() <font class="java-bracket">{</font><font class="java-reserved_word"><b>return</b></font> contextLoader;
  <font class="java-bracket">}</font>
 
  <font class="java-comment">/**
   * Close the root web application context.
   */</font><font class="java-reserved_word"><b>public</b></font><font class="java-reserved_word"><b>void</b></font> contextDestroyed(ServletContextEvent event) <font class="java-bracket">{</font><font class="java-reserved_word"><b>if</b></font> (this.contextLoader != <font class="java-reserved_word"><b>null</b></font>) <font class="java-bracket">{</font>
      this.contextLoader.closeWebApplicationContext(event.getServletContext());
    <font class="java-bracket">}</font><font class="java-bracket">}</font>
 
<font class="java-bracket">}</font></pre></td></tr></tbody></table><br />看一下是怎么来初始化webapplicationContext的 <br />==&gt;contextLoader.initWebApplicationContext <br /><br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre><font class="java-reserved_word"><b>public</b></font> WebApplicationContext initWebApplicationContext(ServletContext servletContext)
      <font class="java-reserved_word"><b>throws</b></font> IllegalStateException, BeansException <font class="java-bracket">{</font>
 
    <font class="java-reserved_word"><b>if</b></font> (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != <font class="java-reserved_word"><b>null</b></font>) <font class="java-bracket">{</font><font class="java-reserved_word"><b>throw</b></font><font class="java-reserved_word"><b>new</b></font> IllegalStateException(
          <font class="java-string">"Cannot initialize context because there is already a root application context </font>
 
present - <font class="java-string">" +</font><font class="java-string">"check whether you have multiple ContextLoader* definitions in your web.xml!"</font>);
    <font class="java-bracket">}</font>
 
    <font class="java-reserved_word"><b>long</b></font> startTime = System.currentTimeMillis();
    <font class="java-reserved_word"><b>if</b></font> (logger.isInfoEnabled()) <font class="java-bracket">{</font>
      logger.info(<font class="java-string">"Root WebApplicationContext: initialization started"</font>);
    <font class="java-bracket">}</font>
    servletContext.log(<font class="java-string">"Loading Spring root WebApplicationContext"</font>);
 
    <font class="java-reserved_word"><b>try</b></font><font class="java-bracket">{</font><font class="java-comment">// Determine parent for root web application context, if any.</font>
      ApplicationContext parent = loadParentContext(servletContext);
 
      <font class="java-comment">// Store context in local instance variable, to guarantee that</font><font class="java-comment">// it is available on ServletContext shutdown.</font>
 
<font color="red"><font class="java-comment">//创建web上下文</font>
      this.context = createWebApplicationContext(servletContext, parent);
      servletContext.setAttribute(
          WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
</font>
 
      <font class="java-reserved_word"><b>if</b></font> (logger.isInfoEnabled()) <font class="java-bracket">{</font>
        logger.info(<font class="java-string">"Using context class ["</font> + this.context.getClass().getName() +
            <font class="java-string">"] for root WebApplicationContext"</font>);
      <font class="java-bracket">}</font><font class="java-reserved_word"><b>if</b></font> (logger.isDebugEnabled()) <font class="java-bracket">{</font>
        logger.debug(<font class="java-string">"Published root WebApplicationContext ["</font> + this.context +
            <font class="java-string">"] as ServletContext attribute with name ["</font> +
            WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + <font class="java-string">"]"</font>);
      <font class="java-bracket">}</font><font class="java-reserved_word"><b>if</b></font> (logger.isInfoEnabled()) <font class="java-bracket">{</font><font class="java-reserved_word"><b>long</b></font> elapsedTime = System.currentTimeMillis() - startTime;
        logger.info(<font class="java-string">"Root WebApplicationContext: initialization completed in "</font> + elapsedTime + <font class="java-string">" </font>
 
ms<font class="java-string">");</font><font class="java-bracket">}</font>
 
      <font class="java-reserved_word"><b>return</b></font> this.context;
    <font class="java-bracket">}</font><font class="java-reserved_word"><b>catch</b></font> (RuntimeException ex) <font class="java-bracket">{</font>
      logger.error(<font class="java-string">"Context initialization failed"</font>, ex);
      servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
      <font class="java-reserved_word"><b>throw</b></font> ex;
    <font class="java-bracket">}</font><font class="java-reserved_word"><b>catch</b></font> (Error err) <font class="java-bracket">{</font>
      logger.error(<font class="java-string">"Context initialization failed"</font>, err);
      servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
      <font class="java-reserved_word"><b>throw</b></font> err;
    <font class="java-bracket">}</font><font class="java-bracket">}</font></pre></td></tr></tbody></table><br />==&gt;contextLoader.createWebApplicationContext(servletContext, parent); <br /><br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre><font class="java-reserved_word"><b>protected</b></font> WebApplicationContext createWebApplicationContext(
      ServletContext servletContext, ApplicationContext parent) <font class="java-reserved_word"><b>throws</b></font> BeansException <font class="java-bracket">{</font><font color="red"><font class="java-comment">//根据servletContext来决定要实例化的WebApplicationContext</font>
    Class contextClass = determineContextClass(servletContext);
    <font class="java-reserved_word"><b>if</b></font> (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) <font class="java-bracket">{</font><font class="java-reserved_word"><b>throw</b></font><font class="java-reserved_word"><b>new</b></font> ApplicationContextException(<font class="java-string">"Custom context class ["</font> + contextClass.getName() +
          <font class="java-string">"] is not of type ConfigurableWebApplicationContext"</font>);
    <font class="java-bracket">}</font>
    ConfigurableWebApplicationContext wac =
        (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
    wac.setParent(parent);
    wac.setServletContext(servletContext);
 
    <font class="java-comment">//得到WEB.XML中设置的SPRING配置文件位置</font>
    String <a name="baidusnap0"></a><b style="COLOR: black; BACKGROUND-COLOR: #ffff66">configLocation</b> = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
    <font class="java-reserved_word"><b>if</b></font> (<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">configLocation</b> != <font class="java-reserved_word"><b>null</b></font>) <font class="java-bracket">{</font><font class="java-comment">//把配置文件分段后设置到WebApplicationContext的ConfigLocations中</font>
      wac.setConfigLocations(StringUtils.tokenizeToStringArray(<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">configLocation</b>,
          ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
    <font class="java-bracket">}</font><font class="java-comment">//刷新WebApplicationContext</font>
    wac.refresh();
</font><font class="java-reserved_word"><b>return</b></font> wac;
  <font class="java-bracket">}</font></pre></td></tr></tbody></table><br />==&gt;contextLoader.determineContextClass(servletContext); <br /><br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre><font class="java-reserved_word"><b>protected</b></font> Class determineContextClass(ServletContext servletContext) <font class="java-reserved_word"><b>throws</b></font> ApplicationContextException <font class="java-bracket">{</font><font color="red"><font class="java-comment">//获得需要实例化的CONTEXT类名,在web.xml中有设置,如果没有设置,那么为空</font>
    String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);
    <font class="java-reserved_word"><b>if</b></font> (contextClassName != <font class="java-reserved_word"><b>null</b></font>) <font class="java-bracket">{</font><font class="java-reserved_word"><b>try</b></font><font class="java-bracket">{</font><font class="java-reserved_word"><b>return</b></font> ClassUtils.forName(contextClassName);
      <font class="java-bracket">}</font><font class="java-reserved_word"><b>catch</b></font> (ClassNotFoundException ex) <font class="java-bracket">{</font><font class="java-reserved_word"><b>throw</b></font><font class="java-reserved_word"><b>new</b></font> ApplicationContextException(
            <font class="java-string">"Failed to load custom context class ["</font> + contextClassName + <font class="java-string">"]"</font>, ex);
      <font class="java-bracket">}</font><font class="java-bracket">}</font><font class="java-comment">//如果在spring web.xml中没有设置context类位置,那么取得默认context</font><font class="java-reserved_word"><b>else</b></font><font class="java-bracket">{</font><font class="java-comment">//取得defaultStrategies配置文件中的WebApplicationContext属性</font>
      contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());
      <font class="java-reserved_word"><b>try</b></font><font class="java-bracket">{</font><font class="java-reserved_word"><b>return</b></font> ClassUtils.forName(contextClassName);
      <font class="java-bracket">}</font><font class="java-reserved_word"><b>catch</b></font> (ClassNotFoundException ex) <font class="java-bracket">{</font><font class="java-reserved_word"><b>throw</b></font><font class="java-reserved_word"><b>new</b></font> ApplicationContextException(
            <font class="java-string">"Failed to load default context class ["</font> + contextClassName + <font class="java-string">"]"</font>, ex);
      <font class="java-bracket">}</font><font class="java-bracket">}</font></font><font class="java-bracket">}</font></pre></td></tr></tbody></table><br />SPRING上下文默认的策略是甚么呢? <br />==&gt;contextLoader.defaultStrategies <br /><br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre><font class="java-reserved_word"><b>private</b></font><font class="java-reserved_word"><b>static</b></font><font class="java-reserved_word"><b>final</b></font> Properties defaultStrategies;
 
  <font class="java-reserved_word"><b>static</b></font><font class="java-bracket">{</font><font class="java-comment">// Load default strategy implementations from properties file.</font><font class="java-comment">// This is currently strictly internal and not meant to be customized</font><font class="java-comment">// by application developers.</font><font class="java-reserved_word"><b>try</b></font><font class="java-bracket">{</font><font color="red"><font class="java-comment">//设置classpath为contextLoader同级目录</font>
      ClassPathResource resource = <font class="java-reserved_word"><b>new</b></font> ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.class);
      <font class="java-comment">//加载该目录下的所有properties文件</font>
      defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
</font><font class="java-bracket">}</font><font class="java-reserved_word"><b>catch</b></font> (IOException ex) <font class="java-bracket">{</font><font class="java-reserved_word"><b>throw</b></font><font class="java-reserved_word"><b>new</b></font> IllegalStateException(<font class="java-string">"Could not load 'ContextLoader.properties': "</font> + ex.getMessage());
    <font class="java-bracket">}</font><font class="java-bracket">}</font></pre></td></tr></tbody></table><br />找到同级目录下的配置文件 <br />==&gt;ContextLoader.properties <br /><br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre># Default WebApplicationContext implementation <font class="java-reserved_word"><b>class</b></font><font class="java-reserved_word"><b>for</b></font> ContextLoader.
# Used as fallback when no explicit context implementation has been specified as context-param.
# Not meant to be customized by application developers.
 
<font color="red">
#默认的WebApplicationContext为org.springframework.web.context.support.XmlWebApplicationContext
org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext
</font></pre></td></tr></tbody></table><br />==&gt;org.springframework.web.context.support.XmlWebApplicationContext <br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre><font class="java-reserved_word"><b>public</b></font><font class="java-reserved_word"><b>class</b></font> XmlWebApplicationContext <font class="java-reserved_word"><b>extends</b></font> AbstractRefreshableWebApplicationContext <font class="java-bracket">{</font>
 
  <font class="java-comment">/** Default config location for the root context */</font>
 
<font color="red"><font class="java-comment">//配置了默认的spring配置文件</font><font class="java-reserved_word"><b>public</b></font><font class="java-reserved_word"><b>static</b></font><font class="java-reserved_word"><b>final</b></font> String DEFAULT_CONFIG_LOCATION = <font class="java-string">"/WEB-INF/applicationContext.xml"</font>;
</font>
 
  <font class="java-comment">//配置文件默认BUILD路径</font><font class="java-reserved_word"><b>public</b></font><font class="java-reserved_word"><b>static</b></font><font class="java-reserved_word"><b>final</b></font> String DEFAULT_CONFIG_LOCATION_PREFIX = <font class="java-string">"/WEB-INF/"</font>;
 
  <font class="java-comment">//配置文件默认后缀名</font><font class="java-reserved_word"><b>public</b></font><font class="java-reserved_word"><b>static</b></font><font class="java-reserved_word"><b>final</b></font> String DEFAULT_CONFIG_LOCATION_SUFFIX = <font class="java-string">".xml"</font>;
 
  <font class="java-comment">/**
   * Loads the bean definitions via an XmlBeanDefinitionReader.
   * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
   * @see #initBeanDefinitionReader
   * @see #loadBeanDefinitions
   */</font><font class="java-comment">//获得bean配置</font><font class="java-reserved_word"><b>protected</b></font><font class="java-reserved_word"><b>void</b></font> loadBeanDefinitions(DefaultListableBeanFactory beanFactory) <font class="java-reserved_word"><b>throws</b></font> IOException <font class="java-bracket">{</font><font class="java-comment">//从BEAN工厂获得一个XmlBeanDefinitionReader 来读取SPRING配置文件</font>
    XmlBeanDefinitionReader beanDefinitionReader = <font class="java-reserved_word"><b>new</b></font> XmlBeanDefinitionReader(beanFactory);
 
    <font class="java-comment">//设置beanDefinitionReader服务于当前CONTEXT</font><font class="java-comment">// resource loading environment.</font>
    beanDefinitionReader.setResourceLoader(<font class="java-reserved_word"><b>this</b></font>);
    beanDefinitionReader.setEntityResolver(<font class="java-reserved_word"><b>new</b></font> ResourceEntityResolver(<font class="java-reserved_word"><b>this</b></font>));
 
    <font class="java-comment">// Allow a subclass to provide custom initialization of the reader,</font><font class="java-comment">// then proceed with actually loading the bean definitions.</font>
    initBeanDefinitionReader(beanDefinitionReader);
<font color="red"><font class="java-comment">//读取配置文件</font>
    loadBeanDefinitions(beanDefinitionReader);
</font><font class="java-bracket">}</font>
 
  <font class="java-comment">/**
   * Initialize the bean definition reader used for loading the bean
   * definitions of this context. Default implementation is empty.
   * &lt;p&gt;Can be overridden in subclasses, e.g. for turning off XML validation
   * or using a different XmlBeanDefinitionParser implementation.
   * @param beanDefinitionReader the bean definition reader used by this context
   * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader#setValidationMode
   * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader#setDocumentReaderClass
   */</font><font class="java-reserved_word"><b>protected</b></font><font class="java-reserved_word"><b>void</b></font> initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) <font class="java-bracket">{</font><font class="java-bracket">}</font>
 
  <font class="java-comment">/**
   * Load the bean definitions with the given XmlBeanDefinitionReader.
   * &lt;p&gt;The lifecycle of the bean factory is handled by the refreshBeanFactory method;
   * therefore this method is just supposed to load and/or register bean definitions.
   * &lt;p&gt;Delegates to a ResourcePatternResolver for resolving location patterns
   * into Resource instances.
   * @throws org.springframework.beans.BeansException in case of bean registration errors
   * @throws java.io.IOException if the required XML document isn't found
   * @see #refreshBeanFactory
   * @see #getConfigLocations
   * @see #getResources
   * @see #getResourcePatternResolver
   */</font><font color="red"><font class="java-comment">//读取配置文件</font><font class="java-reserved_word"><b>protected</b></font><font class="java-reserved_word"><b>void</b></font> loadBeanDefinitions(XmlBeanDefinitionReader reader) <font class="java-reserved_word"><b>throws</b></font> BeansException, IOException <font class="java-bracket">{</font>
    String[] configLocations = getConfigLocations();
    <font class="java-reserved_word"><b>if</b></font> (configLocations != <font class="java-reserved_word"><b>null</b></font>) <font class="java-bracket">{</font><font class="java-reserved_word"><b>for</b></font> (<font class="java-reserved_word"><b>int</b></font> i = 0; i &lt; configLocations.length; i++) <font class="java-bracket">{</font>
        reader.loadBeanDefinitions(configLocations[i]);
      <font class="java-bracket">}</font><font class="java-bracket">}</font><font class="java-bracket">}</font></font>
 
  <font class="java-comment">/**
   * The default location for the root context is "/WEB-INF/applicationContext.xml",
   * and "/WEB-INF/test-servlet.xml" for a context with the namespace "test-servlet"
   * (like for a DispatcherServlet instance with the servlet-name "test").
   */</font><font class="java-comment">//获得默认的ConfigLocations</font><font class="java-reserved_word"><b>protected</b></font> String[] getDefaultConfigLocations() <font class="java-bracket">{</font><font class="java-reserved_word"><b>if</b></font> (getNamespace() != <font class="java-reserved_word"><b>null</b></font>) <font class="java-bracket">{</font><font class="java-reserved_word"><b>return</b></font><font class="java-reserved_word"><b>new</b></font> String[] <font class="java-bracket">{</font>DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + 
 
DEFAULT_CONFIG_LOCATION_SUFFIX<font class="java-bracket">}</font>;
    <font class="java-bracket">}</font><font class="java-reserved_word"><b>else</b></font><font class="java-bracket">{</font><font class="java-reserved_word"><b>return</b></font><font class="java-reserved_word"><b>new</b></font> String[] <font class="java-bracket">{</font>DEFAULT_CONFIG_LOCATION<font class="java-bracket">}</font>;
    <font class="java-bracket">}</font><font class="java-bracket">}</font></pre></td></tr></tbody></table><br />==&gt;AbstractBeanDefinitionReader.loadBeanDefinitions() <br /><br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre><font class="java-reserved_word"><b>public</b></font><font class="java-reserved_word"><b>int</b></font> loadBeanDefinitions(String location) <font class="java-reserved_word"><b>throws</b></font> BeanDefinitionStoreException <font class="java-bracket">{</font>
    ResourceLoader resourceLoader = getResourceLoader();
    <font class="java-reserved_word"><b>if</b></font> (resourceLoader == <font class="java-reserved_word"><b>null</b></font>) <font class="java-bracket">{</font><font class="java-reserved_word"><b>throw</b></font><font class="java-reserved_word"><b>new</b></font> BeanDefinitionStoreException(
          <font class="java-string">"Cannot import bean definitions from location ["</font> + location + <font class="java-string">"]: no ResourceLoader available"</font>);
    <font class="java-bracket">}</font>
 
    <font class="java-reserved_word"><b>if</b></font> (resourceLoader <font class="java-reserved_word"><b>instanceof</b></font> ResourcePatternResolver) <font class="java-bracket">{</font><font class="java-comment">// Resource pattern matching available.</font><font class="java-reserved_word"><b>try</b></font><font class="java-bracket">{</font><font color="red"><font class="java-comment">//根据配置文件读取相应配置</font>
        Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
</font><font class="java-reserved_word"><b>int</b></font> loadCount = loadBeanDefinitions(resources);
        <font class="java-reserved_word"><b>if</b></font> (logger.isDebugEnabled()) <font class="java-bracket">{</font>
          logger.debug(<font class="java-string">"Loaded "</font> + loadCount + <font class="java-string">" bean definitions from location pattern ["</font> + location + <font class="java-string">"]"</font>);
        <font class="java-bracket">}</font><font class="java-reserved_word"><b>return</b></font> loadCount;
      <font class="java-bracket">}</font><font class="java-reserved_word"><b>catch</b></font> (IOException ex) <font class="java-bracket">{</font><font class="java-reserved_word"><b>throw</b></font><font class="java-reserved_word"><b>new</b></font> BeanDefinitionStoreException(
            <font class="java-string">"Could not resolve bean definition resource pattern ["</font> + location + <font class="java-string">"]"</font>, ex);
      <font class="java-bracket">}</font><font class="java-bracket">}</font><font class="java-reserved_word"><b>else</b></font><font class="java-bracket">{</font><font class="java-comment">// Can only load single resources by absolute URL.</font>
      Resource resource = resourceLoader.getResource(location);
      <font class="java-reserved_word"><b>int</b></font> loadCount = loadBeanDefinitions(resource);
      <font class="java-reserved_word"><b>if</b></font> (logger.isDebugEnabled()) <font class="java-bracket">{</font>
        logger.debug(<font class="java-string">"Loaded "</font> + loadCount + <font class="java-string">" bean definitions from location ["</font> + location + <font class="java-string">"]"</font>);
      <font class="java-bracket">}</font><font class="java-reserved_word"><b>return</b></font> loadCount;
    <font class="java-bracket">}</font><font class="java-bracket">}</font></pre></td></tr></tbody></table><br />这个是其中一个ResourceLoader的实现 <br />==&gt;PathMatchingResourcePatternResolver.getResources(String locationPattern); <br /><br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre><font class="java-reserved_word"><b>public</b></font> Resource[] getResources(String locationPattern) <font class="java-reserved_word"><b>throws</b></font> IOException <font class="java-bracket">{</font>
    Assert.notNull(locationPattern, <font class="java-string">"Location pattern must not be null"</font>);
    <font class="java-reserved_word"><b>if</b></font> (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) <font class="java-bracket">{</font><font class="java-comment">// a class path resource (multiple resources for same name possible)</font><font color="red"><font class="java-reserved_word"><b>if</b></font> (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) <font class="java-bracket">{</font><font class="java-comment">// a class path resource pattern</font><font class="java-reserved_word"><b>return</b></font> findPathMatchingResources(locationPattern);
      <font class="java-bracket">}</font><font class="java-reserved_word"><b>else</b></font><font class="java-bracket">{</font><font class="java-comment">// all class path resources with the given name</font><font class="java-reserved_word"><b>return</b></font> findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
      <font class="java-bracket">}</font></font><font class="java-bracket">}</font><font class="java-reserved_word"><b>else</b></font><font class="java-bracket">{</font><font class="java-comment">// Only look for a pattern after a prefix here</font><font class="java-comment">// (to not get fooled by a pattern symbol in a strange prefix).</font><font class="java-reserved_word"><b>int</b></font> prefixEnd = locationPattern.indexOf(<font class="java-string">":"</font>) + 1;
      <font class="java-reserved_word"><b>if</b></font> (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) <font class="java-bracket">{</font><font class="java-comment">// a file pattern</font><font class="java-reserved_word"><b>return</b></font> findPathMatchingResources(locationPattern);
      <font class="java-bracket">}</font><font class="java-reserved_word"><b>else</b></font><font class="java-bracket">{</font><font class="java-comment">// a single resource with the given name</font><font class="java-reserved_word"><b>return</b></font><font class="java-reserved_word"><b>new</b></font> Resource[] <font class="java-bracket">{</font>getResourceLoader().getResource(locationPattern)<font class="java-bracket">}</font>;
      <font class="java-bracket">}</font><font class="java-bracket">}</font><font class="java-bracket">}</font></pre></td></tr></tbody></table><br /><br />==&gt;PathMatchingResourcePatternResolver.findPathMatchingResources(String locationPattern); <br /><br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre><font class="java-reserved_word"><b>protected</b></font> Resource[] findPathMatchingResources(String locationPattern) <font class="java-reserved_word"><b>throws</b></font> IOException <font class="java-bracket">{</font>
    String rootDirPath = determineRootDir(locationPattern);
    String subPattern = locationPattern.substring(rootDirPath.length());
    Resource[] rootDirResources = getResources(rootDirPath);
<font color="red"><font class="java-comment">//collectionFactory初始化一个set容量为16</font>
    Set result = CollectionFactory.createLinkedSetIfPossible(16);
    <font class="java-reserved_word"><b>for</b></font> (<font class="java-reserved_word"><b>int</b></font> i = 0; i &lt; rootDirResources.length; i++) <font class="java-bracket">{</font>
      Resource rootDirResource = rootDirResources[i];
      <font class="java-reserved_word"><b>if</b></font> (isJarResource(rootDirResource)) <font class="java-bracket">{</font>
        result.addAll(doFindPathMatchingJarResources(rootDirResource, subPattern));
      <font class="java-bracket">}</font><font class="java-reserved_word"><b>else</b></font><font class="java-bracket">{</font>
        result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern));
      <font class="java-bracket">}</font><font class="java-bracket">}</font></font><font class="java-reserved_word"><b>if</b></font> (logger.isDebugEnabled()) <font class="java-bracket">{</font>
      logger.debug(<font class="java-string">"Resolved location pattern ["</font> + locationPattern + <font class="java-string">"] to resources "</font> + result);
    <font class="java-bracket">}</font><font class="java-reserved_word"><b>return</b></font> (Resource[]) result.toArray(<font class="java-reserved_word"><b>new</b></font> Resource[result.size()]);
  <font class="java-bracket">}</font></pre></td></tr></tbody></table><br /><br />前面说到有一个刷新WebApplicationContext的操作,但是XmlWebApplicationContext 并没有实现refresh方法,而方法的实现写在 <br /><br />AbstractRefreshableWebApplicationContext 中 <br /><br />==&gt;AbstractRefreshableWebApplicationContext.refresh(); <br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre><font class="java-reserved_word"><b>public</b></font><font class="java-reserved_word"><b>void</b></font> refresh() <font class="java-reserved_word"><b>throws</b></font> BeansException <font class="java-bracket">{</font><font class="java-reserved_word"><b>if</b></font> (ObjectUtils.isEmpty(getConfigLocations())) <font class="java-bracket">{</font><font class="java-comment">//设置configLocations为默认的getDefaultConfigLocations()</font>
      setConfigLocations(getDefaultConfigLocations());
    <font class="java-bracket">}</font>
    super.refresh();
  <font class="java-bracket">}</font></pre></td></tr></tbody></table><br /><br />==&gt;AbstractApplicationContext.refresh(); <br /><table class="java" cellspacing="1" cellpadding="3" bgcolor="#999999" border="0"><tbody><tr><td valign="top" align="left" width="1" bgcolor="#dddddd"><pre><font color="#555555">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br /></font></pre></td><td valign="top" align="left" bgcolor="#ffffff"><pre><font class="java-reserved_word"><b>public</b></font><font class="java-reserved_word"><b>void</b></font> refresh() <font class="java-reserved_word"><b>throws</b></font> BeansException, IllegalStateException <font class="java-bracket">{</font><font class="java-reserved_word"><b>synchronized</b></font> (this.startupShutdownMonitor) <font class="java-bracket">{</font>
      this.startupTime = System.currentTimeMillis();
 
      <font class="java-reserved_word"><b>synchronized</b></font> (this.activeMonitor) <font class="java-bracket">{</font>
        this.active = <font class="java-reserved_word"><b>true</b></font>;
      <font class="java-bracket">}</font>
 
      <font class="java-comment">// Tell subclass to refresh the internal bean factory.</font>
      refreshBeanFactory();
      ConfigurableListableBeanFactory beanFactory = getBeanFactory();
 
      <font class="java-comment">// Tell the internal bean factory to use the context's class loader.</font>
      beanFactory.setBeanClassLoader(getClassLoader());
 
      <font class="java-comment">// Populate the bean factory with context-specific resource editors.</font>
      beanFactory.addPropertyEditorRegistrar(<font class="java-reserved_word"><b>new</b></font> ResourceEditorRegistrar(<font class="java-reserved_word"><b>this</b></font>));
 
      <font class="java-comment">// Configure the bean factory with context semantics.</font>
      beanFactory.addBeanPostProcessor(<font class="java-reserved_word"><b>new</b></font> ApplicationContextAwareProcessor(<font class="java-reserved_word"><b>this</b></font>));
      beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
      beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
      beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
      beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
 
      <font class="java-comment">// Allows post-processing of the bean factory in context subclasses.</font>
      postProcessBeanFactory(beanFactory);
 
      <font class="java-comment">// Invoke factory processors registered with the context instance.</font><font class="java-reserved_word"><b>for</b></font> (Iterator it = getBeanFactoryPostProcessors().iterator(); it.hasNext();) <font class="java-bracket">{</font>
        BeanFactoryPostProcessor factoryProcessor = (BeanFactoryPostProcessor) it.next();
        factoryProcessor.postProcessBeanFactory(beanFactory);
      <font class="java-bracket">}</font>
 
      <font class="java-reserved_word"><b>if</b></font> (logger.isInfoEnabled()) <font class="java-bracket">{</font><font class="java-reserved_word"><b>if</b></font> (getBeanDefinitionCount() == 0) <font class="java-bracket">{</font>
          logger.info(<font class="java-string">"No beans defined in application context ["</font> + getDisplayName() + <font class="java-string">"]"</font>);
        <font class="java-bracket">}</font><font class="java-reserved_word"><b>else</b></font><font class="java-bracket">{</font>
          logger.info(getBeanDefinitionCount() + <font class="java-string">" beans defined in application context ["</font> + 
 
getDisplayName() + <font class="java-string">"]"</font>);
        <font class="java-bracket">}</font><font class="java-bracket">}</font>
 
      <font class="java-reserved_word"><b>try</b></font><font class="java-bracket">{</font><font class="java-comment">// Invoke factory processors registered as beans in the context.</font>
        invokeBeanFactoryPostProcessors();
 
        <font class="java-comment">// Register bean processors that intercept bean creation.</font>
        registerBeanPostProcessors();
 
        <font class="java-comment">// Initialize message source for this context.</font>
        initMessageSource();
 
        <font class="java-comment">// Initialize event multicaster for this context.</font>
        initApplicationEventMulticaster();
 
        <font class="java-comment">// Initialize other special beans in specific context subclasses.</font>
        onRefresh();
 
        <font class="java-comment">// Check for listener beans and register them.</font>
        registerListeners();
 
        <font class="java-comment">// Instantiate singletons this late to allow them to access the message source.</font>
        beanFactory.preInstantiateSingletons();
 
        <font class="java-comment">// Last step: publish corresponding event.</font>
        publishEvent(<font class="java-reserved_word"><b>new</b></font> ContextRefreshedEvent(<font class="java-reserved_word"><b>this</b></font>));
      <font class="java-bracket">}</font>
 
      <font class="java-reserved_word"><b>catch</b></font> (BeansException ex) <font class="java-bracket">{</font><font class="java-comment">// Destroy already created singletons to avoid dangling resources.</font>
        beanFactory.destroySingletons();
        <font class="java-reserved_word"><b>throw</b></font> ex;
      <font class="java-bracket">}</font><font class="java-bracket">}</font><font class="java-bracket">}</font></pre></td></tr></tbody></table><img src ="http://www.blogjava.net/19851985lili/aggbug/93484.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-01-12 16:53 <a href="http://www.blogjava.net/19851985lili/articles/93484.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>