<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>Dev Notes</title>
	<atom:link href="http://dev.ymeng.net/feed" rel="self" type="application/rss+xml" />
	<link>http://dev.ymeng.net</link>
	<description></description>
	<pubDate>Sat, 05 Jun 2010 15:06:46 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>确定当前Python环境中的site-packages目录位置</title>
		<link>http://dev.ymeng.net/find-site-packages-folder.html</link>
		<comments>http://dev.ymeng.net/find-site-packages-folder.html#comments</comments>
		<pubDate>Thu, 23 Jul 2009 02:13:23 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=174</guid>
		<description><![CDATA[How to find the site-packages folder in Python?
在Mac OS或者Linux中比较有用，因为这些系统一般都同时安装了多个版本。尤其是Mac OS 10.5，目录结构太乱了
在python环境中：

1
2
from distutils.sysconfig import get_python_lib
print get_python_lib&#40;&#41;

或者，直接命令行：

1
python -c &#34;from distutils.sysconfig import get_python_lib; print get_python_lib()&#34;

]]></description>
			<content:encoded><![CDATA[<p>How to find the <strong><em>site-packages</em></strong> folder in Python?</p>
<p>在Mac OS或者Linux中比较有用，因为这些系统一般都同时安装了多个版本。尤其是Mac OS 10.5，目录结构太乱了</p>
<p>在python环境中：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">distutils</span>.<span style="color: black;">sysconfig</span> <span style="color: #ff7700;font-weight:bold;">import</span> get_python_lib
<span style="color: #ff7700;font-weight:bold;">print</span> get_python_lib<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>或者，直接命令行：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="python" style="font-family:monospace;">python -c <span style="color: #483d8b;">&quot;from distutils.sysconfig import get_python_lib; print get_python_lib()&quot;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/find-site-packages-folder.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Oracle宣布收购Sun</title>
		<link>http://dev.ymeng.net/oracle-buys-sun.html</link>
		<comments>http://dev.ymeng.net/oracle-buys-sun.html#comments</comments>
		<pubDate>Mon, 20 Apr 2009 14:46:56 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[Acquire]]></category>

		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[Oracle]]></category>

		<category><![CDATA[Sun]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=164</guid>
		<description><![CDATA[这是一个大新闻，不知道以后Java会是什么样子～～
MySQL又可以使用InnoDB了

]]></description>
			<content:encoded><![CDATA[<p>这是一个大新闻，不知道以后Java会是什么样子～～</p>
<p>MySQL又可以使用InnoDB了</p>
<p><img class="alignnone size-full wp-image-170" title="Oracle buys Sun" src="http://dev.ymeng.net/wp-content/uploads/2009/04/oracle-buys-sun.png" alt="Oracle buys Sun" width="624" height="335" /></p>
]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/oracle-buys-sun.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>WireframeSketcher - a UI design plugin for Eclipse</title>
		<link>http://dev.ymeng.net/wireframesketcher.html</link>
		<comments>http://dev.ymeng.net/wireframesketcher.html#comments</comments>
		<pubDate>Sat, 28 Mar 2009 15:16:22 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[Develop Tool]]></category>

		<category><![CDATA[Design]]></category>

		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=160</guid>
		<description><![CDATA[今天又发现了一个UI设计工具－－WireframeSketcher，和上一个工具差不多，用来进入界面草图设计，不过WireframeSketcher是一个Eclipse插件，如果开发环境是基于Eclipse，可能会方便很多。
不过也有一些问题，比如没有MenuItem，没有快速搜索Component的功能，在Component列表中不支持滚动。
对于License，也可以通过blog推广的方式来获取，试一下  
网站：http://wireframesketcher.com/index.html

]]></description>
			<content:encoded><![CDATA[<p>今天又发现了一个UI设计工具－－<a href="http://wireframesketcher.com/index.html" target="_blank">WireframeSketcher</a>，和上一个工具差不多，用来进入界面草图设计，不过WireframeSketcher是一个Eclipse插件，如果开发环境是基于Eclipse，可能会方便很多。</p>
<p>不过也有一些问题，比如没有MenuItem，没有快速搜索Component的功能，在Component列表中不支持滚动。</p>
<p>对于License，也可以通过blog推广的方式来获取，试一下 <img src='http://dev.ymeng.net/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>网站：<a href="http://wireframesketcher.com/index.html" target="_blank">http://wireframesketcher.com/index.html</a></p>
<p><a href="http://picasaweb.google.com/lh/photo/aoavwZWK2Sx5A5p8jD2ZzA?feat=embedwebsite" target="_blank"><img src="http://lh4.ggpht.com/_yN_LeFUyx_o/Sc47wIhhUHI/AAAAAAAAAIU/Nyd5Frg3SCY/s400/WireframeSketcher.png" alt="" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/wireframesketcher.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Mockups For Desktop</title>
		<link>http://dev.ymeng.net/mockups-for-desktop.html</link>
		<comments>http://dev.ymeng.net/mockups-for-desktop.html#comments</comments>
		<pubDate>Sat, 07 Feb 2009 13:24:06 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[Develop Tool]]></category>

		<category><![CDATA[Design]]></category>

		<category><![CDATA[Mockups For Desktop]]></category>

		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=146</guid>
		<description><![CDATA[今天在网上发现一个不错的工具，Mockups For Desktop，一款基于Adobe AIR的程序，使用它可以非常快捷地设计出程序界面。
Mockups For Desktop提供了很多“控件”进行选择，Button, Checkbox, Dialog Windows等等，直接拖到设计区域就可以，效果看起来像“手绘”的草图，感觉相当不错。
下面是偶画的一个程序界面：

程序没有右键菜单，感觉挺奇怪的，而且似乎不支持中文字符输入。
售价$79，不过可以通过Blog推广等方式来免费获取注册码。未注册版本还不能保存设计稿，这点相当不爽。
================
2月9日更新：
昨晚发布了日志后，马上给作者发了邮件，告知已经在Blog上进行推广，另外还有右键菜单建议和中文问题，今天就收到了作者的回复，他们会在以后的版本中增加右键功能菜单；如果需要输入中文，则可以在View菜单下，选中Use System Fonts，即可支持中文输入。

使用作者提供的注册码激活后，就可以保存文件了，格式为BMML，其实是一个XML格式的文件。
下载 Mockups For Desktop
]]></description>
			<content:encoded><![CDATA[<p>今天在网上发现一个不错的工具，<a href="http://www.balsamiq.com/products/mockups/desktop" target="_blank">Mockups For Desktop</a>，一款基于Adobe AIR的程序，使用它可以非常快捷地设计出程序界面。</p>
<p>Mockups For Desktop提供了很多“控件”进行选择，Button, Checkbox, Dialog Windows等等，直接拖到设计区域就可以，效果看起来像“手绘”的草图，感觉相当不错。</p>
<p>下面是偶画的一个程序界面：<br />
<a href="http://picasaweb.google.com/lh/photo/FUyhctaYyWHnu5PWoABY3A?feat=embedwebsite" target="_blank"><img src="http://lh6.ggpht.com/_yN_LeFUyx_o/SY2GGRkz6MI/AAAAAAAAADw/BwqDndAygac/s400/Balsamiq%20Mockups.png" /></a></p>
<p>程序没有右键菜单，感觉挺奇怪的，而且似乎不支持中文字符输入。<br />
售价$79，不过可以通过Blog推广等方式来免费获取注册码。未注册版本还不能保存设计稿，这点相当不爽。</p>
<p>================<br />
2月9日更新：<br />
昨晚发布了日志后，马上给作者发了邮件，告知已经在Blog上进行推广，另外还有右键菜单建议和中文问题，今天就收到了作者的回复，他们会在以后的版本中增加右键功能菜单；如果需要输入中文，则可以在View菜单下，选中Use System Fonts，即可支持中文输入。</p>
<p><a href="http://picasaweb.google.com/lh/photo/yeuIvZ6vdBIR5Ear-3-sKQ?feat=embedwebsite" target="_blank"><img src="http://lh6.ggpht.com/_yN_LeFUyx_o/SY7fAU6iB7I/AAAAAAAAAEU/TN26AfY_3ng/s400/Balsamiq%20Mockups%20-%20Chinese.png" /></a></p>
<p>使用作者提供的注册码激活后，就可以保存文件了，格式为BMML，其实是一个XML格式的文件。</p>
<p><a href="http://www.balsamiq.com/products/mockups/desktop" target="_blank">下载 Mockups For Desktop</a></p>
]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/mockups-for-desktop.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>使用JBoss Seam提供的Converter</title>
		<link>http://dev.ymeng.net/converter-in-jboss-seam.html</link>
		<comments>http://dev.ymeng.net/converter-in-jboss-seam.html#comments</comments>
		<pubDate>Mon, 29 Dec 2008 02:44:37 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[JBoss Seam]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Converter]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=101</guid>
		<description><![CDATA[在Seam中，使用&#60;s:convertEntity/&#62;或者&#60;s:convertEnum/&#62;会方便很多，Seam会自动将用户选中的Entity实例放到对应选择标签的value中。
]]></description>
			<content:encoded><![CDATA[<p>在Seam中，使用&lt;s:convertEntity/&gt;或者&lt;s:convertEnum/&gt;会方便很多，Seam会自动将用户选中的Entity实例放到对应选择标签的value中。</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/converter-in-jboss-seam.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>在JBoss Seam中使用GWT</title>
		<link>http://dev.ymeng.net/integrate-gwt-into-jboss-seam.html</link>
		<comments>http://dev.ymeng.net/integrate-gwt-into-jboss-seam.html#comments</comments>
		<pubDate>Tue, 09 Dec 2008 13:07:37 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[GWT]]></category>

		<category><![CDATA[JBoss Seam]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Google Web Toolkit]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=128</guid>
		<description><![CDATA[这几天在JBoss Seam集成GWT，试了很多时间，总结出一些问题：
JBoss Seam版本：2.1.0.SP1
Google Web Toolkit版本：1.5.3

gwt-servlet.jar版本问题：Seam中自带的gwt-servlet.jar版本可能和你使用的GWT版本不一致，如果你编译GWT程序的版本与Seam中gwt-servlet.jar版本不一致，可能会出现一些奇怪的问题，最好的办法是将Seam中的gwt-servlet.jar换成GWT中带的jar。
Seam Resource Servlet的配置和GWT程序中Service Entry Point的设置：Seam中的默认url pattern是/seam/resource/*，所以Seam会把对/seam/resource/gwt/*的请求发送给org.jboss.seam.remoting.gwt.GWT14Service处理，GWTService才会根据GWT客户端发送的请求类和方法来进行调用。需要注意的是，根据跟踪Seam的GWTService发现，客户端发送的请求类似于“5&#124;0&#124;6&#124;http://127.0.0.1:8080/SeamGWT/&#124;5BA8A5B3E35F40698BB0BF65F390BCF2&#124;com.tiandinet.gwt.hello.client.HelloService&#124;sayHello&#124;java.lang.String&#124;your name&#124;1&#124;2&#124;3&#124;4&#124;1&#124;5&#124;6&#124;”，而Seam的GWTService.getResource会根据com.tiandinet.gwt.hello.client.HelloService名称查找Seam组件，此组件即为GWT中的远程服务接口的Seam实现，所以在设置此实现类的@Name属性时，需要将其设置为GWT中远程服务接口的类名。
所以，对于Service Entry Point的设置，只要URL能匹配到/seam/resource/gwt/即可，而Seam Reference示例中的String endpointURL = GWT.getModuleBaseURL() + &#8220;seam/resource/gwt&#8221;;可能不一定正确，因为根据GWT编译后页面路径在Seam应用中所处的位置不同，GWT.getModuleBaseURL()返回的路径可能就不能匹配到/seam/resource/gwt。
Seam Resource Servlet映射
/web=org.jboss.seam.ui.resource.WebResource
/captcha=org.jboss.seam.captcha.CaptchaImage
/remoting=org.jboss.seam.remoting.Remoting
/gwt=org.jboss.seam.remoting.gwt.GWT14Service
/graphicImage=org.jboss.seam.ui.graphicImage.GraphicImageResource

]]></description>
			<content:encoded><![CDATA[<p>这几天在JBoss Seam集成GWT，试了很多时间，总结出一些问题：</p>
<p>JBoss Seam版本：2.1.0.SP1</p>
<p>Google Web Toolkit版本：1.5.3</p>
<ol>
<li>gwt-servlet.jar版本问题：Seam中自带的gwt-servlet.jar版本可能和你使用的GWT版本不一致，如果你编译GWT程序的版本与Seam中gwt-servlet.jar版本不一致，可能会出现一些奇怪的问题，最好的办法是将Seam中的gwt-servlet.jar换成GWT中带的jar。</li>
<li>Seam Resource Servlet的配置和GWT程序中Service Entry Point的设置：Seam中的默认url pattern是/seam/resource/*，所以Seam会把对/seam/resource/gwt/*的请求发送给org.jboss.seam.remoting.gwt.GWT14Service处理，GWTService才会根据GWT客户端发送的请求类和方法来进行调用。需要注意的是，根据跟踪Seam的GWTService发现，客户端发送的请求类似于“<strong>5|0|6|http://127.0.0.1:8080/SeamGWT/|5BA8A5B3E35F40698BB0BF65F390BCF2|com.tiandinet.gwt.hello.client.HelloService|sayHello|java.lang.String|your name|1|2|3|4|1|5|6|</strong>”，而Seam的GWTService.getResource会根据com.tiandinet.gwt.hello.client.HelloService名称查找Seam组件，此组件即为GWT中的远程服务接口的Seam实现，所以在设置此实现类的@Name属性时，需要将其设置为GWT中远程服务接口的类名。<br />
所以，对于Service Entry Point的设置，只要URL能匹配到/seam/resource/gwt/即可，而Seam Reference示例中的String endpointURL = GWT.getModuleBaseURL() + &#8220;seam/resource/gwt&#8221;;可能不一定正确，因为根据GWT编译后页面路径在Seam应用中所处的位置不同，GWT.getModuleBaseURL()返回的路径可能就不能匹配到/seam/resource/gwt。</li>
<li>Seam Resource Servlet映射<br />
/web=org.jboss.seam.ui.resource.WebResource<br />
/captcha=org.jboss.seam.captcha.CaptchaImage<br />
/remoting=org.jboss.seam.remoting.Remoting<br />
/gwt=org.jboss.seam.remoting.gwt.GWT14Service<br />
/graphicImage=org.jboss.seam.ui.graphicImage.GraphicImageResource</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/integrate-gwt-into-jboss-seam.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Eclipse Ganymede下Subclipse插件的安装</title>
		<link>http://dev.ymeng.net/eclipse-ganymede-plugin-subclipse.html</link>
		<comments>http://dev.ymeng.net/eclipse-ganymede-plugin-subclipse.html#comments</comments>
		<pubDate>Mon, 17 Nov 2008 13:54:13 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[Develop Tool]]></category>

		<category><![CDATA[Eclipse]]></category>

		<category><![CDATA[Subclipse]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=124</guid>
		<description><![CDATA[Eclipse Ganymede (Eclipse 3.4)版本出来很久了，一直没有在这个版本上搞定离线安装subclipse插件，不论是link，还是copy到dropins目录，却无法识别插件，今天在Mac上捣鼓时无意间问了Roy一句，他说3.4版本下的插件似乎不能有site.xml文件，否则好象会被认为在线安装。我随手删除掉site.xml，重新启动eclipse，居然装好了  
]]></description>
			<content:encoded><![CDATA[<p>Eclipse Ganymede (Eclipse 3.4)版本出来很久了，一直没有在这个版本上搞定离线安装subclipse插件，不论是link，还是copy到dropins目录，却无法识别插件，今天在Mac上捣鼓时无意间问了Roy一句，他说3.4版本下的插件似乎不能有site.xml文件，否则好象会被认为在线安装。我随手删除掉site.xml，重新启动eclipse，居然装好了 <img src='http://dev.ymeng.net/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/eclipse-ganymede-plugin-subclipse.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Java中的初始化块</title>
		<link>http://dev.ymeng.net/java-initiateblock.html</link>
		<comments>http://dev.ymeng.net/java-initiateblock.html#comments</comments>
		<pubDate>Sat, 01 Nov 2008 13:05:01 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[初始化块]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=120</guid>
		<description><![CDATA[在Java中，有两种初始化块：静态初始化块和非静态初始化块。
静态初始化块：使用static定义，当类装载到系统时执行一次。若在静态初始化块中想初始化变量，那仅能初始化类变量，即static修饰的数据成员。
非静态初始化块：在每个对象生成时都会被执行一次，可以初始化类的实例变量。
非静态初始化块会在构造函数执行时，且在构造函数主体代码执行之前被运行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.tiandinet.studyjava;
&#160;
public class TestInitiateBlock &#123;
&#160;
    &#123;
        System.out.println&#40;&#34;In non-static initialization block!&#34;&#41;;
    &#125;;
&#160;
    static &#123;
        System.out.println&#40;&#34;In static initialization block!&#34;&#41;;
    &#125;;
&#160;
    public TestInitiateBlock&#40;&#41; &#123;
      [...]]]></description>
			<content:encoded><![CDATA[<p>在Java中，有两种初始化块：静态初始化块和非静态初始化块。</p>
<p><strong>静态初始化块：</strong>使用static定义，当类装载到系统时执行一次。若在静态初始化块中想初始化变量，那仅能初始化类变量，即static修饰的数据成员。<br />
<strong>非静态初始化块：</strong>在每个对象生成时都会被执行一次，可以初始化类的实例变量。</p>
<p>非静态初始化块会在构造函数执行时，且在构造函数主体代码执行之前被运行。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.tiandinet.studyjava</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> TestInitiateBlock <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;In non-static initialization block!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;In static initialization block!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> TestInitiateBlock<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;In Constructor1!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> show<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;In show()!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #008000; font-style: italic; font-weight: bold;">/**
     * @param args
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        TestInitiateBlock ti <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> TestInitiateBlock<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        ti.<span style="color: #006633;">show</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>运行结果：<br />
In static initialization block!<br />
In non-static initialization block!<br />
In Constructor1!<br />
In show()!</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/java-initiateblock.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Linux下安装memcached和编译PHP扩展</title>
		<link>http://dev.ymeng.net/linux-memcached-install.html</link>
		<comments>http://dev.ymeng.net/linux-memcached-install.html#comments</comments>
		<pubDate>Tue, 07 Oct 2008 12:56:42 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[memcached]]></category>

		<category><![CDATA[LAMP]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=106</guid>
		<description><![CDATA[虽然之前一直做PHP的开发，但一直没有用过memcache，仅是知道一些简单的原理。今天突然来兴趣，想试一下memcache，和PHP下的调用。
1. 安装memcached (服务器版本1.2.6)
服务器OS是RHEL5(Red Hat Linux Enterprise 5)，之前已经装好LAMP环境，这是我们的一台测试服务器，LAMP均位于/opt/lamp下。准备将memcached安装在/opt/cache/memcached目录下。
memcached需要libevent(http://monkey.org/~provos/libevent/)的支持，所以需要先安装libevent，安装目录位于/opt/cache/libevent，下载最新版本的libevent（此例中为1.4.8），解压后进入源代码目录，进行配置和安装。

./configure --prefix=/opt/cache/libevent
&#160;
make
&#160;
make install

接着安装memcached，使用的版本是1.2.6，进入解压后的源代码目录，

./configure --prefix=/opt/cache/memcached --with-libevent=/opt/cache/libevent

&#8211;with-libevent指令指定libevent的目录


make
&#160;
make install

安装完成，试着使用

/opt/cache/memcached/bin/memcached -d -m 16 -p 33333 -u memcached -l 127.0.0.1

启动memcached服务器，但会报错，
error while loading shared libraries: libevent-1.4.so.2: cannot open shared object file: No such file or directory
意思是memcached无法找到libevent-1.4.so.2这个文件，但明明是指定了libevent的安装目录，为什么找不到呢？
memcached其实是到/usr/lib/目录下去找libevent的so文件，但我在安装时指定的libevent是位于/opt/cache/libevent，所以解决办法是在/usr/lib目录下创建一个文件链接（不知道算不算一个bug）

ln -s /opt/cache/libevent/lib/libevent-1.4.so.2 /usr/lib/libevent-1.4.so.2

再次启动memcached，一切正常。
2. 编译PHP的memcache扩展　(扩展版本2.2.4)
PHP的memcache是PECL下的一个包，下载地址位于http://pecl.php.net/package/memcache，因为这台服务器之前已经装好了PHP环境，所以我们直接将下载的tar包解压到PHP源代码目录下的ext目录中，进入memcache-2.2.4目录，使用phpize生成configure等配置文件

/opt/lamp/php/bin/phpize

配置

./configure --with-php-config=/opt/lamp/php/bin/php-config --enable-shared --enable-static

但此处会报错，提示找不到php_session.h头文件，该文件位于PHP源文件目录下的ext/session下，可以通过修改configure文件，设置正确的session_inc_path变量，指向PHP源文件目录/opt/lamp/php-5.2.5即可，重新configure即可通过。
接着调用make，会在module目录下生成memcache.so文件，将此文件拷贝到PHP的extension目录，再修改php.ini，重启httpd就完成了memcache扩展的配置。
值得注意的是，在编译扩展时，并不需要使用make install命令。
]]></description>
			<content:encoded><![CDATA[<p>虽然之前一直做PHP的开发，但一直没有用过memcache，仅是知道一些简单的原理。今天突然来兴趣，想试一下memcache，和PHP下的调用。</p>
<p><strong>1. 安装memcached (服务器版本1.2.6)</strong></p>
<p>服务器OS是RHEL5(Red Hat Linux Enterprise 5)，之前已经装好LAMP环境，这是我们的一台测试服务器，LAMP均位于/opt/lamp下。准备将memcached安装在/opt/cache/memcached目录下。</p>
<p>memcached需要libevent(<a href="http://monkey.org/~provos/libevent/">http://monkey.org/~provos/libevent/</a>)的支持，所以需要先安装libevent，安装目录位于/opt/cache/libevent，下载最新版本的libevent（此例中为1.4.8），解压后进入源代码目录，进行配置和安装。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>configure <span style="color: #660033;">--prefix</span>=<span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>cache<span style="color: #000000; font-weight: bold;">/</span>libevent
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">make</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">install</span></pre></div></div>

<p>接着安装memcached，使用的版本是1.2.6，进入解压后的源代码目录，</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>configure <span style="color: #660033;">--prefix</span>=<span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>cache<span style="color: #000000; font-weight: bold;">/</span>memcached <span style="color: #660033;">--with-libevent</span>=<span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>cache<span style="color: #000000; font-weight: bold;">/</span>libevent</pre></div></div>

<p>&#8211;with-libevent指令指定libevent的目录<br />
<span id="more-106"></span></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">make</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">install</span></pre></div></div>

<p>安装完成，试着使用</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>cache<span style="color: #000000; font-weight: bold;">/</span>memcached<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>memcached <span style="color: #660033;">-d</span> <span style="color: #660033;">-m</span> <span style="color: #000000;">16</span> <span style="color: #660033;">-p</span> <span style="color: #000000;">33333</span> <span style="color: #660033;">-u</span> memcached <span style="color: #660033;">-l</span> 127.0.0.1</pre></div></div>

<p>启动memcached服务器，但会报错，<br />
error while loading shared libraries: libevent-1.4.so.2: cannot open shared object file: No such file or directory</p>
<p>意思是memcached无法找到libevent-1.4.so.2这个文件，但明明是指定了libevent的安装目录，为什么找不到呢？</p>
<p>memcached其实是到/usr/lib/目录下去找libevent的so文件，但我在安装时指定的libevent是位于/opt/cache/libevent，所以解决办法是在/usr/lib目录下创建一个文件链接（不知道算不算一个bug）</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>cache<span style="color: #000000; font-weight: bold;">/</span>libevent<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>libevent-1.4.so.2 <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>libevent-1.4.so.2</pre></div></div>

<p>再次启动memcached，一切正常。</p>
<p><strong>2. 编译PHP的memcache扩展　(扩展版本2.2.4)</strong><br />
PHP的memcache是PECL下的一个包，下载地址位于<a href="http://pecl.php.net/package/memcache">http://pecl.php.net/package/memcache</a>，因为这台服务器之前已经装好了PHP环境，所以我们直接将下载的tar包解压到PHP源代码目录下的ext目录中，进入memcache-2.2.4目录，使用phpize生成configure等配置文件</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>lamp<span style="color: #000000; font-weight: bold;">/</span>php<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>phpize</pre></div></div>

<p>配置</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>configure <span style="color: #660033;">--with-php-config</span>=<span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>lamp<span style="color: #000000; font-weight: bold;">/</span>php<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>php-config <span style="color: #660033;">--enable-shared</span> <span style="color: #660033;">--enable-static</span></pre></div></div>

<p>但此处会报错，提示找不到php_session.h头文件，该文件位于PHP源文件目录下的ext/session下，可以通过修改configure文件，设置正确的session_inc_path变量，指向PHP源文件目录/opt/lamp/php-5.2.5即可，重新configure即可通过。</p>
<p>接着调用make，会在module目录下生成memcache.so文件，将此文件拷贝到PHP的extension目录，再修改php.ini，重启httpd就完成了memcache扩展的配置。</p>
<p>值得注意的是，在编译扩展时，并不需要使用make install命令。</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/linux-memcached-install.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>解决自定义文件上传处理与Spring MultipartResolver的冲突问题</title>
		<link>http://dev.ymeng.net/spring-multipartresolver-conflict.html</link>
		<comments>http://dev.ymeng.net/spring-multipartresolver-conflict.html#comments</comments>
		<pubDate>Sun, 07 Sep 2008 03:41:49 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[Spring]]></category>

		<category><![CDATA[File Upload]]></category>

		<category><![CDATA[Multipart]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=82</guid>
		<description><![CDATA[　　在原项目中，对文件上传的处理并不是使用Spring的MultipartResolver，而是使用自定义的MultiPartFilter和HttpServletRequestWrapper结合来进行处理。
　　MultiPartFilter是一个定义在web.xml中的&#60;filter&#62;，原理是通过判断HttpServletRequest中的contentType是否包含&#8221;multipart/form-data&#8221;，若代码中包含此字符品，则表明是一个File Upload请求，就使用JakartaMultiPartRequest来对HttpServletRequest对其进行包装。
　　其代码如下：

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class MultiPartFilter extends GenericFilterBean &#123;
&#160;
    public void doFilter&#40;ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain&#41;
            throws IOException, ServletException &#123;
&#160;
		HttpServletRequest request = &#40;HttpServletRequest&#41; servletRequest;
&#160;
		String content_type = request.getContentType&#40;&#41;;
		if &#40;content_type != null &#38;&#38; content_type.indexOf&#40;&#34;multipart/form-data&#34;&#41; != -1&#41; &#123;
			JakartaMultiPartRequest jakartaMultiPartRequest = new JakartaMultiPartRequest&#40;request,
					getFilterConfig&#40;&#41;.getInitParameter&#40;&#34;saveDir&#34;&#41;, Integer.valueOf&#40;
							getFilterConfig&#40;&#41;.getInitParameter&#40;&#34;maxUploadSize&#34;&#41;&#41;.intValue&#40;&#41;&#41;;
&#160;
			request = jakartaMultiPartRequest;
		&#125;
&#160;
		filterChain.doFilter&#40;request, [...]]]></description>
			<content:encoded><![CDATA[<p>　　在原项目中，对文件上传的处理并不是使用Spring的MultipartResolver，而是使用自定义的MultiPartFilter和HttpServletRequestWrapper结合来进行处理。</p>
<p>　　MultiPartFilter是一个定义在web.xml中的&lt;filter&gt;，原理是通过判断HttpServletRequest中的contentType是否包含&#8221;multipart/form-data&#8221;，若代码中包含此字符品，则表明是一个File Upload请求，就使用JakartaMultiPartRequest来对HttpServletRequest对其进行包装。</p>
<p>　　其代码如下：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MultiPartFilter <span style="color: #000000; font-weight: bold;">extends</span> GenericFilterBean <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doFilter<span style="color: #009900;">&#40;</span>ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain<span style="color: #009900;">&#41;</span>
            <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">IOException</span>, ServletException <span style="color: #009900;">&#123;</span>
&nbsp;
		HttpServletRequest request <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>HttpServletRequest<span style="color: #009900;">&#41;</span> servletRequest<span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #003399;">String</span> content_type <span style="color: #339933;">=</span> request.<span style="color: #006633;">getContentType</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>content_type <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> content_type.<span style="color: #006633;">indexOf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;multipart/form-data&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			JakartaMultiPartRequest jakartaMultiPartRequest <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> JakartaMultiPartRequest<span style="color: #009900;">&#40;</span>request,
					getFilterConfig<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getInitParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;saveDir&quot;</span><span style="color: #009900;">&#41;</span>, <span style="color: #003399;">Integer</span>.<span style="color: #006633;">valueOf</span><span style="color: #009900;">&#40;</span>
							getFilterConfig<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getInitParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;maxUploadSize&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">intValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			request <span style="color: #339933;">=</span> jakartaMultiPartRequest<span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		filterChain.<span style="color: #006633;">doFilter</span><span style="color: #009900;">&#40;</span>request, servletResponse<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>　　JakartaMultiPartRequest类继承自HttpServletRequestWrapper，在其构造方法中，我们对Request进行分析，并且保存用户上传的文件，将文件名等信息放到Request的attribute中，从而在后续的代码中可以对上传的文件进行处理。</p>
<p>　　但在后来客户进出的对产品图片处理的新需求中，因为JakartaMultiPartRequest的问题，没有办法满足我们的要求，所以考虑到使用Spring的MultipartResolver来进行上传处理，但之前的代码不能再进行改动，否则所有处理文件上传的Controller必须更改，代价很大。但如果在Spring中进行配置MultipartResolver的配置后，发现我们旧的文件上传代码都失效了，无法上传文件。<br />
<span id="more-82"></span><br />
　　后来经过调试，发现在我们定义的MultiPartFilter中处理过上传的请求后，Spring的MultipartResolver又对其进行了上传处理，这样就导致我们之前设计在Request中的attribute全部丢失，所以我们得想办法让我们自定义的MultiPartFilter和Spring的MultipartResolver不要互相干扰。</p>
<p>我们需要经两步来解决此问题：</p>
<p><strong>第一步：</strong>我们对自定义的MultiPartFilter进行改动，让其接受在web.xml中传入的配置参数“excludeURL”，此参数指定那些不需要JakartaMultiPartRequest类进行处理的页面URL。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">boolean</span> jump <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// 根据web.xml中的配置，判断当前url是否跳过此过滤器</span>
<span style="color: #003399;">String</span> excludeURL <span style="color: #339933;">=</span> getFilterConfig<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getInitParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;excludeURL&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>excludeURL <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span><span style="color: #0000ff;">&quot;&quot;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>excludeURL<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>request.<span style="color: #006633;">getRequestURI</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">indexOf</span><span style="color: #009900;">&#40;</span>excludeURL<span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		jump <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>jump<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #003399;">String</span> content_type <span style="color: #339933;">=</span> request.<span style="color: #006633;">getContentType</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>content_type <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> content_type.<span style="color: #006633;">indexOf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;multipart/form-data&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		JakartaMultiPartRequest jakartaMultiPartRequest <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> JakartaMultiPartRequest<span style="color: #009900;">&#40;</span>request,
				getFilterConfig<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getInitParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;saveDir&quot;</span><span style="color: #009900;">&#41;</span>, <span style="color: #003399;">Integer</span>.<span style="color: #006633;">valueOf</span><span style="color: #009900;">&#40;</span>
						getFilterConfig<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getInitParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;maxUploadSize&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">intValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		request <span style="color: #339933;">=</span> jakartaMultiPartRequest<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
filterChain.<span style="color: #006633;">doFilter</span><span style="color: #009900;">&#40;</span>request, servletResponse<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><strong>第二步：</strong><br />
　　经过查看org.springframework.web.multipart.commons.CommonsMultipartResolver的源代码我们发现（我们在spring中使用commons fileupload处理上传），其中有个public boolean isMultipart(HttpServletRequest request)方法，此方法控制着Spring是否对用户的Request进行文件上传处理，于是自定义一个我们自己的CommonsMultipartResolver，继承自org.springframework.web.multipart.commons.CommonsMultipartResolver，并重写其中的public boolean isMultipart(HttpServletRequest request)，在方法中对当前的request进行判断，如果是一个JakartaMultiPartRequest实例，则返回false，告知Spring不需要再对当前的request进行文件上传处理；如果不是，则直接调用父类的isMultipart方法。</p>
<p>代码如下：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> CommonsMultipartResolver <span style="color: #000000; font-weight: bold;">extends</span> org.<span style="color: #006633;">springframework</span>.<span style="color: #006633;">web</span>.<span style="color: #006633;">multipart</span>.<span style="color: #006633;">commons</span>.<span style="color: #006633;">CommonsMultipartResolver</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #008000; font-style: italic; font-weight: bold;">/**
     * {@inheritDoc}
     * 
     * @see org.springframework.web.multipart.commons.CommonsMultipartResolver#isMultipart(javax.servlet.http.HttpServletRequest)
     */</span>
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> isMultipart<span style="color: #009900;">&#40;</span>HttpServletRequest request<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>request <span style="color: #000000; font-weight: bold;">instanceof</span> JakartaMultiPartRequest<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">isMultipart</span><span style="color: #009900;">&#40;</span>request<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>　　当然，Spring中的配置也要使用自定义的CommonsMultipartResolver，</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;">    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;bean</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;multipartResolver&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;net.ymeng.example.web.filter.CommonsMultipartResolver&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;maxUploadSize&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;20000000&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/bean<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>　　这样，就可以让自定义的MultiPartFilter和Spring的MultipartResolver各司其职了。</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/spring-multipartresolver-conflict.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>JSF Converter in JBoss Seam</title>
		<link>http://dev.ymeng.net/jsf-converter-in-jboss-seam.html</link>
		<comments>http://dev.ymeng.net/jsf-converter-in-jboss-seam.html#comments</comments>
		<pubDate>Thu, 04 Sep 2008 13:28:05 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[JBoss Seam]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Converter]]></category>

		<category><![CDATA[JSF]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=84</guid>
		<description><![CDATA[折腾了两天，终于在JBoss Seam中搞定了JSF Converter。
在这个程序中，产品（Product）和分类（Category）是多对多的关系，关系维护方为产品，在创建产品时，允许选择多个分类，因为Product.categories是一个List属性，同时产品选择&#60;select /&#62;标签也是由从Action中查询出来的所有Category的List，所以在页面上，需要在页面渲染、用户提交后的category进行转换。
显示时，我们以Category.id为&#60;option /&#62;的value值，而Category.title为label。
Entity如下（省略setter和getter）：
Category.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Entity
@Table&#40;name = &#34;category&#34;&#41;
public class Category extends BaseEntity &#123;
&#160;
	@Id
	@GeneratedValue
	@Column&#40;name = &#34;id&#34;, unique = true, nullable = false, length = 10&#41;
	private Integer id;
&#160;
	@Column&#40;name = &#34;title&#34;&#41;
	@NotNull
	@Length&#40;min = 4, max = 64, message = &#34;{invalid.length}&#34;&#41;
	private String title;
&#160;
	@ManyToMany&#40;mappedBy = &#34;categories&#34;&#41;
	private List&#60;product&#62; products = new ArrayList&#60;/product&#62;&#60;product&#62;&#40;&#41;;
&#125;
&#60;/product&#62;


Product.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Entity
@Table&#40;name = &#34;product&#34;&#41;
public class Product extends BaseEntity &#123;
&#160;
	@Id
	@GeneratedValue
	@Column&#40;name = &#34;id&#34;, nullable = [...]]]></description>
			<content:encoded><![CDATA[<p>折腾了两天，终于在JBoss Seam中搞定了JSF Converter。</p>
<p>在这个程序中，产品（Product）和分类（Category）是多对多的关系，关系维护方为产品，在创建产品时，允许选择多个分类，因为Product.categories是一个List属性，同时产品选择&lt;select /&gt;标签也是由从Action中查询出来的所有Category的List，所以在页面上，需要在页面渲染、用户提交后的category进行转换。</p>
<p>显示时，我们以Category.id为&lt;option /&gt;的value值，而Category.title为label。</p>
<p>Entity如下（省略setter和getter）：</p>
<p><strong>Category.java</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">@<span style="color: #003399;">Entity</span>
@Table<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;category&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Category <span style="color: #000000; font-weight: bold;">extends</span> BaseEntity <span style="color: #009900;">&#123;</span>
&nbsp;
	@Id
	@GeneratedValue
	@Column<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;id&quot;</span>, unique <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span>, nullable <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span>, length <span style="color: #339933;">=</span> <span style="color: #cc66cc;">10</span><span style="color: #009900;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> id<span style="color: #339933;">;</span>
&nbsp;
	@Column<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;title&quot;</span><span style="color: #009900;">&#41;</span>
	@NotNull
	@Length<span style="color: #009900;">&#40;</span>min <span style="color: #339933;">=</span> <span style="color: #cc66cc;">4</span>, max <span style="color: #339933;">=</span> <span style="color: #cc66cc;">64</span>, message <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;{invalid.length}&quot;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> title<span style="color: #339933;">;</span>
&nbsp;
	@ManyToMany<span style="color: #009900;">&#40;</span>mappedBy <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;categories&quot;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">private</span> List<span style="color: #339933;">&lt;</span>product<span style="color: #339933;">&gt;</span> products <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ArrayList<span style="color: #339933;">&lt;/</span>product<span style="color: #339933;">&gt;&lt;</span>product<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #339933;">&lt;/</span>product<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p><span id="more-84"></span></p>
<p><strong>Product.java</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">@<span style="color: #003399;">Entity</span>
@Table<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;product&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Product <span style="color: #000000; font-weight: bold;">extends</span> BaseEntity <span style="color: #009900;">&#123;</span>
&nbsp;
	@Id
	@GeneratedValue
	@Column<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;id&quot;</span>, nullable <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span>, unique <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span>, length <span style="color: #339933;">=</span> <span style="color: #cc66cc;">10</span><span style="color: #009900;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> id<span style="color: #339933;">;</span>
&nbsp;
	@Column<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;title&quot;</span><span style="color: #009900;">&#41;</span>
	@NotNull
	@Length<span style="color: #009900;">&#40;</span>min <span style="color: #339933;">=</span> <span style="color: #cc66cc;">4</span>, max <span style="color: #339933;">=</span> <span style="color: #cc66cc;">64</span><span style="color: #009900;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> title<span style="color: #339933;">;</span>
&nbsp;
	@Column<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;price&quot;</span><span style="color: #009900;">&#41;</span>
	@NotNull
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Float</span> price<span style="color: #339933;">;</span>
&nbsp;
	@ManyToMany<span style="color: #009900;">&#40;</span>cascade <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> CascadeType.<span style="color: #006633;">MERGE</span>, CascadeType.<span style="color: #006633;">REFRESH</span> <span style="color: #009900;">&#125;</span>, fetch <span style="color: #339933;">=</span> FetchType.<span style="color: #006633;">LAZY</span><span style="color: #009900;">&#41;</span>
	@JoinTable<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;category_product&quot;</span>, joinColumns <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> @JoinColumn<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;product_id&quot;</span>, referencedColumnName <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;id&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span>, inverseJoinColumns <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> @JoinColumn<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;category_id&quot;</span>, referencedColumnName <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;id&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">private</span> List<span style="color: #339933;">&lt;</span>category<span style="color: #339933;">&gt;</span> categories <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ArrayList<span style="color: #339933;">&lt;/</span>category<span style="color: #339933;">&gt;&lt;</span>category<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #339933;">&lt;/</span>category<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>如果persistence.xml中，hibernate.hbm2ddl.auto的属性配置为create-drop，那么在JBoss启动时，这两个Entity会生成三张表，除了product和category外，还有一张关联表：category_product。</p>
<p>xhtml页面代码如下：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="xhtml" style="font-family:monospace;">                &lt;ui :define name=&quot;label&quot;&gt;Category&lt;/ui&gt;
                &lt;h :selectManyListbox id=&quot;categories&quot; value=&quot;#{productEditAction.product.categories}&quot; converter=&quot;categoryConverter&quot; &gt;
                  &lt;s :selectItems var=&quot;cat&quot; value=&quot;#{productEditAction.categories}&quot; label=&quot;#{cat.title}&quot; /&gt;
                &lt;/h&gt;</pre></td></tr></table></div>

<p>其中，#{productEditAction.categories}表示系统中所有的分类，是一个List&lt;category&gt;列表。</p>
<p>JSF Converter代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.faces.component.UIComponent</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.faces.context.FacesContext</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.faces.convert.ConverterException</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">net.ymeng.studyseam.entity.Category</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">net.ymeng.studyseam.service.InventoryService</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.jboss.seam.annotations.In</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.jboss.seam.annotations.Name</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.jboss.seam.annotations.faces.Converter</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * @author yangtze
 * 
 */</span>
@<span style="color: #003399;">Name</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;categoryConverter&quot;</span><span style="color: #009900;">&#41;</span>
@Converter<span style="color: #009900;">&#40;</span>id <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;categoryConverter&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> CategoryConverter <span style="color: #000000; font-weight: bold;">implements</span> javax.<span style="color: #006633;">faces</span>.<span style="color: #006633;">convert</span>.<span style="color: #006633;">Converter</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	@In<span style="color: #009900;">&#40;</span>create <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span>, value <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;inventoryServiceImpl&quot;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">private</span> InventoryService inventoryService<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * javax.faces.convert.Converter#getAsObject(javax.faces.context.FacesContext
	 * , javax.faces.component.UIComponent, java.lang.String)
	 */</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span> getAsObject<span style="color: #009900;">&#40;</span>FacesContext context, UIComponent component,
			<span style="color: #003399;">String</span> value<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>value <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span><span style="color: #0000ff;">&quot;&quot;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>value<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #003399;">Integer</span> catId <span style="color: #339933;">=</span> <span style="color: #003399;">Integer</span>.<span style="color: #006633;">valueOf</span><span style="color: #009900;">&#40;</span>value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			Category cat <span style="color: #339933;">=</span> inventoryService.<span style="color: #006633;">findCategoryById</span><span style="color: #009900;">&#40;</span>catId<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000000; font-weight: bold;">return</span> cat<span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * javax.faces.convert.Converter#getAsString(javax.faces.context.FacesContext
	 * , javax.faces.component.UIComponent, java.lang.Object)
	 */</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getAsString<span style="color: #009900;">&#40;</span>FacesContext context, UIComponent component,
			<span style="color: #003399;">Object</span> value<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>value <span style="color: #000000; font-weight: bold;">instanceof</span> Category<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #003399;">String</span>.<span style="color: #006633;">valueOf</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>Category<span style="color: #009900;">&#41;</span> value<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> ConverterException<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Unsupported valued! Value is: &quot;</span>
					<span style="color: #339933;">+</span> value <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Type is: &quot;</span> <span style="color: #339933;">+</span> value.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>其中getAsString方法在页面显示时会自动调用，将传入的对象value转换为字符串输出，因为这里用作option值的是Category.id，所以我们在此方面中取出分类的id并返回。</p>
<p>而getAsObject方法是在用户提交时，将option的值转换为Integer，并从Service层中查找对应的Category实例、返回。</p>
<p>所以对于提交后的保存动作，我们就不需要再做任何处理，Product.categories中已经是转换好的List&lt;Category&gt;，直接persist/merge即可。</p>
<p>如果在转换类中使用@Converter注解，就不再需要在faces-config.xml中进行converter的配置了，Seam会自动帮你完成这个配置。</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/jsf-converter-in-jboss-seam.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>设计模式－－享元模式 (Flyweight)</title>
		<link>http://dev.ymeng.net/design-pattern-flyweight.html</link>
		<comments>http://dev.ymeng.net/design-pattern-flyweight.html#comments</comments>
		<pubDate>Fri, 29 Aug 2008 05:21:25 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[Design Pattern]]></category>

		<category><![CDATA[Flyweight]]></category>

		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=79</guid>
		<description><![CDATA[　　享元模式的宗旨：通过共享来为大量的细粒度对象提供有效支持。
　　避免大量拥有相同类型的小类（细粒度，小类中的不可变部份）的开销(如耗费内存)，使所有客户代码共享一个实例(元类)。
　　怎么使用？（以人力资源系统中的公司员工为例）：
　　一般来说，在需要对某个员工进行访问的时候，我们都会new一个员工类，如果两个客户代码同时访问同一个员工，则会产生两个相同（或部份相同）的同一员工实例，这样，对于一个员工来说，内存中就可能有该员工的多个实例存在，如果一个企业有10000个员工，那内存中实际的员工实例可能就不止10000个。在这种情况下，我们就可以用享元模式来解决这个问题。
（假设我们系统中原有的类如下图OldPerson所示）

1
2
3
4
5
6
7
8
9
10
11
12
13
public class OldPerson &#123;
	private String id;
	private String name;
	private double basicSalary;
	private double variableSalary;
&#160;
	/* 省略setter和getter */
&#160;
	public OldPerson&#40;String id, String name&#41; &#123;
		this.id = id;
		this.name = name;
	&#125;
&#125;

我们需要分两步来完成这个模式：
1、提取类中的不可变部份
仔细思考上面的OldPerson类，我们发现，在任何一种情况下，员工的id号和name都是不变的，不管是计算基础薪资的客户代码，还是计算绩效薪资的客户代码，id和name都具有不变性，所以我们可以将这两个属性列为员工类的不可变部份，利用这两个不变属性，创建一个接口NewPerson。

1
2
3
4
5
public interface NewPerson &#123;
	public String getId&#40;&#41;;
	public String getName&#40;&#41;;
	public String toString&#40;&#41;;
&#125;

2、创建享元工厂
在这一步，我们实例化享元并组织共享享元的客户代码，而且我们必须保证各个客户代码都使用享元工厂创建享元实例，而不能自己创建。下图是我们创建的享元工厂。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class PersonFactory &#123;
	private static Map&#60;string , NewPerson&#62; persons = new HashMap&#40;&#41;;
	static &#123;
		persons.put&#40;&#34;001&#34;, new NewPersonImpl&#40;&#34;001&#34;, &#34;Tom&#34;&#41;&#41;;
		persons.put&#40;&#34;002&#34;, new NewPersonImpl&#40;&#34;002&#34;, &#34;Jerry&#34;&#41;&#41;;
	&#125;
&#160;
	public static NewPerson getPerson&#40;String id&#41; &#123;
		return [...]]]></description>
			<content:encoded><![CDATA[<p>　　享元模式的宗旨：通过共享来为大量的细粒度对象提供有效支持。<br />
　　避免大量拥有相同类型的小类（细粒度，小类中的不可变部份）的开销(如耗费内存)，使所有客户代码共享一个实例(元类)。</p>
<p>　　怎么使用？（以人力资源系统中的公司员工为例）：<br />
　　一般来说，在需要对某个员工进行访问的时候，我们都会new一个员工类，如果两个客户代码同时访问同一个员工，则会产生两个相同（或部份相同）的同一员工实例，这样，对于一个员工来说，内存中就可能有该员工的多个实例存在，如果一个企业有10000个员工，那内存中实际的员工实例可能就不止10000个。在这种情况下，我们就可以用享元模式来解决这个问题。<span id="more-79"></span><br />
（假设我们系统中原有的类如下图OldPerson所示）</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> OldPerson <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> id<span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> name<span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">double</span> basicSalary<span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">double</span> variableSalary<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">/* 省略setter和getter */</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> OldPerson<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> id, <span style="color: #003399;">String</span> name<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">id</span> <span style="color: #339933;">=</span> id<span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">name</span> <span style="color: #339933;">=</span> name<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>我们需要分两步来完成这个模式：</p>
<p>1、提取类中的不可变部份<br />
仔细思考上面的OldPerson类，我们发现，在任何一种情况下，员工的id号和name都是不变的，不管是计算基础薪资的客户代码，还是计算绩效薪资的客户代码，id和name都具有不变性，所以我们可以将这两个属性列为员工类的不可变部份，利用这两个不变属性，创建一个接口NewPerson。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> NewPerson <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> toString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>2、创建享元工厂<br />
在这一步，我们实例化享元并组织共享享元的客户代码，而且我们必须保证各个客户代码都使用享元工厂创建享元实例，而不能自己创建。下图是我们创建的享元工厂。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> PersonFactory <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> Map<span style="color: #339933;">&lt;</span>string , NewPerson<span style="color: #339933;">&gt;</span> persons <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">HashMap</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">static</span> <span style="color: #009900;">&#123;</span>
		persons.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;001&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> NewPersonImpl<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;001&quot;</span>, <span style="color: #0000ff;">&quot;Tom&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		persons.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;002&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> NewPersonImpl<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;002&quot;</span>, <span style="color: #0000ff;">&quot;Jerry&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> NewPerson getPerson<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> id<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> persons.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">class</span> NewPersonImpl <span style="color: #000000; font-weight: bold;">implements</span> NewPerson <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> id<span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> name<span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">public</span> NewPersonImpl<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> id, <span style="color: #003399;">String</span> name<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">id</span> <span style="color: #339933;">=</span> id<span style="color: #339933;">;</span>
			<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">name</span> <span style="color: #339933;">=</span> name<span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #000000; font-weight: bold;">return</span> id<span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span>
		<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #000000; font-weight: bold;">return</span> name<span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span>
		<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> toString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">id</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot; ===&gt; &quot;</span> <span style="color: #339933;">+</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">name</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #339933;">&lt;/</span>string<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>在PersonFactory中，我们创建了它的一个私有内部类NewPersonImpl，并实现了NewPerson，这样即可禁止客户代码自己实例化NewPersonImple，这也是为什么我们需要创建NewPerson接口的原因了。</p>
<p>客户代码调用都需要使用PersonFactory.getPerson来获得某员工的唯一实例。比如：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> TestNewPerson <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>PersonFactory.<span style="color: #006633;">getPerson</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;001&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>PersonFactory.<span style="color: #006633;">getPerson</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;002&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>需要注意的是，享元对象中的属性必须是不可变的。</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/design-pattern-flyweight.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>设计模式－－模板方法模式 (Template Method)</title>
		<link>http://dev.ymeng.net/design-pattern-template-method.html</link>
		<comments>http://dev.ymeng.net/design-pattern-template-method.html#comments</comments>
		<pubDate>Fri, 29 Aug 2008 05:19:30 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[Design Pattern]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Template Method]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=76</guid>
		<description><![CDATA[　　模板方法模式的目的就是在一个方法中实现一个算法，并将算法中某些步骤的定义推迟，从而使得其他类可以重新定义这些步骤。
　　在编写一个方法的时候，考虑到算法的某些步骤可能会有不同的实现方式，我们可能会首先定出算法的框架。这样，在定义方法的时候，我们可以将某些步骤定义为抽象方法，或者是将它们定义为存根方法，也可以将它们定义为某个单独接口中的方法，这就是模板方法模式的实现。
　　模板方法的典型例子就是排序。java.util.Collections类将sort()方法定义为一个模板方法，而将其中的比较交给用户来实现，sort()方法所接受的List中的对象需要实现Comparator接口，这就是将实际算法推迟并交给其它类来实现的模板方法模式。

　　例：
　　我们有一个抽象类ShowSubClassName，有两个子类SubClassA和SubClassB继承了该抽象类，抽象类中定义的抽象方法showName()被推迟到了两个子类中实现（分别输出自己的class name）。

1
2
3
4
5
6
7
8
9
10
public abstract class ShowSubClassName &#123;
	/**
	 * 这个方法的实现，我们交给子类完成
	 */
	public abstract void showName&#40;&#41;;
&#160;
	public void show&#40;&#41; &#123;
		showName&#40;&#41;;
	&#125;
&#125;


1
2
3
4
5
public class SubClassA extends ShowSubClassName &#123;
	public void showName&#40;&#41; &#123;
		System.out.println&#40;this.getClass&#40;&#41;.getName&#40;&#41;&#41;;
	&#125;
&#125;


1
2
3
4
5
6
7
public class SubClassB extends ShowSubClassName &#123;
&#160;
	public void showName&#40;&#41; &#123;
		System.out.println&#40;this.getClass&#40;&#41;.getName&#40;&#41;&#41;;
	&#125;
&#160;
&#125;


1
2
3
4
5
6
7
8
9
public class Test &#123;
	public static void main&#40;String&#91;&#93; args&#41; &#123;
		ShowSubClassName classA = new SubClassA&#40;&#41;;
		classA.show&#40;&#41;;
&#160;
		ShowSubClassName classB = new SubClassB&#40;&#41;;
		classB.show&#40;&#41;;
	&#125;
&#125;

]]></description>
			<content:encoded><![CDATA[<p>　　模板方法模式的目的就是在一个方法中实现一个算法，并将算法中某些步骤的定义推迟，从而使得其他类可以重新定义这些步骤。</p>
<p>　　在编写一个方法的时候，考虑到算法的某些步骤可能会有不同的实现方式，我们可能会首先定出算法的框架。这样，在定义方法的时候，我们可以将某些步骤定义为抽象方法，或者是将它们定义为存根方法，也可以将它们定义为某个单独接口中的方法，这就是模板方法模式的实现。<br />
　　模板方法的典型例子就是排序。java.util.Collections类将sort()方法定义为一个模板方法，而将其中的比较交给用户来实现，sort()方法所接受的List中的对象需要实现Comparator接口，这就是将实际算法推迟并交给其它类来实现的模板方法模式。</p>
<p><span id="more-76"></span></p>
<p>　　例：<br />
　　我们有一个抽象类ShowSubClassName，有两个子类SubClassA和SubClassB继承了该抽象类，抽象类中定义的抽象方法showName()被推迟到了两个子类中实现（分别输出自己的class name）。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">class</span> ShowSubClassName <span style="color: #009900;">&#123;</span>
	<span style="color: #008000; font-style: italic; font-weight: bold;">/**
	 * 这个方法的实现，我们交给子类完成
	 */</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000066; font-weight: bold;">void</span> showName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> show<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		showName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> SubClassA <span style="color: #000000; font-weight: bold;">extends</span> ShowSubClassName <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> showName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> SubClassB <span style="color: #000000; font-weight: bold;">extends</span> ShowSubClassName <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> showName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Test <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		ShowSubClassName classA <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SubClassA<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		classA.<span style="color: #006633;">show</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		ShowSubClassName classB <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SubClassB<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		classB.<span style="color: #006633;">show</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/design-pattern-template-method.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>设计模式－－工厂方法模式 (Factory Method)</title>
		<link>http://dev.ymeng.net/design-pattern-factory-method.html</link>
		<comments>http://dev.ymeng.net/design-pattern-factory-method.html#comments</comments>
		<pubDate>Fri, 29 Aug 2008 05:17:47 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[Design Pattern]]></category>

		<category><![CDATA[Factory Method]]></category>

		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=73</guid>
		<description><![CDATA[　　并不是能创建并返回一个新的对象的方法都是工厂方法模式的实例。
　　工厂方法模式不仅要求有一个能够创建新对象的方法，还要求能够使得客户代码无需了解应该具体实例化哪个类。工厂方法模式通常会包含有若干个类，这些类实现了相同的操作，返回了相同的抽象类型，然而，这些类的操作在内部实际上实例化了不同的类，不过这些类都实现了上述抽象类型。
　　工厂方法模式的特征：
1.	该方法创建了一个新的对象。
2.	该方法的返回类型为一个抽象类或接口。
3.	有若干个类实现了上述抽象类或接口。
　　比如我们要实现一个在线客户服务系统，若客服人员在线的时候，客户提交的问题将会直接传送给客服人员；若客服人员不在线，则将客户提交的问题发送至客服信箱。
　　类图：
　　　　
　　接口CustomerService中定义了一个抽象方法sendMessage()，类OnlineCustomerService和OffineCustomerService都实现了CustomerService接口，分别实现了客服人员在线和不在线时发送消息的方法。
　　CustomerServiceFactory中提供了一个createCustomerService()方法，用过返回CustomerService类型的对象，在返回此对象之类，它会通过isServiceOnline()来检查客服人员是否在线，以返回不同的对象。
　　下面是工厂类的代码：

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class CustomerServiceFacotry &#123;
	private static boolean isServiceOnline&#40;&#41; &#123;
		// 检查客服人员状态
		// 若在线，返回true；不在线，返回false
		return false;
	&#125;
&#160;
	public static CustomerService createCustomerService&#40;&#41; &#123;
		if &#40;isServiceOnline&#40;&#41;&#41; &#123;
			return new OnlineCustomerService&#40;&#41;;
		&#125; else &#123;
			return new OfflineCustomerService&#40;&#41;;
		&#125;
	&#125;
&#125;

]]></description>
			<content:encoded><![CDATA[<p>　　并不是能创建并返回一个新的对象的方法都是工厂方法模式的实例。<br />
　　工厂方法模式不仅要求有一个能够创建新对象的方法，还要求能够使得客户代码无需了解应该具体实例化哪个类。工厂方法模式通常会包含有若干个类，这些类实现了相同的操作，返回了相同的抽象类型，然而，这些类的操作在内部实际上实例化了不同的类，不过这些类都实现了上述抽象类型。<br />
　　工厂方法模式的特征：<br />
1.	该方法创建了一个<span style="color: #FF0000"><strong>新的对象</strong></span>。<br />
2.	该方法的返回类型为一个<span style="color: #FF0000"><strong>抽象类或接口</strong></span>。<br />
3.	有若干个类<span style="color: #FF0000"><strong>实现</strong></span>了上述抽象类或接口。</p>
<p>　　比如我们要实现一个在线客户服务系统，若客服人员在线的时候，客户提交的问题将会直接传送给客服人员；若客服人员不在线，则将客户提交的问题发送至客服信箱。<span id="more-73"></span><br />
　　类图：<br />
<div id="attachment_74" class="wp-caption alignnone" style="width: 460px"><img src="http://dev.ymeng.net/wp-content/uploads/2008/08/factory-method.png" alt="工厂方法模式" title="工厂方法模式" width="450" height="328" class="size-full wp-image-74" /><p class="wp-caption-text">工厂方法模式</p></div></p>
<p>　　　　<br />
　　接口CustomerService中定义了一个抽象方法sendMessage()，类OnlineCustomerService和OffineCustomerService都实现了CustomerService接口，分别实现了客服人员在线和不在线时发送消息的方法。<br />
　　CustomerServiceFactory中提供了一个createCustomerService()方法，用过返回CustomerService类型的对象，在返回此对象之类，它会通过isServiceOnline()来检查客服人员是否在线，以返回不同的对象。</p>
<p>　　下面是工厂类的代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> CustomerServiceFacotry <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">boolean</span> isServiceOnline<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// 检查客服人员状态</span>
		<span style="color: #666666; font-style: italic;">// 若在线，返回true；不在线，返回false</span>
		<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> CustomerService createCustomerService<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isServiceOnline<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> OnlineCustomerService<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> OfflineCustomerService<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/design-pattern-factory-method.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>设计模式－－观察者模式 (Observer)</title>
		<link>http://dev.ymeng.net/design-pattern-observer.html</link>
		<comments>http://dev.ymeng.net/design-pattern-observer.html#comments</comments>
		<pubDate>Fri, 29 Aug 2008 05:16:01 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[Design Pattern]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Observer]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=70</guid>
		<description><![CDATA[　　　　观察者模式的宗旨：在多个对象之间定义一个一对多的关系，当一个对象状态改变的时候，其他所有的依赖于这个对象的对象能够得到通知，并自动更新。
　　　　观察者模式在Swing中得到了广泛应用。当客户单击按钮时，程序中许多对象都会对此做出反应。在Swing中，关注Swing组件变化的类被称为“监听器”，这就是观察者模式的应用。
　　　　为了支持观察者模式，Java类库中的java.util包中提供了Observable类和Observer接口。
　　　　我们现在举一个例子来说明观察者模式。
　　　　在网上商店的应用中，如果我们希望产品的名称被更改了后，系统会自动在控制台打印新名称，则就可以使用观察者模式。此时，产品类Product就需要继承Observable类，产品观察者类NameObserver则需要实现Observer接口。

　　　　先看类图：
代码实现：
1.	Product.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.util.Observable;
&#160;
public class Product extends Observable &#123;
	private String name;
&#160;
	public String getName&#40;&#41; &#123;
		return name;
	&#125;
&#160;
	public void setName&#40;String name&#41; &#123;
		this.name = name;
&#160;
		setChanged&#40;&#41;;
		notifyObservers&#40;name&#41;;
	&#125;
&#125;

　　注意：在setName()方法中，调用了Observalbe类的setChanged()和notifyObservers()方法。
setChanged()方法将触发Observable代码将这次改变广播出去；而notifyObservers()方法调用所有注册的观察者对象的update()方法。（有点啰嗦）
　　Product类不需要维护所有监视它的对象的引用，这些监视的对象将在实际的代码中TestObserver.java被注册。
2.	NameObserver.java

1
2
3
4
5
6
7
8
9
10
11
import java.util.Observable;
import java.util.Observer;
&#160;
public class NameObserver implements Observer &#123;
&#160;
	public void update&#40;Observable o, Object arg&#41; &#123;
		String name = &#40;String&#41;arg;
		System.out.println&#40;&#34;Set Name: &#34; + name&#41;;
	&#125;
&#160;
&#125;

　　该类实现了Observer接口，当Product对象的setName()方法被调用后，该类的update方法会自动被调用，并在控制台输入新的产品名称。
3.	TestObserver.java

1
2
3
4
5
6
7
8
9
10
11
public class TestObserver &#123;
&#160;
	public static void main&#40;String&#91;&#93; args&#41; &#123;
		NameObserver nameObserver = new NameObserver&#40;&#41;;
		Product product = new Product&#40;&#41;;
		product.addObserver&#40;nameObserver&#41;;
&#160;
		product.setName&#40;&#34;Cat1&#34;&#41;;
	&#125;
&#160;
&#125;

　　该类是一个测试程序，实例化NameObserver和Product，并将NameObserver的实例注册给Product实例（通过调用Product.addObserver来注册），用以实现监听。当程序给Product的setName()方法被调用后，NameObserver实例的update()方法马上就会得到通知并输出新的产品名称。
]]></description>
			<content:encoded><![CDATA[<p>　　　　观察者模式的宗旨：在多个对象之间定义一个一对多的关系，当一个对象状态改变的时候，其他所有的依赖于这个对象的对象能够得到通知，并自动更新。<br />
　　　　观察者模式在Swing中得到了广泛应用。当客户单击按钮时，程序中许多对象都会对此做出反应。在Swing中，关注Swing组件变化的类被称为“监听器”，这就是观察者模式的应用。</p>
<p>　　　　为了支持观察者模式，Java类库中的java.util包中提供了Observable类和Observer接口。</p>
<p>　　　　我们现在举一个例子来说明观察者模式。<br />
　　　　在网上商店的应用中，如果我们希望产品的名称被更改了后，系统会自动在控制台打印新名称，则就可以使用观察者模式。此时，产品类Product就需要继承Observable类，产品观察者类NameObserver则需要实现Observer接口。</p>
<p><span id="more-70"></span></p>
<p>　　　　先看类图：<br />
<div id="attachment_71" class="wp-caption alignnone" style="width: 455px"><img src="http://dev.ymeng.net/wp-content/uploads/2008/08/observer.png" alt="观察者模式" title="观察者模式" width="445" height="260" class="size-full wp-image-71" /><p class="wp-caption-text">观察者模式</p></div></p>
<p><strong>代码实现：</strong></p>
<p>1.	Product.java</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.Observable</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Product <span style="color: #000000; font-weight: bold;">extends</span> <span style="color: #003399;">Observable</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> name<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> name<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setName<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> name<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">name</span> <span style="color: #339933;">=</span> name<span style="color: #339933;">;</span>
&nbsp;
		setChanged<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		notifyObservers<span style="color: #009900;">&#40;</span>name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>　　<strong>注意：</strong>在setName()方法中，调用了Observalbe类的setChanged()和notifyObservers()方法。<br />
setChanged()方法将触发Observable代码将这次改变广播出去；而notifyObservers()方法调用所有注册的观察者对象的update()方法。（有点啰嗦）<br />
　　Product类不需要维护所有监视它的对象的引用，这些监视的对象将在实际的代码中TestObserver.java被注册。</p>
<p>2.	NameObserver.java</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.Observable</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.Observer</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> NameObserver <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399;">Observer</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> update<span style="color: #009900;">&#40;</span><span style="color: #003399;">Observable</span> o, <span style="color: #003399;">Object</span> arg<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #003399;">String</span> name <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#41;</span>arg<span style="color: #339933;">;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Set Name: &quot;</span> <span style="color: #339933;">+</span> name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>　　该类实现了Observer接口，当Product对象的setName()方法被调用后，该类的update方法会自动被调用，并在控制台输入新的产品名称。</p>
<p>3.	TestObserver.java</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> TestObserver <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		NameObserver nameObserver <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> NameObserver<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		Product product <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Product<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		product.<span style="color: #006633;">addObserver</span><span style="color: #009900;">&#40;</span>nameObserver<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		product.<span style="color: #006633;">setName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Cat1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>　　该类是一个测试程序，实例化NameObserver和Product，并将NameObserver的实例注册给Product实例（通过调用Product.addObserver来注册），用以实现监听。当程序给Product的setName()方法被调用后，NameObserver实例的update()方法马上就会得到通知并输出新的产品名称。</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/design-pattern-observer.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>设计模式－－单体模式 (Singleton)</title>
		<link>http://dev.ymeng.net/design-pattern-singleton.html</link>
		<comments>http://dev.ymeng.net/design-pattern-singleton.html#comments</comments>
		<pubDate>Fri, 29 Aug 2008 05:12:42 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[Design Pattern]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Singleton]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=68</guid>
		<description><![CDATA[　　单体模式的宗旨就是：使一个类只有一个实例。
　　我们可以将类的constructor的可见性设置为私有来避免创建多个实例。当其他类调用该类的时候，我们可以利用getInstance()之类的方法来返回给调用者该类的实例。
　　比如：

1
2
3
4
5
6
7
8
9
private Factory factory = null;
&#160;
public static Factory getFactory&#40;&#41; &#123;
  if &#40;factory == null&#41; &#123;
    factory = new Facotry&#40;&#41;;
&#125;
&#160;
return factory;
&#125;

　　上面的例子实现了单体模式，但如果在多线程环境中采用此方式，仍然可能产生多个实例，最好的办法，用synchronized来控制Factory实例的生成。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Factory &#123;
	private static Factory factory;
&#160;
	private Factory&#40;&#41; &#123;
	&#125;
&#160;
	public static Factory getFactory&#40;&#41; &#123;
		synchronized&#40;Factory.class&#41; &#123;
			if &#40;factory == null&#41; &#123;
				factory = new Factory&#40;&#41;;
			&#125;
&#160;
			return factory;
		&#125;
	&#125;
&#125;

]]></description>
			<content:encoded><![CDATA[<p>　　单体模式的宗旨就是：使一个类只有一个实例。<br />
　　我们可以将类的constructor的可见性设置为私有来避免创建多个实例。当其他类调用该类的时候，我们可以利用getInstance()之类的方法来返回给调用者该类的实例。<br />
　　比如：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">private</span> Factory factory <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> Factory getFactory<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>factory <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    factory <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Facotry<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">return</span> factory<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>　　上面的例子实现了单体模式，但如果在多线程环境中采用此方式，仍然可能产生多个实例，最好的办法，用synchronized来控制Factory实例的生成。</p>
<p><span id="more-68"></span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Factory <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> Factory factory<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> Factory<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> Factory getFactory<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">synchronized</span><span style="color: #009900;">&#40;</span>Factory.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>factory <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				factory <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Factory<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
			<span style="color: #000000; font-weight: bold;">return</span> factory<span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/design-pattern-singleton.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>设计模式－－适配器模式 (Adapter)</title>
		<link>http://dev.ymeng.net/design-pattern-adapter.html</link>
		<comments>http://dev.ymeng.net/design-pattern-adapter.html#comments</comments>
		<pubDate>Fri, 29 Aug 2008 05:11:02 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[Design Pattern]]></category>

		<category><![CDATA[Adapter]]></category>

		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=64</guid>
		<description><![CDATA[　　当我们准备实现某个指定接口的时候，我们可能会发现现存的类已经提供了这种功能，只是方法名不同而已。这个时候，我们可以通过利用适配器模式来修改这个现存的类与外界交互的接口，从而使之满足用户的要求。
　　适配器模式的宗旨就是，保留现有的类所提供的服务，修改其接口，从而达到客户期望。
　　类适配器：


　　对象适配器：
]]></description>
			<content:encoded><![CDATA[<p>　　当我们准备实现某个指定接口的时候，我们可能会发现现存的类已经提供了这种功能，只是方法名不同而已。这个时候，我们可以通过利用适配器模式来修改这个现存的类与外界交互的接口，从而使之满足用户的要求。</p>
<p>　　适配器模式的宗旨就是，保留现有的类所提供的服务，修改其接口，从而达到客户期望。</p>
<p>　　<strong>类适配器：</strong><br />
<div id="attachment_65" class="wp-caption alignnone" style="width: 510px"><img src="http://dev.ymeng.net/wp-content/uploads/2008/08/class-adapter.png" alt="类适配器" title="类适配器" width="500" height="245" class="size-full wp-image-65" /><p class="wp-caption-text">类适配器</p></div></p>
<p>
<span id="more-64"></span></p>
<p>　　<strong>对象适配器：</strong><br />
<div id="attachment_66" class="wp-caption alignnone" style="width: 510px"><img src="http://dev.ymeng.net/wp-content/uploads/2008/08/object-adapter.png" alt="对象适配器" title="对象适配器" width="500" height="279" class="size-full wp-image-66" /><p class="wp-caption-text">对象适配器</p></div></p>
]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/design-pattern-adapter.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>设计模式－－接口模式 (Interface)</title>
		<link>http://dev.ymeng.net/design-pattern-interface.html</link>
		<comments>http://dev.ymeng.net/design-pattern-interface.html#comments</comments>
		<pubDate>Fri, 29 Aug 2008 05:06:58 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[Design Pattern]]></category>

		<category><![CDATA[Interface]]></category>

		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=61</guid>
		<description><![CDATA[　　类的接口，就是该类允许其他类对象访问的方法和域的集合。一个类实现了某个接口，通常意味着该类的方法将会执行接口方法名表示的操作，遵循接口方法的代码注释和其他相关文档的要求。而类的实现就是位于这些方法体内的代码。
　　比如：

1
2
3
interface Login &#123;
  boolean login&#40;String name, String password&#41;;
&#125;

需要注意的地方：
　1. 接口的方法总是抽象的，无论是否显式地声明。
　2. 接口的方法总是公共的，无论是否显式地声明。
　3. 接口的可见性受限于其所在的包，因为Login没有显式地声明为public，所以其在包内可见。
　4. 一个接口可以扩展另一个接口。比如List接口扩展了Collection。
　5. 接口可以不包含方法。不包含方法的接口称为“标记”接口。比如Cloneable接口。
　6. 接口不能声明实例域，不过可以通过声明static和final修饰的域来声明常量。
]]></description>
			<content:encoded><![CDATA[<p>　　类的接口，就是该类允许其他类对象访问的方法和域的集合。一个类实现了某个接口，通常意味着该类的方法将会执行接口方法名表示的操作，遵循接口方法的代码注释和其他相关文档的要求。而类的实现就是位于这些方法体内的代码。</p>
<p>　　比如：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">interface</span> Login <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">boolean</span> login<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> name, <span style="color: #003399;">String</span> password<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>需要注意的地方：<br />
　1. 接口的方法总是抽象的，无论是否显式地声明。<br />
　2. 接口的方法总是公共的，无论是否显式地声明。<br />
　3. 接口的可见性受限于其所在的包，因为Login没有显式地声明为public，所以其在包内可见。<br />
　4. 一个接口可以扩展另一个接口。比如List接口扩展了Collection。<br />
　5. 接口可以不包含方法。不包含方法的接口称为“标记”接口。比如Cloneable接口。<br />
　6. 接口不能声明实例域，不过可以通过声明static和final修饰的域来声明常量。</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/design-pattern-interface.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>MySQL 查询优化</title>
		<link>http://dev.ymeng.net/mysql-query-optimize.html</link>
		<comments>http://dev.ymeng.net/mysql-query-optimize.html#comments</comments>
		<pubDate>Fri, 29 Aug 2008 04:46:29 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[Query Optimize]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=58</guid>
		<description><![CDATA[1. 索引按顺序排列存储
2. 选择索引
　　搜索的索引列，不一定是所要选择的列。出现在ON，WHERE和GROUP BY后的列适合作索引。
　　使用惟一索引
　　　　对于惟一值的列，索引的效果最好。例如：存放年龄的列具有不同值，所以很容易区分各行；而用来记录性别的列，只有&#8217;M'和&#8217;F'，不论搜索哪个值，都会得出大约一半的行，所以对其进行索引没有多大用途。
　　使用短索引
　　　　如果对字符串类型的列进行索引，应该指定一个前辍长度。比如一个varchar(200)的列，最好指定索引为前10个或20个字符内。（短的索引节省存储空间，并可能使查询更快）
　　利用最左前辍
　　　　在创建一个包含n列的索引时，实际上是创建了MySQL可以使用的n个索引。
多列索引可起几个索引的作用，因为可利用索引中最左边的列来匹配行。这样的列的集称为最左前辍。
　　比如在一个表中的state, city和zip三个列上创建索引，那么索引中的行是按state/city/zip的次序存放的。因此，索引中的行也会自动按state/city的顺序和state的顺序来存放。所以，该索引可以用来搜索下列的列的组合：
　　　　state/city/zip
　　　　state/city
　　　　state

　　不要过度索引
　　考虑在列上进行的比较类型
　　　　索引可用于< , =, >和BETWEEN运算，也可以用于LIKE运算。对于其他类型的计算（如STRCP()），则索引不起作用。
3. MySQL查询优化程序
　　EXPLAIN SELECT * FROM student WHERE 1=0;
　　3.1 优化程序怎样工作
　　　　MySQL查询优化程序有几个目标，但主要目标是尽量利用索引，而且尽量使用最具有限制性的索引以排除尽可能多的行。
　　　　比如：WHERE col1=’aaa’ AND col2=’bbb’，col1和col2都是索引。
　　　　假设整个表内，满足这col1=’aaa’的行有900行，满足col2=’bbb’的行有300行，两个条件都满足的行有30行。
　　　　那么，如果首先测试col1，必须检查900行以找到同时与col2值相符的30行，那么在测试col2时，有870行会失败。如果首先测试col2，要找到同时与col1相符的30行，只需要检测300行，这个过程中会有270行失败，这样所涉及的计算较少，磁盘I/O也较少，所以相对来说更快。
　　　　遵循下列准则，有助于优化程序利用索引：
　　　　　　a. 比较具有相同类型的列。
　　　　　　b. 比较中应尽量使用索引列独立。两个例子：
　　　　　　　　1. 比如WHERE col1 < 4 / 2的效果好于WHERE col1 * 2 < 4，后者不会使用索引，且会扫描表中所有行并进行计算。
　　　　　　　　2. 某表中的一个索引列date_col，日期类型
　　　　　　　　　　对于查询WHERE YEAR(date_col) < 1990，并不会使用索引与1990比较，而是将从列值计算出的值与1990比较，而且必须计算每一行。索引没有得到应用。
　　　　　　　　　　改进：WHERE date_col < ‘1990-01-01’
――――――――――――――――――――――――――――
但如果没有特定的日期值，比如要查询到今天为止100天内的记录，有3条语句可以完成这个任务
WHERE TO_DAYS(date_col) – TO_DAYS(CURRENT_DATE) < 100
WHERE TO_DAYS(date_col) < 100 + TO_DAYS(CURRENT_DATE)
WHERE date_col < DATE_ADD(CURRENT_DATE, INTERVAL 100 DAY)
第一条查询不能利用索引，因为必须检索每一行，以计算TO_DAYS(date_col)。
第二条查询要好一些，100和TO_DAYS(CURRENT_DATE)都是常量，因为表达式右边的值可以在查询处理前由优化程序一次计算出来，而不是每行计算一次，但date_col仍然在函数中，所以仍然没有使用索引。
第三条查询是最好的方法，表达式右边会在查询处理前一次性计算出来，其值是一个日期，可以直接和date_col比较，不需要再转换为天数，索引得到利用。
　　　　　　c. [...]]]></description>
			<content:encoded><![CDATA[<p>1. 索引按顺序排列存储</p>
<p>2. 选择索引<br />
　　搜索的索引列，不一定是所要选择的列。出现在ON，WHERE和GROUP BY后的列适合作索引。<br />
　　使用惟一索引<br />
　　　　对于惟一值的列，索引的效果最好。例如：存放年龄的列具有不同值，所以很容易区分各行；而用来记录性别的列，只有&#8217;M'和&#8217;F'，不论搜索哪个值，都会得出大约一半的行，所以对其进行索引没有多大用途。<br />
　　使用短索引<br />
　　　　如果对字符串类型的列进行索引，应该指定一个前辍长度。比如一个varchar(200)的列，最好指定索引为前10个或20个字符内。（短的索引节省存储空间，并可能使查询更快）<br />
　　利用最左前辍<br />
　　　　在创建一个包含n列的索引时，实际上是创建了MySQL可以使用的n个索引。<br />
多列索引可起几个索引的作用，因为可利用索引中最左边的列来匹配行。这样的列的集称为最左前辍。</p>
<p>　　比如在一个表中的state, city和zip三个列上创建索引，那么索引中的行是按state/city/zip的次序存放的。因此，索引中的行也会自动按state/city的顺序和state的顺序来存放。所以，该索引可以用来搜索下列的列的组合：<br />
　　　　state/city/zip<br />
　　　　state/city<br />
　　　　state</p>
<p><span id="more-58"></span></p>
<p>　　不要过度索引<br />
　　考虑在列上进行的比较类型<br />
　　　　索引可用于< , <=, =, >=, >和BETWEEN运算，也可以用于LIKE运算。对于其他类型的计算（如STRCP()），则索引不起作用。</p>
<p>3. MySQL查询优化程序<br />
　　EXPLAIN SELECT * FROM student WHERE 1=0;</p>
<p>　　3.1 优化程序怎样工作<br />
　　　　MySQL查询优化程序有几个目标，但主要目标是尽量利用索引，而且尽量使用最具有限制性的索引以排除尽可能多的行。<br />
　　　　比如：WHERE col1=’aaa’ AND col2=’bbb’，col1和col2都是索引。<br />
　　　　假设整个表内，满足这col1=’aaa’的行有900行，满足col2=’bbb’的行有300行，两个条件都满足的行有30行。<br />
　　　　那么，如果首先测试col1，必须检查900行以找到同时与col2值相符的30行，那么在测试col2时，有870行会失败。如果首先测试col2，要找到同时与col1相符的30行，只需要检测300行，这个过程中会有270行失败，这样所涉及的计算较少，磁盘I/O也较少，所以相对来说更快。</p>
<p>　　　　遵循下列准则，有助于优化程序利用索引：<br />
　　　　　　a. 比较具有相同类型的列。<br />
　　　　　　b. 比较中应尽量使用索引列独立。两个例子：<br />
　　　　　　　　1. 比如WHERE col1 < 4 / 2的效果好于WHERE col1 * 2 < 4，后者不会使用索引，且会扫描表中所有行并进行计算。<br />
　　　　　　　　2. 某表中的一个索引列date_col，日期类型<br />
　　　　　　　　　　对于查询WHERE YEAR(date_col) < 1990，并不会使用索引与1990比较，而是将从列值计算出的值与1990比较，而且必须计算每一行。索引没有得到应用。<br />
　　　　　　　　　　改进：WHERE date_col < ‘1990-01-01’</p>
<p>――――――――――――――――――――――――――――<br />
但如果没有特定的日期值，比如要查询到今天为止100天内的记录，有3条语句可以完成这个任务<br />
WHERE TO_DAYS(date_col) – TO_DAYS(CURRENT_DATE) < 100<br />
WHERE TO_DAYS(date_col) < 100 + TO_DAYS(CURRENT_DATE)<br />
WHERE date_col < DATE_ADD(CURRENT_DATE, INTERVAL 100 DAY)</p>
<p>第一条查询不能利用索引，因为必须检索每一行，以计算TO_DAYS(date_col)。<br />
第二条查询要好一些，100和TO_DAYS(CURRENT_DATE)都是常量，因为表达式右边的值可以在查询处理前由优化程序一次计算出来，而不是每行计算一次，但date_col仍然在函数中，所以仍然没有使用索引。<br />
第三条查询是最好的方法，表达式右边会在查询处理前一次性计算出来，其值是一个日期，可以直接和date_col比较，不需要再转换为天数，索引得到利用。</p>
<p>　　　　　　c. 在LIKE模式的起始处不要使用通配符。<br />
　　　　　　　　查询WHERE name LIKE ‘%zhang%’的效率是很差的。<br />
　　　　　　　　如果要查询以Mac开始的行，可以写成WHERE name LIKE ‘Mac%’，<br />
　　　　　　　　但是WHERE name >= ‘Mac’ AND name < ‘Mad’的效率好于前者。</p>
<p>4. 列类型的选择与查询效率<br />
　　a. 使用定长列，不使用可变长列。特别对于经常修改的表，变长列更容易产生碎片。<br />
　　b. 在较短的列能够满足要求时不要使用较长的列<br />
　　　　比如能使用CHAR(40)就不要使用CHAR(60)，好处：节省空间、节省I/O操作时间。<br />
　　c. 将列定义为NOT NULL<br />
　　　　这样处理速度更快，所需空间也更少。而且有时还能简化查询，因为不需要检查是否存在行例NULL。<br />
　　d. 考虑使用ENUM列<br />
　　　　如果某列的值的数量有限，应该考虑将其转换为ENUM类型。ENUM在内部使用数值表示，具有更快的处理速度。<br />
　　e. 使用PROCEDURE ANALYSE()<br />
　　　　比如SELECT * FROM commodity PROCEDURE ANALYSE();<br />
　　　　会告诉你该列的最大值、最小值、平均值，以及推荐的列类型等等（主要是ENUM）。<br />
　　f. 对容易产生碎片的表使用OPTIMIZE TABLE<br />
　　　　以常进行修改的表、特别包含了变长列（特别是BLOB类型）的表，容易产生碎片。<br />
　　g. 除非需要，应避免检索BLOB或TEXT值　――节省网络传输时间<br />
　　h. 将BLOB或TEXT列分离到一个独立的表中<br />
　　　　在某些情况下，将BLOB或TEXT列从表中移出可能具有一定意义，比如可将剩下的字段设置为定长格式，可以减少碎片，加快处理速度。</p>
<p>5. 有效地装载数据<br />
　　基本理论：<br />
　　a. 成批装载比单行装载更快，因为不需要在装载每个记录后就刷新索引。<br />
　　b. 在表无索引的时候装载比有索引装载快，因为有索引的时候不仅需要写到数据文件，还需要写到索引文件。<br />
　　c. 较短的语句比较长的语句快，因为服务器分析较少，网络传输量也较少。</p>
<p>　　实际结论：<br />
　　a. LOAD DATA比INSERT效率高。<br />
　　b. LOAD DATE比LOAD DATA LOCAL效率高。因为使用LOAD DATA，文件必须在服务器上（需要有FILE权限），节省了网络传输时间。<br />
　　c. 如果必须使用INSERT，应该使用其多行插入形式。比如：<br />
　　　　INSERT INTO student VALUES (1, ‘AAA’), (2, ‘BBB’), …<br />
　　　　这样会减少索引创建的次数，也可以减少网络传送SQL语句的时间。</p>
<p>　　　　如果使用mysqldump来生成SQL备份文件，应该使用—extended-insert选项，使备份文件生成为多行插入形式。或者使用—opt参数。<br />
　　d. 使用压缩参数。当需要在客户机/服务器间传输数据时，对于大多数客户机，可以使用—compress参数。但一般只用于较慢的网络，因为—compress参数需要占用更多的处理器时间。<br />
　　e. 让MySQL来插入缺省值　――减少传输时间和服务器分析语句时间。<br />
　　f. 在装载大量数据之前不要建立索引，待装载完成后再建立索引。或者在装载前删除索引，完成后再重建。</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/mysql-query-optimize.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>MySQL 5.0 字符集(2)－－数据库连接中的字符集</title>
		<link>http://dev.ymeng.net/mysql-character-set-connection.html</link>
		<comments>http://dev.ymeng.net/mysql-character-set-connection.html#comments</comments>
		<pubDate>Fri, 29 Aug 2008 04:44:43 +0000</pubDate>
		<dc:creator>Yangtze</dc:creator>
		
		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[Character Set]]></category>

		<guid isPermaLink="false">http://dev.ymeng.net/?p=55</guid>
		<description><![CDATA[1. 客户端以什么字符集来发送SQL命令？
   character_set_client
2. 当服务器接收到SQL命令时，它会将其转换成什么字符集？
   character_set_connection and collation_connection
   服务器将客户端发送的SQL命令从character_set_client转换到character_set_connection
   在进行字符串比较时，collation_connection将起作用。
   但是在进行column中字符串比较时，collation_connection将不起作用，因为column有自己的collation。
3. 服务器将以什么字符集发送 给果/错误信息 给客户端？
   character_set_results

－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
有两个语句可以改变connection character set：
1. SET NAMES &#8216;charset_name&#8217;;
2. SET CHARACTER SET charset_name;
SET NAMES告诉服务器客户端将使用什么样的字符集来发送SQL命令，也同时指定服务器返回给客户端所使用的字符集。
SET NAMES &#8216;x&#8217; 等效于：
  SET character_set_client = x;
  SET character_set_results = x;
  SET character_set_connection = x;
  [...]]]></description>
			<content:encoded><![CDATA[<p>1. 客户端以什么字符集来发送SQL命令？<br />
   character_set_client</p>
<p>2. 当服务器接收到SQL命令时，它会将其转换成什么字符集？<br />
   character_set_connection and collation_connection<br />
   服务器将客户端发送的SQL命令从character_set_client转换到character_set_connection<br />
   在进行字符串比较时，collation_connection将起作用。<br />
   但是在进行column中字符串比较时，collation_connection将不起作用，因为column有自己的collation。</p>
<p>3. 服务器将以什么字符集发送 给果/错误信息 给客户端？<br />
   character_set_results</p>
<p><span id="more-55"></span><br />
－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br />
有两个语句可以改变connection character set：<br />
1. SET NAMES &#8216;charset_name&#8217;;<br />
2. SET CHARACTER SET charset_name;</p>
<p>SET NAMES告诉服务器客户端将使用什么样的字符集来发送SQL命令，也同时指定服务器返回给客户端所使用的字符集。</p>
<p>SET NAMES &#8216;x&#8217; 等效于：<br />
  SET character_set_client = x;<br />
  SET character_set_results = x;<br />
  SET character_set_connection = x;<br />
   (注：SET character_set_connection = x; 语句同时也自动指定了字符集x的默认collation为 collation_connection的值，但也可以用 SET NAMES &#8216;charset_name&#8217; COLLATE &#8216;collation_name&#8217;来提定你想使用的collation。)</p>
<p>SET CHARACTER SET和SET NAMES作用相似，但它将连接的字符集和collation设置为默认数据库的字符集和collation。</p>
<p>SET CHARACTER SET x 等效于：<br />
  SET character_set_client = x;<br />
  SET character_set_results = x;<br />
  SET collation_connection = @@collation_database;<br />
  (注：SET collation_connection同时也会自动设置character_set_connection。)</p>
<p>如果不希望MySQL在返回结果时进行转换，可以使用SET character_set_results = NULL;语句</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.ymeng.net/mysql-character-set-connection.html/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
