﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-空白-随笔分类-Java</title><link>http://www.blogjava.net/niumd/category/32382.html</link><description>天行健、君子以自强不息 ；地势坤、君子以厚德载物……</description><language>zh-cn</language><lastBuildDate>Wed, 11 May 2011 02:52:47 GMT</lastBuildDate><pubDate>Wed, 11 May 2011 02:52:47 GMT</pubDate><ttl>60</ttl><item><title>Spring JDBC Framework详解——批量JDBC操作、ORM映射</title><link>http://www.blogjava.net/niumd/archive/2011/05/10/349965.html</link><dc:creator>空白</dc:creator><author>空白</author><pubDate>Tue, 10 May 2011 13:06:00 GMT</pubDate><guid>http://www.blogjava.net/niumd/archive/2011/05/10/349965.html</guid><wfw:comment>http://www.blogjava.net/niumd/comments/349965.html</wfw:comment><comments>http://www.blogjava.net/niumd/archive/2011/05/10/349965.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/niumd/comments/commentRss/349965.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/niumd/services/trackbacks/349965.html</trackback:ping><description><![CDATA[<div style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; background-position: initial initial; background-repeat: initial initial; ">
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">作者：niumd，转载请注明出处，谢谢&nbsp;&nbsp;&nbsp;</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><span mce_style="font-size: small;" style="font-size: small; "><span lang="EN-US"><span mce_style="font-size: x-small;" style="font-size: x-small; ">发表时间：2010 年&nbsp;03 月&nbsp;17 日&nbsp;&nbsp;</span></span></span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><span lang="EN-US"><span mce_style="font-size: small;" style="font-size: small; "><span mce_style="font-size: x-small;" style="font-size: x-small; ">原文链接：<a href="http://ari.iteye.com/admin/blogs/618449" mce_href="/admin/blogs/618449">http://ari.iteye.com/admin/blogs/618449</a></span></span></span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong>一、Spring JDBC 概述</strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp; Spring 提供了一个强有力的模板类JdbcTemplate简化JDBC操作，DataSource,JdbcTemplate都可以以Bean的方式定义在想xml配置文件，JdbcTemplate创建只需注入一个DataSource，应用程序Dao层只需要继承JdbcDaoSupport, 或者注入JdbcTemplate，便可以获取JdbcTemplate，JdbcTemplate是一个线程安全的类，多个Dao可以注入一个JdbcTemplate；</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="xml" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">&lt;!--         Oracle数据源           --&gt;
&lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"&gt;
&lt;property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/&gt;
&lt;property name="url" value="jdbc:oracle:thin:@oracle.devcake.co.uk:1521:INTL"/&gt;
&lt;property name="username" value="sa"/&gt;
&lt;property name="password" value=""/&gt;
&lt;/bean&gt;
&lt;bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"&gt;
&lt;property name="dataSource" ref="dataSource"/&gt;
&lt;/bean&gt;
&lt;!--  set注入方式获取jdbcTemplate --&gt;
&lt;bean id="customerDao" class="JdbcCustomerDao" &gt;
&lt;property name="jdbcTemplate" ref="jdbcTemplate"/&gt;
&lt;/bean&gt;
&lt;!-- 注入dataSource，customerDao通过继承JdbcDaoSupport ,使用this.getJdbcTemplate()获取JdbcTemplate   --&gt;
&lt;bean id="customerDao" class="JdbcCustomerDao" &gt;
&lt;property name="dataSource" ref="dataSource"/&gt;
&lt;/bean&gt;
</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">然后将jdbcTemplate对象注入自定义的Dao、或者继承JdbcDaoSupport，例如：</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">public class JdbcCustomerDao extends JdbcDaoSupport implements CustomerDao {
}
public class JdbcCustomerDao implements CustomerDao {
private JdbcTemplate jdbcTemplate
public void setJdbcTemplate()JdbcTemplate jdbcTemplate{
this.jdbcTemplate=jdbcTemplate
}
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong></strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong>二、&nbsp;JdbcTemplate 提供以下主要方法简化JDBC操作：</strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong></strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong></strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong></strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong></strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong>2.1、List query(String sql,Ojbect[] args,RowMapper rowMapper)</strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp; 说明：常用的查询，sql待执行的sql语句，args是sql语句的参数，rowMapper负责将每一行记录转化为java对象存放在list，并最终返回，例如：</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">public List&lt;Book&gt; queryByAuthor(String author) {
String sql = "select * from book where author=?";
Collection c = getJdoTemplate().find(sql,
new Object[] { author },new BookRowMapper());
List&lt;Book&gt; books = new ArrayList&lt;Book&gt;();
books.addAll(c);
return books;
}
class BookRowMapper implements RowMapper{
public Object mapRow(ResultSet res, int index) throws SQLException {
Book book = new Book();
book.setId(rs.getInt("id"));
//省略set
return book；
}
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp; 更新、删除、其他查询操作类似，举例如下，详细细节请参考spring api：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">//返回值为一个长整形
public long getAverageAge() {
return getJdbcTemplate().queryForLong("SELECT AVG(age) FROM employee");
}
//返回一个整数
public int getTotalNumberOfEmployees() {
return getJdbcTemplate().queryForInt("SELECT COUNT(0) FROM employees");
}
//更新操作
this.jdbcTemplate.update(
"insert into t_actor (first_name, surname) values (?, ?)",
new Object[] {"Leonor", "Watling"});
</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;2.<strong>2、spring 2.5新功能，另类的jdbc ORM：BeanPropertyRowMapper</strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 上面我们检索时必须实现RowMapper，将结果集转化为java对象。Spring2.5 简化了这一操作，使得我们不必再实现RowMapper，实现此功能的俩个神奇东东便是：ParameterizedRowMapper，ParameterizedBeanPropertyRowMapper，貌似通过java反射机制实现了将resultset字段映射到java对象，但是数据表的列必须和java对象的属性对应，没有研究源码，有点类似于apache 的BeanUtil，不知为何这部分在spring开发参考手册没有，难道不是经典。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">//使用ParameterizedBeanPropertyRowMapper
@SuppressWarnings({"unchecked"})
public List&lt;Customer&gt; getAll() {
return getJdbcTemplate().query("select * from t_customer", ParameterizedBeanPropertyRowMapper.newInstance(Customer.class));
}
//使用BeanPropertyRowMapper
@SuppressWarnings({"unchecked"})
public List&lt;Customer&gt; getAll() {
return getJdbcTemplate().query("select * from t_customer", new BeanPropertyRowMapper(Customer.class));
}
</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">注意：ParameterizedBeanPropertyRowMapper是BeanPropertyRowMapper子类。另外表的字段名称必须和实体类的成员变量名称一致；</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong>2.3、spring之JDBC批量操作</strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span mce_style="font-family: Courier New;" style="font-family: 'Courier New'; ">jdbcTemplate.batchUpdate(final String[] sql) ，API解释：Issue multiple SQL updates on a single JDBC Statement using batching，翻译过来大致为：解决多个sql的插入、更新、删除操作在一个Statement中。性能一般。</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><span mce_style="font-family: Courier New;" style="font-family: 'Courier New'; ">&nbsp;&nbsp;&nbsp;jdbcTemplate.batchUpdate(String sql, final BatchPreparedStatementSetter pss),类似于JDBC的PreparedStatement，性能较上着有所提高。</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><span mce_style="font-family: Courier New;" style="font-family: 'Courier New'; ">&nbsp;&nbsp;&nbsp;我们举例说明如何使用，示例如下:</span></p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">final int count = 2000;
final List&lt;String&gt; firstNames = new ArrayList&lt;String&gt;(count);
final List&lt;String&gt; lastNames = new ArrayList&lt;String&gt;(count);
for (int i = 0; i &lt; count; i++) {
firstNames.add("First Name " + i);
lastNames.add("Last Name " + i);
}
jdbcTemplate.batchUpdate(
"insert into customer (id, first_name, last_name, last_login, comments) values (?, ?, ?, ?, ?)",
new BatchPreparedStatementSetter() {
//为prepared statement设置参数。这个方法将在整个过程中被调用的次数
public void setValues(PreparedStatement ps, int i) throws SQLException {
ps.setLong(1, i + 10);
ps.setString(2, firstNames.get(i));
ps.setString(3, lastNames.get(i));
ps.setNull(4, Types.TIMESTAMP);
ps.setNull(5, Types.CLOB);
}
//返回更新的结果集条数
public int getBatchSize() {
return count;
}
});
}
</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><span mce_style="font-family: Courier New;" style="font-family: 'Courier New'; ">&nbsp; BatchSqlUpdate类是SqlUpdate 的子类，适用于插入、删除、更新批量操作，内部使用PreparedStatement，所以效率很高，批量语句达到设定的batchSize，或者手动调用flush才会执行批量操作。注意：此类是非线程安全的，必须为每个使用者创建一个实例，或者在同一个线程中使用前调用reset。</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><span mce_style="font-family: Courier New;" style="font-family: 'Courier New'; ">&nbsp;&nbsp; 下面我们举例说明如何使用BatchSqlUpdate，来执行批量操作。示例如下：</span></p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">class BatchInsert extends BatchSqlUpdate {
private static final String SQL = "insert into t_customer (id, first_name, last_name, last_login, "
+ "comments) values (?, ?, ?, ?, null)";
BatchInsert(DataSource dataSource) {
super(dataSource, SQL);
declareParameter(new SqlParameter(Types.INTEGER));
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.TIMESTAMP));
setBatchSize(10);
}
}
</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">int count = 5000;
for (int i = 0; i &lt; count; i++) {
batchInsert.update(new Object[] { i + 100L, "a" + i, "b" + i, null });
}
</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;至此，spring JDBC主要的应用基本上都简单罗列一番，所有代码均为文章举例，不是很严谨，仅为演示每一种用法，抛砖引玉，希望有独特见解的拍砖，有问题的请指明问题所在,谢谢</p>
</div>
<img src ="http://www.blogjava.net/niumd/aggbug/349965.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/niumd/" target="_blank">空白</a> 2011-05-10 21:06 <a href="http://www.blogjava.net/niumd/archive/2011/05/10/349965.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat6.x目录与server.xml详解</title><link>http://www.blogjava.net/niumd/archive/2011/05/10/349964.html</link><dc:creator>空白</dc:creator><author>空白</author><pubDate>Tue, 10 May 2011 13:04:00 GMT</pubDate><guid>http://www.blogjava.net/niumd/archive/2011/05/10/349964.html</guid><wfw:comment>http://www.blogjava.net/niumd/comments/349964.html</wfw:comment><comments>http://www.blogjava.net/niumd/archive/2011/05/10/349964.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/niumd/comments/commentRss/349964.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/niumd/services/trackbacks/349964.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 本文参考自：Tomcat全攻略参考链接：http://www.ibm.com/developerworks/cn/java/l-tomcat/index.html#1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; Tomcat&nbsp;服务器是一个免费的开放源代码的Web&nbsp;应用服务器，目前最新版本是6.x，相对5.x性能提升很多，主要...&nbsp;&nbsp;<a href='http://www.blogjava.net/niumd/archive/2011/05/10/349964.html'>阅读全文</a><img src ="http://www.blogjava.net/niumd/aggbug/349964.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/niumd/" target="_blank">空白</a> 2011-05-10 21:04 <a href="http://www.blogjava.net/niumd/archive/2011/05/10/349964.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>项目重构之命令模式</title><link>http://www.blogjava.net/niumd/archive/2011/05/10/349962.html</link><dc:creator>空白</dc:creator><author>空白</author><pubDate>Tue, 10 May 2011 13:03:00 GMT</pubDate><guid>http://www.blogjava.net/niumd/archive/2011/05/10/349962.html</guid><wfw:comment>http://www.blogjava.net/niumd/comments/349962.html</wfw:comment><comments>http://www.blogjava.net/niumd/archive/2011/05/10/349962.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/niumd/comments/commentRss/349962.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/niumd/services/trackbacks/349962.html</trackback:ping><description><![CDATA[<div style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; background-position: initial initial; background-repeat: initial initial; ">
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp; &nbsp; 项目中有个业务处理类大小117K，代码2700行，看此类差点雷死我，如今如要增加业务逻辑大约20个吧，此类如果随着项目工程的二期、三期如次添加逻辑迟早有一天大小达到M，噢、mygod。细心研读前人的工作总结，发现其中有点可改造的蛛丝马迹(本人很笨、别笑我才发现如何改造)。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp; 下面我们对业务流程、以及涉及的相关类进行介绍，<span lang="EN-US"><span mce_style="font-family: Calibri;" style="font-family: Calibri; ">Msg</span>代表接受到客户端的一个消息报文，消息报文结构：消息头<span lang="EN-US"><span mce_style="font-family: Calibri;" style="font-family: Calibri; ">+</span></span>消息体，消息头参数固定、消息体参数不定，下面是一个简单的类图，这只是一个模拟场景，<span lang="EN-US"><span mce_style="font-family: Calibri;" style="font-family: Calibri; ">****Req</span></span>代表各户端请求类，<span lang="EN-US"><span mce_style="font-family: Calibri;" style="font-family: Calibri; ">***Rsp</span></span>代表返回给客户端的参数类。实际比此复杂，为描述问题我们简单摘除几个类介绍，别问我为何这么设计继承。类图<span lang="EN-US"><span mce_style="font-family: Calibri;" style="font-family: Calibri; ">msg</span></span>与<span lang="EN-US"><span mce_style="font-family: Calibri;" style="font-family: Calibri; ">msgHead</span></span>是组合关系也许画错了、不当之处请指出，勿恶语向伤；</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><span lang="EN-US">&nbsp;</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;<br />
<img src="http://dl.iteye.com/upload/attachment/264052/9e823571-e81c-35d0-a4e5-b5b14b525542.png" mce_src="http://dl.iteye.com/upload/attachment/264052/9e823571-e81c-35d0-a4e5-b5b14b525542.png" alt="" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; " /><br />
&nbsp;处理请求Handler类的代码逻辑如下：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">//类中主要方法如下
public void execute(Object object) {
Message message = (Message)object;
int opcode = message.getOpcode();
int connectId = message.getConnectId();
//消息头已经解析，获取消息体，即子类属性字节数组
byte[] bytes = message.getBytes();
if (opcode == MsgInfo.ADD_RING) {
// 订购彩铃
orderRing(connectId, bytes);
} else if (opcode == MsgInfo.PRESENT_RING) {
// 赠送彩铃
presentRing(connectId, bytes);
} else if (opcode == MsgInfo.DEL_RING) {
// 删除个人铃音
delPersonalRing(connectId, bytes);
}
//此处省略n个else if
}
//其他删除、赠送与省略的else if中的处理逻辑与之基本相同
private void orderRing(int connectId, byte[] bytes) {
//处理方法分为四步，具体代码省略
//1、解析字节数组为订购铃音类
//2、处理订购关系
//3、处理结果封装为订购响应类
//4、发送回客户端
}
//省略presentRing、delPersonalRing等一系列其他方法，所有的处理方法参数相同&#8230;&#8230;
</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;鉴于此、想到使用命令模式改造此类，如果不了解命令模式请阅读相关书籍，大话设计模式或设计与模式，这里我们仅给出大致的定于与类图。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">何谓命令模式：将一个请求封装为一个对象，从而是你可用不同的请求对客户端参数化，对请求排队或记录日志，以及支持可撤销的操作。</p>
<p class="MsoNormal" mce_style="text-indent: 15.75pt; margin: 0cm 0cm 0pt;" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 0pt; margin-left: 0cm; text-indent: 15.75pt; ">&nbsp;<span lang="EN-US"><span mce_style="font-family: Calibri;" style="font-family: Calibri; ">Shit</span></span>、这句话很难理解哦，那就先别理解了，我们看下命令模式的类图，然后介绍如何使用命令模式改造上面的<span lang="EN-US"><span mce_style="font-family: Calibri;" style="font-family: Calibri; ">elseif</span></span>。</p>
<p class="MsoNormal" mce_style="text-indent: 21pt; margin: 0cm 0cm 0pt;" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 0pt; margin-left: 0cm; text-indent: 21pt; ">类图先省略，上班偷空写的；</p>
<p class="MsoNormal" mce_style="text-indent: 21pt; margin: 0cm 0cm 0pt;" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 0pt; margin-left: 0cm; text-indent: 21pt; "><span lang="EN-US"><span mce_style="font-family: Calibri;" style="font-family: Calibri; ">&nbsp;</span></span></p>
<p class="MsoNormal" mce_style="text-indent: 21pt; margin: 0cm 0cm 0pt;" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 0pt; margin-left: 0cm; text-indent: 21pt; ">下面进入正题，对<span lang="EN-US"><span mce_style="font-family: Calibri;" style="font-family: Calibri; ">Handler</span></span>小手术开始，主要考虑如下：</p>
<p class="MsoListParagraph" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong><span lang="EN-US"><span mce_style="font-family: Calibri;" style="font-family: Calibri; ">1、</span></span>提炼方法</strong></p>
<p class="MsoListParagraph" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp; 将每个<span lang="EN-US"><span mce_style="font-family: Calibri;" style="font-family: Calibri; ">if</span></span>语句块中的逻辑提取为一个方法，这里我们的<span lang="EN-US"><span mce_style="font-family: Calibri;" style="font-family: Calibri; ">handler</span></span>已经实现，就是：<span mce_style="font-family: 'Courier New'; color: black; font-size: 10pt;" style="font-family: 'Courier New'; color: black; font-size: 10pt; ">orderRing</span>、<span mce_style="font-family: 'Courier New'; color: black; font-size: 10pt;" style="font-family: 'Courier New'; color: black; font-size: 10pt; ">presentRing</span>、<span mce_style="font-family: 'Courier New'; color: black; font-size: 10pt;" style="font-family: 'Courier New'; color: black; font-size: 10pt; ">delPersonalRing</span>、&#8230;&#8230;。</p>
<p class="MsoListParagraph" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong><span lang="EN-US"><span mce_style="font-family: Calibri;" style="font-family: Calibri; ">2、</span></span>提炼类</strong></p>
<p class="MsoListParagraph" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp; 将每个业务处理方法提取为以各类，然后对具体类进行抽象，提取父类或者接口；代码如下：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">public Abstract class Command{
public void execute()
｝
public class OrderRingCommand extends Command {
private Handler hander;
public OrderRingCommand(Handler hander){
this.hander = hander;
}
public void execute(int connectId, byte[] bytes){
//1、解析字节数组为订购铃音类
//2、增加订购关系
//3、处理结果封装为订购响应类
//4、发送回客户端
}
/**
* 1、解析字节数组为订购铃音类
*/
public void method1(){
}
/**
* 2、处理订购关系
*/
public void method2(){
}
/**
* 3、处理结果封装为订购响应类
*/
public void method3(){
}
/**
* 4、结果发送回客户端
*/
public void method4(){
}
}
public class DelRingCommand extends Command {
private Handler hander;
public DelRingCommand(Handler hander){
this.hander = hander;
}
public void execute(int connectId, byte[] bytes){
//1、解析字节数组为订购铃音类
//2、删除购关系
//3、处理结果封装为订购响应类
//4、发送回客户端
}
//提取方法
}
</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;<span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; ">&nbsp;</span></span></span></span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong><span lang="EN-US"><span mce_style="font-family: Calibri;" style="font-family: Calibri; ">3、</span></span>命令模式改造替换</strong><span lang="EN-US"><span mce_style="font-family: Calibri;" style="font-family: Calibri; "><strong>elseif：</strong></span></span></p>
<p class="MsoListParagraph" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">Map&lt;Integer, Command&gt; map = new HashMap&lt;Integer,Command&gt;();
static{
map.put(MsgInfo.ADD_RING, new OrderRingCommand());
//省却其他，这里仅为演示，实际项目中实例化类通过spring容器或者其他方法
}
public void execute(Object object) {
Message message = (Message)object;
int opcode = message.getOpcode();
int connectId = message.getConnectId();
//消息头已经解析，获取消息体，即子类属性字节数组
byte[] bytes = message.getBytes();
map.get(opcode).execute(connectId,bytes);
}
</pre>
<p class="MsoListParagraph" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "></span></span></span></span></span></span></span></span></span></span></span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span lang="EN-US"></span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "></span></span></span></span></span></span></span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><span lang="EN-US"></span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><span lang="EN-US">&nbsp;命令模式替换else if代码坏味道的重构结束，众多的if条件块烟消云散，取而代之的是一个个精简的类，doc版本在附件中</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><span lang="EN-US"><font><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><font mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "></font></span></span></span></span></span></span></font></span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font><font mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><br />
</font></font></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p class="MsoListParagraph" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p>&nbsp;</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p class="MsoListParagraph" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p>&nbsp;</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "><span mce_style="font-size: 10.5pt;" style="font-size: 10.5pt; "></span></span></span></span></span></span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p class="MsoListParagraph" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p class="MsoListParagraph" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
</div>
<img src ="http://www.blogjava.net/niumd/aggbug/349962.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/niumd/" target="_blank">空白</a> 2011-05-10 21:03 <a href="http://www.blogjava.net/niumd/archive/2011/05/10/349962.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入浅出ThreadLocal</title><link>http://www.blogjava.net/niumd/archive/2011/05/10/349961.html</link><dc:creator>空白</dc:creator><author>空白</author><pubDate>Tue, 10 May 2011 13:02:00 GMT</pubDate><guid>http://www.blogjava.net/niumd/archive/2011/05/10/349961.html</guid><wfw:comment>http://www.blogjava.net/niumd/comments/349961.html</wfw:comment><comments>http://www.blogjava.net/niumd/archive/2011/05/10/349961.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/niumd/comments/commentRss/349961.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/niumd/services/trackbacks/349961.html</trackback:ping><description><![CDATA[<div style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; background-position: initial initial; background-repeat: initial initial; ">
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong>一、ThreadLocal概述</strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 学习JDK中的类，首先看下JDK API对此类的描述，描述如下：</p>
<div class="quote_title" style="font-weight: bold; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; margin-top: 5px; margin-right: 0px; margin-bottom: 0px; margin-left: 15px; ">JDK API 写道</div>
<div class="quote_div" style="border-left-color: #cccccc; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; ">该类提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物，因为访问某个变量（通过其 get 或 set 方法）的每个线程都有自己的局部变量，它独立于变量的初始化副本。ThreadLocal 实例通常是类中的 private static 字段，它们希望将状态与某一个线程（例如，用户 ID 或事务 ID）相关联。&nbsp;<br />
<br />
</div>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;API表达了下面几种观点：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">1、ThreadLocal不是线程，是线程的一个变量，你可以先简单理解为线程类的属性变量。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">2、ThreadLocal 在类中通常定义为静态类变量。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">3、每个线程有自己的一个ThreadLocal，它是变量的一个&#8216;拷贝&#8217;，修改它不影响其他线程。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; 既然定义为类变量，为何为每个线程维护一个副本（姑且成为&#8216;拷贝&#8217;容易理解），让每个线程独立访问？多线程编程的经验告诉我们，对于线程共享资源（你可以理解为属性），资源是否被所有线程共享，也就是说这个资源被一个线程修改是否影响另一个线程的运行，如果影响我们需要使用synchronized同步，让线程顺序访问。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp; ThreadLocal适用于资源共享但不需要维护状态的情况，也就是一个线程对资源的修改，不影响另一个线程的运行；这种设计是<strong>&#8216;空间换时间&#8217;</strong>，synchronized顺序执行是<strong>&#8216;时间换取空间&#8217;</strong>。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong>二、ThreadLocal方法介绍</strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<table border="1" cellspacing="0" cellpadding="3" width="100%">
    <tbody>
        <tr class="TableRowColor">
            <td width="1%" align="right" valign="top" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code>&nbsp;<a title="ThreadLocal 中的类型参数" href="http://ari.iteye.com/java/lang/ThreadLocal.html" mce_href="/java/lang/ThreadLocal.html">T</a></code></td>
            <td style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code><strong><a href="http://ari.iteye.com/java/lang/ThreadLocal.html#get()" mce_href="/java/lang/ThreadLocal.html#get()">get</a></strong>()</code>&nbsp;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回此线程局部变量的当前线程副本中的值。</td>
        </tr>
        <tr class="TableRowColor">
            <td width="1%" align="right" valign="top" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code>protected &nbsp;<a title="ThreadLocal 中的类型参数" href="http://ari.iteye.com/java/lang/ThreadLocal.html" mce_href="/java/lang/ThreadLocal.html">T</a></code></td>
            <td style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code><strong><a href="http://ari.iteye.com/java/lang/ThreadLocal.html#initialValue()" mce_href="/java/lang/ThreadLocal.html#initialValue()">initialValue</a></strong>()</code>&nbsp;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回此线程局部变量的当前线程的&#8220;初始值&#8221;。</td>
        </tr>
        <tr class="TableRowColor">
            <td width="1%" align="right" valign="top" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code>&nbsp;void</code></td>
            <td style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code><strong><a href="http://ari.iteye.com/java/lang/ThreadLocal.html#remove()" mce_href="/java/lang/ThreadLocal.html#remove()">remove</a></strong>()</code>&nbsp;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;移除此线程局部变量当前线程的值。</td>
        </tr>
        <tr class="TableRowColor">
            <td width="1%" align="right" valign="top" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code>&nbsp;void</code></td>
            <td style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code><strong><a href="http://ari.iteye.com/java/lang/ThreadLocal.html#set(T)" mce_href="/java/lang/ThreadLocal.html#set(T)">set</a></strong>(<a title="ThreadLocal 中的类型参数" href="http://ari.iteye.com/java/lang/ThreadLocal.html" mce_href="/java/lang/ThreadLocal.html">T</a>&nbsp;value)</code>&nbsp;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将此线程局部变量的当前线程副本中的值设置为指定值。</td>
        </tr>
    </tbody>
</table>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong>三、深入源码</strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; ThreadLocal有一个ThreadLocalMap静态内部类，你可以简单理解为一个MAP，这个&#8216;Map&#8217;为每个线程复制一个变量的&#8216;拷贝&#8217;存储其中。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; 当线程调用ThreadLocal.get()方法获取变量时,首先获取当前线程引用，以此为key去获取响应的ThreadLocalMap，如果此&#8216;Map&#8217;不存在则初始化一个，否则返回其中的变量，代码如下：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="get方法" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; "> public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
return (T)e.value;
}
return setInitialValue();
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;调用get方法如果此Map不存在首先初始化，创建此map，将线程为key，初始化的vlaue存入其中，注意此处的initialValue，我们可以覆盖此方法，在首次调用时初始化一个适当的值。setInitialValue代码如下：</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">    private T setInitialValue() {
T value = initialValue();
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
return value;
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; set方法相对比较简单如果理解以上俩个方法，获取当前线程的引用，从map中获取该线程对应的map，如果map存在更新缓存值，否则创建并存储，代码如下：</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">    public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; 对于ThreadLocal在何处存储变量副本，我们看getMap方法：获取的是当前线程的ThreadLocal类型的threadLocals属性。显然变量副本存储在每一个线程中。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">/**
* 获取线程的ThreadLocalMap 属性实例
*/
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; 上面我们知道变量副本存放于何处，这里我们简单说下如何被java的垃圾收集机制收集，当我们不在使用是调用set(null)，此时不在将引用指向该&#8216;map&#8217;，而线程退出时会执行资源回收操作，将申请的资源进行回收，其实就是将属性的引用设置为null。这时已经不在有任何引用指向该map，故而会被垃圾收集。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong>&nbsp;四、ThreadLocal应用示例</strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在我的另一篇文章，对ThreadLocal的使用做了一个实例，此示例也可以用作生产环境，请参见：<a href="http://ari.iteye.com/blog/757641" mce_href="/blog/757641">http://ari.iteye.com/blog/757641</a></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">如有问题请留言讨论，谢谢</p>
</div>
<img src ="http://www.blogjava.net/niumd/aggbug/349961.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/niumd/" target="_blank">空白</a> 2011-05-10 21:02 <a href="http://www.blogjava.net/niumd/archive/2011/05/10/349961.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ThreadLocal示例</title><link>http://www.blogjava.net/niumd/archive/2011/05/10/349960.html</link><dc:creator>空白</dc:creator><author>空白</author><pubDate>Tue, 10 May 2011 13:01:00 GMT</pubDate><guid>http://www.blogjava.net/niumd/archive/2011/05/10/349960.html</guid><wfw:comment>http://www.blogjava.net/niumd/comments/349960.html</wfw:comment><comments>http://www.blogjava.net/niumd/archive/2011/05/10/349960.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/niumd/comments/commentRss/349960.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/niumd/services/trackbacks/349960.html</trackback:ping><description><![CDATA[<div style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; background-position: initial initial; background-repeat: initial initial; ">
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp; &nbsp; 本文借花献佛，引用Tim Cull的博文&#8220;SimpleDateFormat: Performance Pig&#8221;介绍下ThreadLocal的简单使用，同时也对SimpleDateFormat的使用有个深入的了解。</p>
<div class="quote_title" style="font-weight: bold; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; margin-top: 5px; margin-right: 0px; margin-bottom: 0px; margin-left: 15px; ">Tim Cull 写道</div>
<div class="quote_div" style="border-left-color: #cccccc; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; ">Just yesterday I came across this problem &#8220;in the wild&#8221; for the third time in my career so far: an application with performance problems creating tons of java.text.SimpleDateFormat instances. So, I have to get this out there: creating a new instance of SimpleDateFormat is incredibly expensive and should be minimized. In the case that prompted this post, I was using JProfiler to profile this code that parses a CSV file and discovered that 50% of the time it took to suck in the file and make 55,000 objects out of it was spent solely in the constructor of SimpleDateFormat. It created and then threw away a new one every time it had to parse a date. Whew!&nbsp;<br />
<br />
&#8220;Great,&#8221; you think, &#8220;I&#8217;ll just create one, static instance, slap it in a field in a DateUtils helper class and life will be good.&#8221;&nbsp;<br />
<br />
Well, more precisely, life will be good about 97% of the time. A few days after you roll that code into production you&#8217;ll discover the second cool fact that&#8217;s good to know: SimpleDateFormat is not thread safe. Your code will work just fine most of the time and all of your regression tests will probably pass, but once your system gets under a production load you&#8217;ll see the occasional exception.&nbsp;<br />
<br />
&#8220;Fine,&#8221; you think, &#8220;I&#8217;ll just slap a &#8217;synchronized&#8217; around my use of that one, static instance.&#8221;&nbsp;<br />
<br />
Ok, fine, you could do that and you&#8217;d be more or less ok, but the problem is that you&#8217;ve now taken a very common operation (date formatting and parsing) and crammed all of your otherwise-lovely, super-parallel application through a single pipe to get it done.</div>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp; 大致意思：Tim Cull碰到一个SimpleDateFormat带来的严重的性能问题，该问题主要有SimpleDateFormat引发，创建一个SimpleDateFormat实例的开销比较昂贵，解析字符串时间时频繁创建生命周期短暂的实例导致性能低下。即使将SimpleDateFormat定义为静态类变量，貌似能解决这个问题，但是SimpleDateFormat是非线程安全的，同样存在问题，如果用&#8216;synchronized&#8217;线程同步同样面临问题，同步导致性能下降（线程之间序列化的获取SimpleDateFormat实例）。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; Tim Cull使用Threadlocal解决了此问题，对于每个线程SimpleDateFormat不存在影响他们之间协作的状态，为每个线程创建一个SimpleDateFormat变量的拷贝或者叫做副本，代码如下：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 使用ThreadLocal以空间换时间解决SimpleDateFormat线程安全问题。
* @author
*
*/
public class DateUtil {
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
@SuppressWarnings("rawtypes")
private static ThreadLocal threadLocal = new ThreadLocal() {
protected synchronized Object initialValue() {
return new SimpleDateFormat(DATE_FORMAT);
}
};
public static DateFormat getDateFormat() {
return (DateFormat) threadLocal.get();
}
public static Date parse(String textDate) throws ParseException {
return getDateFormat().parse(textDate);
}
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;创建一个ThreadLocal类变量，这里创建时用了一个匿名类，覆盖了initialValue方法，主要作用是创建时初始化实例。也可以采用下面方式创建；</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">//第一次调用get将返回null
private static ThreadLocal threadLocal = new ThreadLocal()；
//获取线程的变量副本，如果不覆盖initialValue，第一次get返回null，故需要初始化一个SimpleDateFormat，并set到threadLocal中
public static DateFormat getDateFormat()
{
DateFormat df = (DateFormat) threadLocal.get();
if(df==null){
df = new SimpleDateFormat(DATE_FORMAT)
threadLocal.set(df);
}
return df;
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp; 我们看下我们覆盖的initialValue方法：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">protected T initialValue() {
return null;//直接返回null
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
</div>
<img src ="http://www.blogjava.net/niumd/aggbug/349960.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/niumd/" target="_blank">空白</a> 2011-05-10 21:01 <a href="http://www.blogjava.net/niumd/archive/2011/05/10/349960.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>探究Struts2运行机制：StrutsPrepareAndExecuteFilter 源码剖析</title><link>http://www.blogjava.net/niumd/archive/2011/05/10/349959.html</link><dc:creator>空白</dc:creator><author>空白</author><pubDate>Tue, 10 May 2011 12:58:00 GMT</pubDate><guid>http://www.blogjava.net/niumd/archive/2011/05/10/349959.html</guid><wfw:comment>http://www.blogjava.net/niumd/comments/349959.html</wfw:comment><comments>http://www.blogjava.net/niumd/archive/2011/05/10/349959.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/niumd/comments/commentRss/349959.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/niumd/services/trackbacks/349959.html</trackback:ping><description><![CDATA[<div style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; background-position: initial initial; background-repeat: initial initial; ">
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong>&nbsp; 作者：niumd</strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong>&nbsp;&nbsp;blog：<a href="http://ari.iteye.com/" mce_href="/">http://ari.iteye.com</a></strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong></strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong>&nbsp;一、概述</strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp; Struts2的核心是一个Filter，Action可以脱离web容器，那么是什么让http请求和action关联在一起的，下面我们深入源码来分析下Struts2是如何工作的。</p>
<div class="quote_title" style="font-weight: bold; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; margin-top: 5px; margin-right: 0px; margin-bottom: 0px; margin-left: 15px; ">FilterDispatcher API 写道</div>
<div class="quote_div" style="border-left-color: #cccccc; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; ">Deprecated. Since Struts 2.1.3, use StrutsPrepareAndExecuteFilter instead or StrutsPrepareFilter and StrutsExecuteFilter if needing using the ActionContextCleanUp filter in addition to this one</div>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;鉴于常规情况官方推荐使用StrutsPrepareAndExecuteFilter替代FilterDispatcher，我们此文将剖析StrutsPrepareAndExecuteFilter，其在工程中作为一个Filter配置在web.xml中，配置如下：</p>
<pre name="code" class="xml" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">&lt;filter&gt;
&lt;filter-name&gt;struts2&lt;/filter-name&gt;
&lt;filter-class&gt;org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
&lt;filter-name&gt;struts2&lt;/filter-name&gt;
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong>二、源码属性方法简介</strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; 下面我们研究下StrutsPrepareAndExecuteFilter源码，类的主要信息如下：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<table border="1" cellspacing="0" cellpadding="3" width="100%">
    <tbody>
        <tr class="TableHeadingColor">
            <th colspan="2" align="left"><strong>属性摘要</strong></th>
        </tr>
        <tr class="TableRowColor">
            <td width="1%" align="right" valign="top" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code>protected &nbsp;<a title="class or interface in java.util" href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/List.html?is-external=true" mce_href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/List.html?is-external=true">List</a>&lt;<a title="class or interface in java.util.regex" href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html?is-external=true" mce_href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html?is-external=true">Pattern</a>&gt;</code></td>
            <td style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code><strong><a href="http://ari.iteye.com/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.html#excludedPatterns" mce_href="/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.html#excludedPatterns">excludedPatterns</a></strong></code>&nbsp;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
        </tr>
        <tr class="TableRowColor">
            <td width="1%" align="right" valign="top" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code>protected &nbsp;<a title="class in org.apache.struts2.dispatcher.ng" href="http://ari.iteye.com/org/apache/struts2/dispatcher/ng/ExecuteOperations.html" mce_href="/org/apache/struts2/dispatcher/ng/ExecuteOperations.html">ExecuteOperations</a></code></td>
            <td style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code><strong><a href="http://ari.iteye.com/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.html#execute" mce_href="/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.html#execute">execute</a></strong></code>&nbsp;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
        </tr>
        <tr class="TableRowColor">
            <td width="1%" align="right" valign="top" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code>protected &nbsp;<a title="class in org.apache.struts2.dispatcher.ng" href="http://ari.iteye.com/org/apache/struts2/dispatcher/ng/PrepareOperations.html" mce_href="/org/apache/struts2/dispatcher/ng/PrepareOperations.html">PrepareOperations</a></code></td>
            <td style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code><strong><a href="http://ari.iteye.com/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.html#prepare" mce_href="/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.html#prepare">prepare</a></strong></code>&nbsp;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
        </tr>
    </tbody>
</table>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; StrutsPrepareAndExecuteFilter与普通的Filter并无区别，方法除继承自Filter外，仅有一个回调方法，第三部分我们将按照Filter方法调用顺序，由init—&gt;doFilter—&gt;destroy顺序地分析源码。</p>
<table border="1" cellspacing="0" cellpadding="3" width="100%">
    <tbody>
        <tr class="TableHeadingColor">
            <th colspan="2" align="left"><strong>方法摘要</strong></th>
        </tr>
        <tr class="TableRowColor">
            <td width="1%" align="right" valign="top" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code>&nbsp;void</code></td>
            <td style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code><strong><a href="http://ari.iteye.com/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.html#destroy()" mce_href="/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.html#destroy()">destroy</a></strong>()</code>&nbsp;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;继承自Filter，用于资源释放</td>
        </tr>
        <tr class="TableRowColor">
            <td width="1%" align="right" valign="top" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code>&nbsp;void</code></td>
            <td style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code><strong><a href="http://ari.iteye.com/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.html#doFilter(javax.servlet.ServletRequest,%20javax.servlet.ServletResponse,%20javax.servlet.FilterChain)" mce_href="/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.html#doFilter(javax.servlet.ServletRequest,%20javax.servlet.ServletResponse,%20javax.servlet.FilterChain)">doFilter</a></strong>(<a title="class or interface in javax.servlet" href="http://java.sun.com/javaee/5/docs/api/javax/servlet/ServletRequest.html?is-external=true" mce_href="http://java.sun.com/javaee/5/docs/api/javax/servlet/ServletRequest.html?is-external=true">ServletRequest</a>&nbsp;req,&nbsp;<a title="class or interface in javax.servlet" href="http://java.sun.com/javaee/5/docs/api/javax/servlet/ServletResponse.html?is-external=true" mce_href="http://java.sun.com/javaee/5/docs/api/javax/servlet/ServletResponse.html?is-external=true">ServletResponse</a>&nbsp;res,&nbsp;<a title="class or interface in javax.servlet" href="http://java.sun.com/javaee/5/docs/api/javax/servlet/FilterChain.html?is-external=true" mce_href="http://java.sun.com/javaee/5/docs/api/javax/servlet/FilterChain.html?is-external=true">FilterChain</a>&nbsp;chain)</code>&nbsp;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;继承自Filter，执行方法</td>
        </tr>
        <tr class="TableRowColor">
            <td width="1%" align="right" valign="top" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code>&nbsp;void</code></td>
            <td style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code><strong><a href="http://ari.iteye.com/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.html#init(javax.servlet.FilterConfig)" mce_href="/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.html#init(javax.servlet.FilterConfig)">init</a></strong>(<a title="class or interface in javax.servlet" href="http://java.sun.com/javaee/5/docs/api/javax/servlet/FilterConfig.html?is-external=true" mce_href="http://java.sun.com/javaee/5/docs/api/javax/servlet/FilterConfig.html?is-external=true">FilterConfig</a>&nbsp;filterConfig)</code>&nbsp;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;继承自Filter，初始化参数</td>
        </tr>
        <tr class="TableRowColor">
            <td width="1%" align="right" valign="top" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code>protected &nbsp;void</code></td>
            <td style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 8px; margin-right: 8px; margin-bottom: 8px; margin-left: 8px; "><code><strong><a href="http://ari.iteye.com/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.html#postInit(org.apache.struts2.dispatcher.Dispatcher,%20javax.servlet.FilterConfig)" mce_href="/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.html#postInit(org.apache.struts2.dispatcher.Dispatcher,%20javax.servlet.FilterConfig)">postInit</a></strong>(<a title="class in org.apache.struts2.dispatcher" href="http://ari.iteye.com/org/apache/struts2/dispatcher/Dispatcher.html" mce_href="/org/apache/struts2/dispatcher/Dispatcher.html">Dispatcher</a>&nbsp;dispatcher,&nbsp;<a title="class or interface in javax.servlet" href="http://java.sun.com/javaee/5/docs/api/javax/servlet/FilterConfig.html?is-external=true" mce_href="http://java.sun.com/javaee/5/docs/api/javax/servlet/FilterConfig.html?is-external=true">FilterConfig</a>&nbsp;filterConfig)</code>&nbsp;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Callback for post initialization（一个空的方法，用于方法回调初始化）</td>
        </tr>
    </tbody>
</table>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong>三、源码剖析&nbsp;&nbsp;&nbsp;&nbsp;</strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;<strong>1、init方法</strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init是Filter第一个运行的方法，我们看下struts2的核心Filter在调用init方法初始化时做哪些工作：</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; "> public void init(FilterConfig filterConfig) throws ServletException {
InitOperations init = new InitOperations();
try {
//封装filterConfig，其中有个主要方法getInitParameterNames将参数名字以String格式存储在List中
FilterHostConfig config = new FilterHostConfig(filterConfig);
// 初始化struts内部日志
init.initLogging(config);
//<strong>创建dispatcher ，并初始化，这部分下面我们重点分析，初始化时加载那些资源</strong>
Dispatcher dispatcher = init.initDispatcher(config);
init.initStaticContentLoader(config, dispatcher);
//初始化类属性：prepare 、execute
prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);
execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);
this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);
//回调空的postInit方法
postInit(dispatcher, filterConfig);
} finally {
init.cleanup();
}
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp; 首先看下FilterHostConfig ，源码如下：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">public class FilterHostConfig implements HostConfig {
private FilterConfig config;
/**
*构造函数
*/
public FilterHostConfig(FilterConfig config) {
this.config = config;
}
/**
*  根据init-param配置的param-name获取param-value的值
*/
public String getInitParameter(String key) {
return config.getInitParameter(key);
}
/**
*  返回初始化参数名的List
*/
public Iterator&lt;String&gt; getInitParameterNames() {
return MakeIterator.convert(config.getInitParameterNames());
}
public ServletContext getServletContext() {
return config.getServletContext();
}
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp; 只有短短的几行代码，getInitParameterNames是这个类的核心，将Filter初始化参数名称有枚举类型转为Iterator。此类的主要作为是对filterConfig 封装。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;<strong><span mce_style="color: #ff0000;" style="color: #ff0000; ">&nbsp;重点来了，创建并初始化Dispatcher</span></strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; "> public Dispatcher initDispatcher( HostConfig filterConfig ) {
Dispatcher dispatcher = createDispatcher(filterConfig);
dispatcher.init();
return dispatcher;
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp; 创建Dispatcher，会读取 filterConfig 中的配置信息，将配置信息解析出来，封装成为一个Map，然后根绝servlet上下文和参数Map构造Dispatcher ：</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">private Dispatcher createDispatcher( HostConfig filterConfig ) {
Map&lt;String, String&gt; params = new HashMap&lt;String, String&gt;();
for ( Iterator e = filterConfig.getInitParameterNames(); e.hasNext(); ) {
String name = (String) e.next();
String value = filterConfig.getInitParameter(name);
params.put(name, value);
}
return new Dispatcher(filterConfig.getServletContext(), params);
}
</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp; Dispatcher初始化，加载struts2的相关配置文件，将按照顺序逐一加载：default.properties，struts-default.xml,struts-plugin.xml,struts.xml，&#8230;&#8230;</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">/**
*初始化过程中依次加载如下配置文件
*/
public void init() {
if (configurationManager == null) {
configurationManager = new ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);
}
try {
//加载org/apache/struts2/default.properties
init_DefaultProperties(); // [1]
//加载struts-default.xml,struts-plugin.xml,struts.xml
init_TraditionalXmlConfigurations(); // [2]
init_LegacyStrutsProperties(); // [3]
//用户自己实现的ConfigurationProviders类
init_CustomConfigurationProviders(); // [5]
//Filter的初始化参数
init_FilterInitParameters() ; // [6]
init_AliasStandardObjects() ; // [7]
Container container = init_PreloadConfiguration();
container.inject(this);
init_CheckConfigurationReloading(container);
init_CheckWebLogicWorkaround(container);
if (!dispatcherListeners.isEmpty()) {
for (DispatcherListener l : dispatcherListeners) {
l.dispatcherInitialized(this);
}
}
} catch (Exception ex) {
if (LOG.isErrorEnabled())
LOG.error("Dispatcher initialization failed", ex);
throw new StrutsException(ex);
}
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp; 初始化default.properties，具体的初始化操作在DefaultPropertiesProvider类中</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong>&nbsp;&nbsp;</strong></p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; "> private void init_DefaultProperties() {
configurationManager.addConfigurationProvider(new DefaultPropertiesProvider());
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong>&nbsp;&nbsp;&nbsp;&nbsp;</strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong>&nbsp;&nbsp;&nbsp;</strong>下面我们看下DefaultPropertiesProvider类源码：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">public void register(ContainerBuilder builder, LocatableProperties props)
throws ConfigurationException {
Settings defaultSettings = null;
try {
defaultSettings = new PropertiesSettings("org/apache/struts2/default");
} catch (Exception e) {
throw new ConfigurationException("Could not find or error in org/apache/struts2/default.properties", e);
}
loadSettings(props, defaultSettings);
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong>&nbsp;&nbsp; 其他的我们再次省略，大家可以浏览下各个初始化操作都加载了那些文件</strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong></strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
3、doFilter方法</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong></strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp; doFilter是过滤器的执行方法，它拦截提交的HttpServletRequest请求，HttpServletResponse响应，作为strtus2的核心拦截器，在doFilter里面到底做了哪些工作，我们将逐行解读其源码，源码如下：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
//父类向子类转：强转为http请求、响应
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
try {
//设置编码和国际化
prepare.setEncodingAndLocale(request, response);
//创建Action上下文（重点）
prepare.createActionContext(request, response);
prepare.assignDispatcherToThread();
if ( excludedPatterns != null &amp;&amp; prepare.isUrlExcluded(request, excludedPatterns)) {
chain.doFilter(request, response);
} else {
request = prepare.wrapRequest(request);
ActionMapping mapping = prepare.findActionMapping(request, response, true);
if (mapping == null) {
boolean handled = execute.executeStaticResourceRequest(request, response);
if (!handled) {
chain.doFilter(request, response);
}
} else {
execute.executeAction(request, response, mapping);
}
}
} finally {
prepare.cleanupRequest(request);
}
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;setEncodingAndLocale调用了dispatcher方法的prepare方法：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">/**
* Sets the request encoding and locale on the response
*/
public void setEncodingAndLocale(HttpServletRequest request, HttpServletResponse response) {
dispatcher.prepare(request, response);
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp; 下面我们看下prepare方法，这个方法很简单只是设置了encoding 、locale ，做的只是一些辅助的工作：</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">public void prepare(HttpServletRequest request, HttpServletResponse response) {
String encoding = null;
if (defaultEncoding != null) {
encoding = defaultEncoding;
}
Locale locale = null;
if (defaultLocale != null) {
locale = LocalizedTextUtil.localeFromString(defaultLocale, request.getLocale());
}
if (encoding != null) {
try {
request.setCharacterEncoding(encoding);
} catch (Exception e) {
LOG.error("Error setting character encoding to '" + encoding + "' - ignoring.", e);
}
}
if (locale != null) {
response.setLocale(locale);
}
if (paramsWorkaroundEnabled) {
request.getParameter("foo"); // simply read any parameter (existing or not) to "prime" the request
}
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;<strong>Action上下文创建（重点）</strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><strong></strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ActionContext是一个容器，这个容易主要存储request、session、application、parameters等相关信息.ActionContext是一个线程的本地变量，这意味着不同的action之间不会共享ActionContext，所以也不用考虑线程安全问题。其实质是一个Map，key是标示request、session、&#8230;&#8230;的字符串，值是其对应的对象：</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">static ThreadLocal actionContext = new ThreadLocal();
Map&lt;String, Object&gt; context;
</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;<br />
&nbsp;&nbsp; 下面我们看下如何创建action上下文的，代码如下：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">/**
*创建Action上下文，初始化thread local
*/
public ActionContext createActionContext(HttpServletRequest request, HttpServletResponse response) {
ActionContext ctx;
Integer counter = 1;
Integer oldCounter = (Integer) request.getAttribute(CLEANUP_RECURSION_COUNTER);
if (oldCounter != null) {
counter = oldCounter + 1;
}
//注意此处是从ThreadLocal中获取此ActionContext变量
ActionContext oldContext = ActionContext.getContext();
if (oldContext != null) {
// detected existing context, so we are probably in a forward
ctx = new ActionContext(new HashMap&lt;String, Object&gt;(oldContext.getContextMap()));
} else {
ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
stack.getContext().putAll(dispatcher.createContextMap(request, response, null, servletContext));
//stack.getContext()返回的是一个Map&lt;String，Object&gt;，根据此Map构造一个ActionContext
ctx = new ActionContext(stack.getContext());
}
request.setAttribute(CLEANUP_RECURSION_COUNTER, counter);
//将ActionContext存如ThreadLocal
ActionContext.setContext(ctx);
return ctx;
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; 上面代码中dispatcher.createContextMap，如何封装相关参数：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">public Map&lt;String,Object&gt; createContextMap(HttpServletRequest request, HttpServletResponse response,
ActionMapping mapping, ServletContext context) {
// request map wrapping the http request objects
Map requestMap = new RequestMap(request);
// parameters map wrapping the http parameters.  ActionMapping parameters are now handled and applied separately
Map params = new HashMap(request.getParameterMap());
// session map wrapping the http session
Map session = new SessionMap(request);
// application map wrapping the ServletContext
Map application = new ApplicationMap(context);
//requestMap、params、session等Map封装成为一个上下文Map，逐个调用了map.put(Map p).
Map&lt;String,Object&gt; extraContext = createContextMap(requestMap, params, session, application, request, response, context);
if (mapping != null) {
extraContext.put(ServletActionContext.ACTION_MAPPING, mapping);
}
return extraContext;
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;我们简单看下RequestMap，其他的省略。RequestMap类实现了抽象Map，故其本身是一个Map，主要方法实现：</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">//map的get实现
public Object get(Object key) {
return request.getAttribute(key.toString());
}
//map的put实现
public Object put(Object key, Object value) {
Object oldValue = get(key);
entries = null;
request.setAttribute(key.toString(), value);
return oldValue;
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp; 下面是源码展示了如何执行Action控制器：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">public void executeAction(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws ServletException {
dispatcher.serviceAction(request, response, servletContext, mapping);
}
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,
ActionMapping mapping) throws ServletException {
//封装执行的上下文环境，主要讲相关信息存储入map
Map&lt;String, Object&gt; extraContext = createContextMap(request, response, mapping, context);
// If there was a previous value stack, then create a new copy and pass it in to be used by the new Action
ValueStack stack = (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
boolean nullStack = stack == null;
if (nullStack) {
ActionContext ctx = ActionContext.getContext();
if (ctx != null) {
stack = ctx.getValueStack();
}
}
if (stack != null) {
extraContext.put(ActionContext.VALUE_STACK, valueStackFactory.createValueStack(stack));
}
String timerKey = "Handling request from Dispatcher";
try {
UtilTimerStack.push(timerKey);
//获取命名空间
String namespace = mapping.getNamespace();
//获取action配置的name属性
String name = mapping.getName();
//获取action配置的method属性
String method = mapping.getMethod();
Configuration config = configurationManager.getConfiguration();
//根据执行上下文参数，命名空间，名称等创建用户自定义Action的代理对象
ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
namespace, name, method, extraContext, true, false);
request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());
// if the ActionMapping says to go straight to a result, do it!
//执行execute方法，并转向结果
if (mapping.getResult() != null) {
Result result = mapping.getResult();
result.execute(proxy.getInvocation());
} else {
proxy.execute();
}
// If there was a previous value stack then set it back onto the request
if (!nullStack) {
request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);
}
} catch (ConfigurationException e) {
// WW-2874 Only log error if in devMode
if(devMode) {
String reqStr = request.getRequestURI();
if (request.getQueryString() != null) {
reqStr = reqStr + "?" + request.getQueryString();
}
LOG.error("Could not find action or result\n" + reqStr, e);
}
else {
LOG.warn("Could not find action or result", e);
}
sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e);
} catch (Exception e) {
sendError(request, response, context, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
} finally {
UtilTimerStack.pop(timerKey);
}
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp; 文中对如何解析Struts.xml，如何将URL与action映射匹配为分析，有需要的我后续补全，因为StrutsXmlConfigurationProvider继承XmlConfigurationProvider，并在register方法回调父类的register，有兴趣的可以深入阅读下下XmlConfigurationProvider源码：</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; "> public void register(ContainerBuilder containerBuilder, LocatableProperties props) throws ConfigurationException {
if (servletContext != null &amp;&amp; !containerBuilder.contains(ServletContext.class)) {
containerBuilder.factory(ServletContext.class, new Factory&lt;ServletContext&gt;() {
public ServletContext create(Context context) throws Exception {
return servletContext;
}
});
}
//调用父类的register，关键点所在
super.register(containerBuilder, props);
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp; struts2-core-2.2.1.jar包中struts-2.1.7.dtd对于Action的定义如下：</p>
<pre name="code" class="xml" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">&lt;!ELEMENT action (param|result|interceptor-ref|exception-mapping)*&gt;
&lt;!ATTLIST action
name CDATA #REQUIRED
class CDATA #IMPLIED
method CDATA #IMPLIED
converter CDATA #IMPLIED
&gt;</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; 从上述DTD中可见Action元素可以含有name 、class 、method 、converter 属性。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp; XmlConfigurationProvider解析struts.xml配置的Action元素：</p>
<pre name="code" class="java" style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; margin-top: 0px; margin-right: 5px; margin-bottom: 5px; margin-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #fafafa; background-position: initial initial; background-repeat: initial initial; ">   protected void addAction(Element actionElement, PackageConfig.Builder packageContext) throws ConfigurationException {
String name = actionElement.getAttribute("name");
String className = actionElement.getAttribute("class");
String methodName = actionElement.getAttribute("method");
Location location = DomHelper.getLocationObject(actionElement);
if (location == null) {
LOG.warn("location null for " + className);
}
//methodName should be null if it's not set
methodName = (methodName.trim().length() &gt; 0) ? methodName.trim() : null;
// if there isnt a class name specified for an &lt;action/&gt; then try to
// use the default-class-ref from the &lt;package/&gt;
if (StringUtils.isEmpty(className)) {
// if there is a package default-class-ref use that, otherwise use action support
/* if (StringUtils.isNotEmpty(packageContext.getDefaultClassRef())) {
className = packageContext.getDefaultClassRef();
} else {
className = ActionSupport.class.getName();
}*/
} else {
if (!verifyAction(className, name, location)) {
if (LOG.isErrorEnabled())
LOG.error("Unable to verify action [#0] with class [#1], from [#2]", name, className, location.toString());
return;
}
}
Map&lt;String, ResultConfig&gt; results;
try {
results = buildResults(actionElement, packageContext);
} catch (ConfigurationException e) {
throw new ConfigurationException("Error building results for action " + name + " in namespace " + packageContext.getNamespace(), e, actionElement);
}
List&lt;InterceptorMapping&gt; interceptorList = buildInterceptorList(actionElement, packageContext);
List&lt;ExceptionMappingConfig&gt; exceptionMappings = buildExceptionMappings(actionElement, packageContext);
ActionConfig actionConfig = new ActionConfig.Builder(packageContext.getName(), name, className)
.methodName(methodName)
.addResultConfigs(results)
.addInterceptors(interceptorList)
.addExceptionMappings(exceptionMappings)
.addParams(XmlHelper.getParams(actionElement))
.location(location)
.build();
packageContext.addActionConfig(name, actionConfig);
if (LOG.isDebugEnabled()) {
LOG.debug("Loaded " + (StringUtils.isNotEmpty(packageContext.getNamespace()) ? (packageContext.getNamespace() + "/") : "") + name + " in '" + packageContext.getName() + "' package:" + actionConfig);
}
}</pre>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br />
</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp; 工作中不涉及Struts2，本周工作有个2天的空档期，稍微看了下struts2的文档，写了个demo，从源码的角度研究了下运行原理，如有分析不当请指出，我后续逐步完善更正，大家共同提高。</p>
<div><br />
</div>
</div>
<img src ="http://www.blogjava.net/niumd/aggbug/349959.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/niumd/" target="_blank">空白</a> 2011-05-10 20:58 <a href="http://www.blogjava.net/niumd/archive/2011/05/10/349959.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>NetBean6字体配置</title><link>http://www.blogjava.net/niumd/archive/2008/09/07/227537.html</link><dc:creator>空白</dc:creator><author>空白</author><pubDate>Sun, 07 Sep 2008 05:46:00 GMT</pubDate><guid>http://www.blogjava.net/niumd/archive/2008/09/07/227537.html</guid><wfw:comment>http://www.blogjava.net/niumd/comments/227537.html</wfw:comment><comments>http://www.blogjava.net/niumd/archive/2008/09/07/227537.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/niumd/comments/commentRss/227537.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/niumd/services/trackbacks/227537.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 解决netbean、squirrel-sql-2.4.1等java开发软件,英文字体以宋体显示，让java桌面应用程序更美观&nbsp;&nbsp;<a href='http://www.blogjava.net/niumd/archive/2008/09/07/227537.html'>阅读全文</a><img src ="http://www.blogjava.net/niumd/aggbug/227537.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/niumd/" target="_blank">空白</a> 2008-09-07 13:46 <a href="http://www.blogjava.net/niumd/archive/2008/09/07/227537.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring之BeanFactory与ApplicationConText区别</title><link>http://www.blogjava.net/niumd/archive/2008/06/22/209873.html</link><dc:creator>空白</dc:creator><author>空白</author><pubDate>Sun, 22 Jun 2008 10:34:00 GMT</pubDate><guid>http://www.blogjava.net/niumd/archive/2008/06/22/209873.html</guid><wfw:comment>http://www.blogjava.net/niumd/comments/209873.html</wfw:comment><comments>http://www.blogjava.net/niumd/archive/2008/06/22/209873.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/niumd/comments/commentRss/209873.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/niumd/services/trackbacks/209873.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;使用BeanFactory从xml配置文件加载bean:
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;org.springframework.beans.factory.xml.XmlBeanFactory;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;org.springframework.core.io.FileSystemResource;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img id="Codehighlighter1_155_323_Open_Image" onclick="this.style.display='none'; Codehighlighter1_155_323_Open_Text.style.display='none'; Codehighlighter1_155_323_Closed_Image.style.display='inline'; Codehighlighter1_155_323_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_155_323_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_155_323_Closed_Text.style.display='none'; Codehighlighter1_155_323_Open_Image.style.display='inline'; Codehighlighter1_155_323_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;XmlConfigWithBeanFactory&nbsp;</span><span id="Codehighlighter1_155_323_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img id="Codehighlighter1_201_321_Open_Image" onclick="this.style.display='none'; Codehighlighter1_201_321_Open_Text.style.display='none'; Codehighlighter1_201_321_Closed_Image.style.display='inline'; Codehighlighter1_201_321_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_201_321_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_201_321_Closed_Text.style.display='none'; Codehighlighter1_201_321_Open_Image.style.display='inline'; Codehighlighter1_201_321_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;main(String[]&nbsp;args)&nbsp;</span><span id="Codehighlighter1_201_321_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XmlBeanFactory&nbsp;factory&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;XmlBeanFactory(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;FileSystemResource(<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">build/beans.xml</span><span style="color: #000000">"</span><span style="color: #000000">));<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>
&nbsp;&nbsp;&nbsp;&nbsp;使用ApplicationConText从xml配置文件加载bean:<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img id="Codehighlighter1_37_222_Open_Image" onclick="this.style.display='none'; Codehighlighter1_37_222_Open_Text.style.display='none'; Codehighlighter1_37_222_Closed_Image.style.display='inline'; Codehighlighter1_37_222_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_37_222_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_37_222_Closed_Text.style.display='none'; Codehighlighter1_37_222_Open_Image.style.display='inline'; Codehighlighter1_37_222_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;XmlConfigWithApplication</span><span id="Codehighlighter1_37_222_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img id="Codehighlighter1_82_220_Open_Image" onclick="this.style.display='none'; Codehighlighter1_82_220_Open_Text.style.display='none'; Codehighlighter1_82_220_Closed_Image.style.display='inline'; Codehighlighter1_82_220_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_82_220_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_82_220_Closed_Text.style.display='none'; Codehighlighter1_82_220_Open_Image.style.display='inline'; Codehighlighter1_82_220_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;main(String[]&nbsp;args)</span><span id="Codehighlighter1_82_220_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ApplicationContext&nbsp;application&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ClassPathXmlApplicationContext(beans.xml</span><span style="color: #000000">"</span><span style="color: #000000">));</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;application.getBean(</span><span style="color: #000000">"</span><span style="color: #000000">BeanName</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>
&nbsp;&nbsp;&nbsp;&nbsp;ApplicationContext和BeanFacotry相比,提供了更多的扩展功能，但其主要区别在于后者是延迟加载,如果Bean的某一个属性没有注入，BeanFacotry加载后，直至第一次使用调用getBean方法才会抛出异常；而ApplicationContext则在初始化自身是检验，这样有利于检查所依赖属性是否注入；所以通常情况下我们选择使用ApplicationContext. 
<img src ="http://www.blogjava.net/niumd/aggbug/209873.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/niumd/" target="_blank">空白</a> 2008-06-22 18:34 <a href="http://www.blogjava.net/niumd/archive/2008/06/22/209873.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Xfire开发WebService</title><link>http://www.blogjava.net/niumd/archive/2008/06/20/209404.html</link><dc:creator>空白</dc:creator><author>空白</author><pubDate>Fri, 20 Jun 2008 04:10:00 GMT</pubDate><guid>http://www.blogjava.net/niumd/archive/2008/06/20/209404.html</guid><wfw:comment>http://www.blogjava.net/niumd/comments/209404.html</wfw:comment><comments>http://www.blogjava.net/niumd/archive/2008/06/20/209404.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/niumd/comments/commentRss/209404.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/niumd/services/trackbacks/209404.html</trackback:ping><description><![CDATA[MyEclipse中和许多网站的WebService教程以HelloWord为例,内容比较简单,在实际的项目应用中大多都是对象和集合,现在我们扩展下,使用webservice传递对象,字符串,集合;<br />
下面是我们设计的webservice的接口:
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #008080">&nbsp;1</span><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;com.test.service;<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.util.List;<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img id="Codehighlighter1_76_232_Open_Image" onclick="this.style.display='none'; Codehighlighter1_76_232_Open_Text.style.display='none'; Codehighlighter1_76_232_Closed_Image.style.display='inline'; Codehighlighter1_76_232_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_76_232_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_76_232_Closed_Text.style.display='none'; Codehighlighter1_76_232_Open_Image.style.display='inline'; Codehighlighter1_76_232_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">interface</span><span style="color: #000000">&nbsp;IPerson&nbsp;</span><span id="Codehighlighter1_76_232_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">根据用户名获取密码</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #008000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;String&nbsp;getPassword(String&nbsp;name);<br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">根据用户名获取Person对象</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #008000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;Person&nbsp;getPersonByName();<br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">获取全部成员</span><span style="color: #008000"><br />
</span><span style="color: #008080">11</span><span style="color: #008000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;List</span><span style="color: #000000">&lt;</span><span style="color: #000000">Person</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;getAllPerson();<br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div>
<br />
其中有三个方法包含了传递:String,Object,List集合;<br />
2,这里我们实现接口中定义的业务逻辑<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;com.test.service;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.util.LinkedList;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.util.List;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img id="Codehighlighter1_123_516_Open_Image" onclick="this.style.display='none'; Codehighlighter1_123_516_Open_Text.style.display='none'; Codehighlighter1_123_516_Closed_Image.style.display='inline'; Codehighlighter1_123_516_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_123_516_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_123_516_Closed_Text.style.display='none'; Codehighlighter1_123_516_Open_Image.style.display='inline'; Codehighlighter1_123_516_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;PersonImpl&nbsp;</span><span style="color: #0000ff">implements</span><span style="color: #000000">&nbsp;IPerson&nbsp;</span><span id="Codehighlighter1_123_516_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img id="Codehighlighter1_169_196_Open_Image" onclick="this.style.display='none'; Codehighlighter1_169_196_Open_Text.style.display='none'; Codehighlighter1_169_196_Closed_Image.style.display='inline'; Codehighlighter1_169_196_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_169_196_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_169_196_Closed_Text.style.display='none'; Codehighlighter1_169_196_Open_Image.style.display='inline'; Codehighlighter1_169_196_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;String&nbsp;getPassword(String&nbsp;name)&nbsp;</span><span id="Codehighlighter1_169_196_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">Password</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img id="Codehighlighter1_232_286_Open_Image" onclick="this.style.display='none'; Codehighlighter1_232_286_Open_Text.style.display='none'; Codehighlighter1_232_286_Closed_Image.style.display='inline'; Codehighlighter1_232_286_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_232_286_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_232_286_Closed_Text.style.display='none'; Codehighlighter1_232_286_Open_Image.style.display='inline'; Codehighlighter1_232_286_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;Person&nbsp;getPersonByName()&nbsp;</span><span id="Codehighlighter1_232_286_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Person(</span><span style="color: #000000">"</span><span style="color: #000000">ObjectName</span><span style="color: #000000">"</span><span style="color: #000000">,</span><span style="color: #000000">"</span><span style="color: #000000">ObjectPass</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img id="Codehighlighter1_334_514_Open_Image" onclick="this.style.display='none'; Codehighlighter1_334_514_Open_Text.style.display='none'; Codehighlighter1_334_514_Closed_Image.style.display='inline'; Codehighlighter1_334_514_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_334_514_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_334_514_Closed_Text.style.display='none'; Codehighlighter1_334_514_Open_Image.style.display='inline'; Codehighlighter1_334_514_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;java.util.List</span><span style="color: #000000">&lt;</span><span style="color: #000000">Person</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;getAllPerson()</span><span id="Codehighlighter1_334_514_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;list&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;LinkedList();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.add(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Person(</span><span style="color: #000000">"</span><span style="color: #000000">One</span><span style="color: #000000">"</span><span style="color: #000000">,</span><span style="color: #000000">"</span><span style="color: #000000">PassOne</span><span style="color: #000000">"</span><span style="color: #000000">));<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.add(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Person(</span><span style="color: #000000">"</span><span style="color: #000000">Two</span><span style="color: #000000">"</span><span style="color: #000000">,</span><span style="color: #000000">"</span><span style="color: #000000">PassTwo</span><span style="color: #000000">"</span><span style="color: #000000">));<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.add(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Person(</span><span style="color: #000000">"</span><span style="color: #000000">Three</span><span style="color: #000000">"</span><span style="color: #000000">,</span><span style="color: #000000">"</span><span style="color: #000000">PassThree</span><span style="color: #000000">"</span><span style="color: #000000">));<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;list;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div>
<br />
在实际应用中比较复杂,可能用调用持久层的Dao,返回需要的结果,这里我们直接创建一个模拟数据,下面是实现类中用到的对象<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #008080">&nbsp;1</span><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;com.test.service;<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img id="Codehighlighter1_47_366_Open_Image" onclick="this.style.display='none'; Codehighlighter1_47_366_Open_Text.style.display='none'; Codehighlighter1_47_366_Closed_Image.style.display='inline'; Codehighlighter1_47_366_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_47_366_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_47_366_Closed_Text.style.display='none'; Codehighlighter1_47_366_Open_Image.style.display='inline'; Codehighlighter1_47_366_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Person&nbsp;</span><span id="Codehighlighter1_47_366_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;String&nbsp;name;<br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;String&nbsp;password;<br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img id="Codehighlighter1_116_130_Open_Image" onclick="this.style.display='none'; Codehighlighter1_116_130_Open_Text.style.display='none'; Codehighlighter1_116_130_Closed_Image.style.display='inline'; Codehighlighter1_116_130_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_116_130_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_116_130_Closed_Text.style.display='none'; Codehighlighter1_116_130_Open_Image.style.display='inline'; Codehighlighter1_116_130_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;Person()&nbsp;</span><span id="Codehighlighter1_116_130_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">super</span><span style="color: #000000">();<br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img id="Codehighlighter1_176_238_Open_Image" onclick="this.style.display='none'; Codehighlighter1_176_238_Open_Text.style.display='none'; Codehighlighter1_176_238_Closed_Image.style.display='inline'; Codehighlighter1_176_238_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_176_238_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_176_238_Closed_Text.style.display='none'; Codehighlighter1_176_238_Open_Image.style.display='inline'; Codehighlighter1_176_238_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;Person(String&nbsp;name,&nbsp;String&nbsp;password)</span><span id="Codehighlighter1_176_238_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">super</span><span style="color: #000000">();<br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.name&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;name;<br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.password&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;password;<br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">15</span><span style="color: #000000"><img id="Codehighlighter1_268_290_Open_Image" onclick="this.style.display='none'; Codehighlighter1_268_290_Open_Text.style.display='none'; Codehighlighter1_268_290_Closed_Image.style.display='inline'; Codehighlighter1_268_290_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_268_290_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_268_290_Closed_Text.style.display='none'; Codehighlighter1_268_290_Open_Image.style.display='inline'; Codehighlighter1_268_290_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;String&nbsp;getPassword()</span><span id="Codehighlighter1_268_290_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;password;<br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">18</span><span style="color: #000000"><img id="Codehighlighter1_333_364_Open_Image" onclick="this.style.display='none'; Codehighlighter1_333_364_Open_Text.style.display='none'; Codehighlighter1_333_364_Closed_Image.style.display='inline'; Codehighlighter1_333_364_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_333_364_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_333_364_Closed_Text.style.display='none'; Codehighlighter1_333_364_Open_Image.style.display='inline'; Codehighlighter1_333_364_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;setPassword(String&nbsp;password)</span><span id="Codehighlighter1_333_364_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">19</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.password&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;password;<br />
</span><span style="color: #008080">20</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">21</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">22</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>
<br />
3,编写XFire要求的WebSevice定义描述文件，如下：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">&lt;?</span><span style="color: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"</span><span style="color: #0000ff">?&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">beans&nbsp;</span><span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="http://xfire.codehaus.org/config/1.0"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">service</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">Person</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">serviceClass</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">com.test.service.IPerson</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">serviceClass</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">implementationClass</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;com.test.service.PersonImpl<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">implementationClass</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">style</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">wrapped</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">style</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">use</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">literal</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">use</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">scope</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">application</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">scope</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">service</span><span style="color: #0000ff">&gt;&lt;/</span><span style="color: #800000">beans</span><span style="color: #0000ff">&gt;</span></div>
本文件的放置位置很关键,此文件放在src/META-INF/xfire/services.xml，如果使用MyEclipse新建的不是webapplication,而是webservice项目,这一步就省去自己编写了,编译时会自动编译到classes的相应目录下面。web.z<br />
5,编译xml,定义XfireConfigableServlet<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #008080">&nbsp;1</span><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;?</span><span style="color: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"</span><span style="color: #0000ff">?&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">web-app&nbsp;</span><span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="http://java.sun.com/xml/ns/j2ee"</span><span style="color: #ff0000">&nbsp;xmlns:xsi</span><span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema-instance"</span><span style="color: #ff0000">&nbsp;version</span><span style="color: #0000ff">="2.4"</span><span style="color: #ff0000">&nbsp;xsi:schemaLocation</span><span style="color: #0000ff">="http://java.sun.com/xml/ns/j2ee&nbsp;&nbsp;&nbsp;http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">servlet</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">servlet-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">XFireServlet</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">servlet-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">servlet-class</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">org.codehaus.xfire.transport.http.XFireConfigurableServlet</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">servlet-class</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">load-on-startup</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">0</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">load-on-startup</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">servlet</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">servlet-mapping</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">servlet-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">XFireServlet</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">servlet-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">url-pattern</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">/services/*</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">url-pattern</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">servlet-mapping</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">welcome-file-list</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">welcome-file</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">index.jsp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">welcome-file</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">welcome-file-list</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">15</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">web-app</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
所有的工作都已经作完，接下来在部署在tomcate下，启动服务器，在地址栏键入：<a href="http://127.0.0.1:8080/MyWebService/srevice/Person?wsdl">http://127.0.0.1:8080/MyWebService/srevice/Person?wsdl</a><br />
如果出现xml描述文件就成功了；<br />
<br />
<br />
 <img src ="http://www.blogjava.net/niumd/aggbug/209404.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/niumd/" target="_blank">空白</a> 2008-06-20 12:10 <a href="http://www.blogjava.net/niumd/archive/2008/06/20/209404.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>