﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-花香蝶自来-随笔分类-Spring</title><link>http://www.blogjava.net/ltc603/category/14099.html</link><description>&lt;font size="3"&gt;学无止境&lt;/font&gt;
&lt;br&gt;

&lt;script type="text/javascript" src="http://wujunlove.googlepages.com/bigstaticeyes.js"&gt;&lt;/script&gt;</description><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 06:23:25 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 06:23:25 GMT</pubDate><ttl>60</ttl><item><title>使用 Spring 更好地处理 Struts 动作</title><link>http://www.blogjava.net/ltc603/archive/2006/09/12/69163.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Tue, 12 Sep 2006 07:11:00 GMT</pubDate><guid>http://www.blogjava.net/ltc603/archive/2006/09/12/69163.html</guid><wfw:comment>http://www.blogjava.net/ltc603/comments/69163.html</wfw:comment><comments>http://www.blogjava.net/ltc603/archive/2006/09/12/69163.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ltc603/comments/commentRss/69163.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ltc603/services/trackbacks/69163.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 三种整合 Struts 应用程序与 Spring 的方式																																																																																																																																								...&nbsp;&nbsp;<a href='http://www.blogjava.net/ltc603/archive/2006/09/12/69163.html'>阅读全文</a><img src ="http://www.blogjava.net/ltc603/aggbug/69163.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ltc603/" target="_blank">阿成</a> 2006-09-12 15:11 <a href="http://www.blogjava.net/ltc603/archive/2006/09/12/69163.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring的事件处理机制</title><link>http://www.blogjava.net/ltc603/archive/2006/09/04/67502.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Mon, 04 Sep 2006 01:10:00 GMT</pubDate><guid>http://www.blogjava.net/ltc603/archive/2006/09/04/67502.html</guid><wfw:comment>http://www.blogjava.net/ltc603/comments/67502.html</wfw:comment><comments>http://www.blogjava.net/ltc603/archive/2006/09/04/67502.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ltc603/comments/commentRss/67502.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ltc603/services/trackbacks/67502.html</trackback:ping><description><![CDATA[
		<div id="msgcns!367370EB9A9B2807!129">
				<div>Spring本身有ApplicationEvent和ApplicationListener，ApplicationContext可以发布ApplicationEvent，然后ApplicationListener监听event并做出相应动作。但是这里的ApplicationEvent有个陷阱，它的传播范围和当前的ApplicationContext的级别有关，<font color="#ff0000"><strong>并不是系统中所有的ApplicationListener都可以收到所有的Event</strong></font>。</div>
				<div> </div>
				<div>假设当前系统为一个典型的Struts+Spring+Hibernate系统，那么系统中至少会有两个ApplicationContext存在，一个时root ApplicationContext，一个是Servlet的ApplicationContext。root ApplicationContext中包含你所有在webApplicationContext.xml中定义的bean，Servlet的ApplicationContext则包含有所有在action-servlet.xml中定义的bean，<font color="#ff0000"><strong>需要注意的是root context中的bean是无法看到servlet context中的bean的</strong></font>。<strong><font color="#ff0000">而在servlet context中的ApplicationListener也无法收到root context发布的ApplicationEvent</font></strong>。<br /><br /><a href="http://sweetriver.spaces.live.com/blog/cns!367370EB9A9B2807!129.entry">http://sweetriver.spaces.live.com/blog/cns!367370EB9A9B2807!129.entry</a></div>
		</div>
<img src ="http://www.blogjava.net/ltc603/aggbug/67502.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ltc603/" target="_blank">阿成</a> 2006-09-04 09:10 <a href="http://www.blogjava.net/ltc603/archive/2006/09/04/67502.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>简化Spring</title><link>http://www.blogjava.net/ltc603/archive/2006/08/29/66344.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Tue, 29 Aug 2006 00:58:00 GMT</pubDate><guid>http://www.blogjava.net/ltc603/archive/2006/08/29/66344.html</guid><wfw:comment>http://www.blogjava.net/ltc603/comments/66344.html</wfw:comment><comments>http://www.blogjava.net/ltc603/archive/2006/08/29/66344.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ltc603/comments/commentRss/66344.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ltc603/services/trackbacks/66344.html</trackback:ping><description><![CDATA[
		<a id="_814bc1840a6fa23_HomePageDays_DaysList__ctl3_DayItem_DayList__ctl1_TitleUrl" href="/calvin/archive/2005/08/21/10530.html">
				<font color="#366900">简化Spring(1)--配置文件</font>
		</a>
		<br />
		<br />
		<a id="_814bc1840a6fa23_HomePageDays_DaysList__ctl2_DayItem_DayList__ctl1_TitleUrl" href="/calvin/archive/2005/08/22/10695.html">
				<font color="#366900">简化Spring(2)--Model层</font>
				<br />
		</a>
		<br />
		<a id="_814bc1840a6fa23_HomePageDays_DaysList__ctl1_DayItem_DayList__ctl1_TitleUrl" href="/calvin/archive/2005/08/23/10794.html">
				<font color="#366900">简化Spring(3)--Controller层</font>
		</a>
		<br />
		<br />
		<a id="_814bc1840a6fa23_HomePageDays_DaysList__ctl0_DayItem_DayList__ctl1_TitleUrl" href="/calvin/archive/2005/08/24/10914.html">
				<font color="#366900">简化Spring(4)--View层</font>
		</a>
<img src ="http://www.blogjava.net/ltc603/aggbug/66344.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ltc603/" target="_blank">阿成</a> 2006-08-29 08:58 <a href="http://www.blogjava.net/ltc603/archive/2006/08/29/66344.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>读取配置文件的几种方法 －ZT（zhaijianhui的blog）</title><link>http://www.blogjava.net/ltc603/archive/2006/06/08/51260.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Thu, 08 Jun 2006 01:12:00 GMT</pubDate><guid>http://www.blogjava.net/ltc603/archive/2006/06/08/51260.html</guid><wfw:comment>http://www.blogjava.net/ltc603/comments/51260.html</wfw:comment><comments>http://www.blogjava.net/ltc603/archive/2006/06/08/51260.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ltc603/comments/commentRss/51260.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ltc603/services/trackbacks/51260.html</trackback:ping><description><![CDATA[
		<div class="postText">在读spring in aciton 时，他用的BeanFactory factory = new XmlBeanFactory(new FileInputStream("hello.xml"));<br />可是现在的用的1.2.6版本的构造器(XmlBeanFactory)只能接收Resource接口了，所以调不出来是正常的事情，假设现在有一个文件hello.xml<br />读取方法<br /><br />1:ApplicationContext cx=new FileSystemXmlApplicationContext("hello.xml");//指定的路径去找文件<br />2:ApplicationContext factory = new ClassPathXmlApplicationContext("hello.xml");//还会在classpath去找<br />3:Resource fa = new FileSystemResource("hello.xml");<br />   BeanFactory factory=new XmlBeanFactory(fa);<br />4:这个要设制classpath了，麻烦<br />　 Resource res = new ClassPathResource("com/springinaction/chapter01/hello/hello.xml");<br />　 BeanFactory factory=new XmlBeanFactory(res);<br />好了，用了上面那种方法都可以调用getBean("your bean name")了，<br />eg: BeanFactory factory=new XmlBeanFactory(fa);<br />      hello he=(hello)factory.getBean("hello");<br />              he.getHello(); </div>
<img src ="http://www.blogjava.net/ltc603/aggbug/51260.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ltc603/" target="_blank">阿成</a> 2006-06-08 09:12 <a href="http://www.blogjava.net/ltc603/archive/2006/06/08/51260.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring 入门实例</title><link>http://www.blogjava.net/ltc603/archive/2006/04/18/41693.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Tue, 18 Apr 2006 09:28:00 GMT</pubDate><guid>http://www.blogjava.net/ltc603/archive/2006/04/18/41693.html</guid><wfw:comment>http://www.blogjava.net/ltc603/comments/41693.html</wfw:comment><comments>http://www.blogjava.net/ltc603/archive/2006/04/18/41693.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/ltc603/comments/commentRss/41693.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ltc603/services/trackbacks/41693.html</trackback:ping><description><![CDATA[
		<p>Spring是一个非常优秀的轻量级框架，通过Spring的IoC容器，我们的关注点便放到了需要实现的业务逻辑上。对AOP的支持则能让我们动态增强业务方法。编写普通的业务逻辑Bean是非常容易而且易于测试的，因为它能脱离J2EE容器（如Servlet，JSP环境）单独进行单元测试。最后的一步便是在Spring框架中将这些业务Bean以XML配置文件的方式组织起来，它们就按照我们预定的目标正常工作了！非常容易！</p>
		<p>本文将给出一个基本的Spring入门示例，并演示如何使用Spring的AOP将复杂的业务逻辑分离到每个方面中。</p>
		<p>1．开发环境配置<br />2．编写Bean接口及其实现<br />3．在Spring中配置Bean并获得Bean的实例<br />4．编写Advisor以增强ServiceBean<br />5．总结</p>
		<h3>1．开发环境配置</h3>
		<p>首先，需要正确配置Java环境。推荐安装JDK1.4.2，并正确配置环境变量：</p>
		<p>JAVA_HOME=&lt;JDK安装目录&gt;<br />CLASSPATH=.<br />Path=%JAVA_HOME%\bin;……</p>
		<p>我们将使用免费的Eclipse 3.1作为IDE。新建一个Java Project，将Spring的发布包spring.jar以及commons-logging-1.0.4.jar复制到Project目录下，并在Project &gt; Properties中配置好Java Build Path：</p>
		<p>
				<img onmousewheel="return bbimg(this)" style="" alt="" src="http://www.crackj2ee.com/Article/UploadFiles/200604/20060402192206665.jpg" onload="javascript:resizepic(this)" border="undefined" />
		</p>
		<h3>2．编写Bean接口及其实现</h3>
		<p>我们实现一个管理用户的业务Bean。首先定义一个ServiceBean接口，声明一些业务方法：</p>
		<pre>
				<font color="#0066ff">/**<br /> * Copyright_2006, Liao Xuefeng<br /> * Created on 2006-3-9<br /> * For more information, please visit: </font>
				<a href="http://www.crackj2ee.com/">
						<font color="#0066ff">http://www.crackj2ee.com</font>
				</a>
				<br />
				<font color="#0066ff"> */<br />package com.crackj2ee.example.spring;</font>
		</pre>
		<pre>
				<font color="#0066ff">/**<br /> * Interface of service facade.<br /> * <br /> * @author Xuefeng<br /> */<br />public interface ServiceBean {<br />    void addUser(String username, String password);<br />    void deleteUser(String username);<br />    boolean findUser(String username);<br />    String getPassword(String username);<br />}</font>
		</pre>
		<p>然后在MyServiceBean中实现接口：</p>
		<pre>
				<font color="#0066ff">/**<br /> * Copyright_2006, Liao Xuefeng<br /> * Created on 2006-3-9<br /> * <br /> * For more information, please visit: </font>
				<a href="http://www.crackj2ee.com/">
						<font color="#0066ff">http://www.crackj2ee.com</font>
				</a>
				<br />
				<font color="#0066ff"> */<br />package com.crackj2ee.example.spring;</font>
		</pre>
		<pre>
				<font color="#0066ff">import java.util.*;</font>
		</pre>
		<pre>
				<font color="#0066ff">public class MyServiceBean implements ServiceBean {</font>
		</pre>
		<pre>
				<font color="#0066ff">    private String dir;<br />    private Map map = new HashMap();</font>
		</pre>
		<pre>
				<font color="#0066ff">    public void setUserDir(String dir) {<br />        this.dir = dir;<br />        System.out.println("Set user dir to: " + dir);<br />    }</font>
		</pre>
		<pre>
				<font color="#0066ff">    public void addUser(String username, String password) {<br />        if(!map.containsKey(username))<br />            map.put(username, password);<br />        else<br />            throw new RuntimeException("User already exist.");<br />    }</font>
		</pre>
		<pre>
				<font color="#0066ff">    public void deleteUser(String username) {<br />        if(map.remove(username)==null)<br />            throw new RuntimeException("User not exist.");<br />    }</font>
		</pre>
		<pre>
				<font color="#0066ff">    public boolean findUser(String username) {<br />        return map.containsKey(username);<br />    }</font>
		</pre>
		<pre>
				<font color="#0066ff">    public String getPassword(String username) {<br />        return (String)map.get(username);<br />    }<br />}</font>
		</pre>
		<p>为了简化逻辑，我们使用一个Map保存用户名和口令。</p>
		<p>现在，我们已经有了一个业务Bean。要测试它非常容易，因为到目前为止，我们还没有涉及到Spring容器，也没有涉及到任何Web容器（假定这是一个Web应用程序关于用户管理的业务Bean）。完全可以直接进行Unit测试，或者，简单地写个main方法测试：</p>
		<pre>
				<font color="#0066ff">/**<br /> * Copyright_2006, Liao Xuefeng<br /> * Created on 2006-3-9<br /> * For more information, please visit: </font>
				<a href="http://www.crackj2ee.com/">
						<font color="#0066ff">http://www.crackj2ee.com</font>
				</a>
				<br />
				<font color="#0066ff"> */<br />package com.crackj2ee.example.spring;</font>
		</pre>
		<pre>
				<font color="#0066ff">public class Main {</font>
		</pre>
		<pre>
				<font color="#0066ff">    public static void main(String[] args) throws Exception {<br />        ServiceBean service = new MyServiceBean();<br />        service.addUser("bill", "hello");<br />        service.addUser("tom", "goodbye");<br />        service.addUser("tracy", "morning");<br />        System.out.println("tom's password is: " + service.getPassword("tom"));<br />        if(service.findUser("tom")) {<br />            service.deleteUser("tom");<br />        }<br />    }<br />}</font>
		</pre>
		<p>执行结果：<br /><img onmousewheel="return bbimg(this)" style="" alt="" src="http://www.crackj2ee.com/Article/UploadFiles/200604/20060402192408916.jpg" onload="javascript:resizepic(this)" border="undefined" /></p>
		<h3>3．在Spring中配置Bean并获得Bean的实例</h3>
		<p>我们已经在一个main方法中实现了业务，不过，将对象的生命周期交给容器管理是更好的办法，我们就不必为初始化对象和销毁对象进行硬编码，从而获得更大的灵活性和可测试性。</p>
		<p>想要把ServiceBean交给Spring来管理，我们需要一个XML配置文件。新建一个beans.xml，放到src目录下，确保在classpath中能找到此配置文件，输入以下内容：</p>
		<pre>
				<font color="#0066ff">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" <br />"</font>
				<a href="http://www.springframework.org/dtd/spring-beans.dtd">
						<font color="#0066ff">http://www.springframework.org/dtd/spring-beans.dtd</font>
				</a>
				<font color="#0066ff">"&gt;<br />&lt;beans&gt;<br />    &lt;bean id="service" class="com.crackj2ee.example.spring.MyServiceBean" /&gt;<br />&lt;/beans&gt;</font>
		</pre>
		<p>以上XML声明了一个id为service的Bean，默认地，Spring为每个声明的Bean仅创建一个实例，并通过id来引用这个Bean。下面，我们修改main方法，让Spring来管理业务Bean：</p>
		<pre>
				<font color="#0066ff">/**<br /> * Copyright_2006, Liao Xuefeng<br /> * Created on 2006-3-9<br /> * For more information, please visit: </font>
				<a href="http://www.crackj2ee.com/">
						<font color="#0066ff">http://www.crackj2ee.com</font>
				</a>
				<br />
				<font color="#0066ff"> */<br />package com.crackj2ee.example.spring;</font>
		</pre>
		<pre>
				<font color="#0066ff">import org.springframework.beans.factory.xml.XmlBeanFactory;<br />import org.springframework.core.io.ClassPathResource;</font>
		</pre>
		<pre>
				<font color="#0066ff">public class Main {</font>
		</pre>
		<pre>
				<font color="#0066ff">    public static void main(String[] args) throws Exception {<br />        // init factory:<br />        <font color="#ff0000">XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));</font><br />        // use service bean:<br />        ServiceBean service = (ServiceBean)factory.getBean("service");<br />        service.addUser("bill", "hello");<br />        service.addUser("tom", "goodbye");<br />        service.addUser("tracy", "morning");<br />        System.out.println("tom's password is \"" + service.getPassword("tom") + "\"");<br />        if(service.findUser("tom")) {<br />            service.deleteUser("tom");<br />        }<br />        // close factory:<br />        <font color="#ff0000">factory.destroySingletons();</font><br />    }<br />}</font>
		</pre>
		<p>执行结果：<br /> <img onmousewheel="return bbimg(this)" style="" alt="" src="http://www.crackj2ee.com/Article/UploadFiles/200604/20060402192443792.jpg" onload="javascript:resizepic(this)" border="undefined" /></p>
		<p>由于我们要通过main方法启动Spring环境，因此，首先需要初始化一个BeanFactory。红色部分是初始化Spring的BeanFactory的典型代码，只需要保证beans.xml文件位于classpath中。</p>
		<p>然后，在BeanFactory中通过id查找，即可获得相应的Bean的实例，并将其适当转型为合适的接口。</p>
		<p>接着，实现一系列业务操作，在应用程序结束前，让Spring销毁所有的Bean实例。</p>
		<p>对比上一个版本的Main，可以看出，最大的变化是不需要自己管理Bean的生命周期。另一个好处是在不更改实现类的前提下，动态地为应用程序增加功能。</p>
		<h3>4．编写Advisor以增强ServiceBean</h3>
		<p>所谓AOP即是将分散在各个方法处的公共代码提取到一处，并通过类似拦截器的机制实现代码的动态织入。可以简单地想象成，在某个方法的调用前、返回前、调用后和抛出异常时，动态插入自己的代码。在弄清楚Pointcut、Advice之类的术语前，不如编写一个最简单的AOP应用来体验一下。</p>
		<p>考虑一下通常的Web应用程序都会有日志记录，我们来编写一个LogAdvisor，对每个业务方法调用前都作一个记录：</p>
		<pre>
				<font color="#0066ff">/**<br /> * Copyright_2006, Liao Xuefeng<br /> * Created on 2006-3-9<br /> * For more information, please visit: </font>
				<a href="http://www.crackj2ee.com/">
						<font color="#0066ff">http://www.crackj2ee.com</font>
				</a>
				<br />
				<font color="#0066ff"> */<br />package com.crackj2ee.example.spring;</font>
		</pre>
		<pre>
				<font color="#0066ff">import java.lang.reflect.Method;<br />import org.springframework.aop.MethodBeforeAdvice;</font>
		</pre>
		<pre>
				<font color="#0066ff">public class LogAdvisor implements MethodBeforeAdvice {<br />    public void before(Method m, Object[] args, Object target) throws Throwable {<br />        System.out.println("[Log] " + target.getClass().getName() + "." + m.getName() + "()");<br />    }<br />}</font>
		</pre>
		<p>然后，修改beans.xml：</p>
		<pre>
				<font color="#0066ff">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" <br />"</font>
				<a href="http://www.springframework.org/dtd/spring-beans.dtd">
						<font color="#0066ff">http://www.springframework.org/dtd/spring-beans.dtd</font>
				</a>
				<font color="#0066ff">"&gt;</font>
		</pre>
		<pre>
				<font color="#0066ff">&lt;beans&gt;<br />    &lt;bean id="serviceTarget" class="com.crackj2ee.example.spring.MyServiceBean" /&gt;</font>
		</pre>
		<pre>
				<font color="#0066ff">    &lt;bean id="logAdvisor" class="com.crackj2ee.example.spring.LogAdvisor" /&gt;</font>
		</pre>
		<pre>
				<font color="#0066ff">    &lt;bean id="service" class="org.springframework.aop.framework.ProxyFactoryBean"&gt;<br />        &lt;property name="proxyInterfaces"&gt;&lt;value&gt;com.crackj2ee.example.spring.ServiceBean&lt;/value&gt;&lt;/property&gt;<br />        &lt;property name="target"&gt;&lt;ref local="serviceTarget"/&gt;&lt;/property&gt;<br />        &lt;property name="interceptorNames"&gt;<br />            &lt;list&gt;<br />                &lt;value&gt;logAdvisor&lt;/value&gt;<br />            &lt;/list&gt;<br />        &lt;/property&gt;<br />    &lt;/bean&gt;<br />&lt;/beans&gt;</font>
		</pre>
		<p>注意观察修改后的配置文件，我们使用了一个ProxyFactoryBean作为service来与客户端打交道，而真正的业务Bean即MyServiceBean被声明为serviceTarget并作为参数对象传递给ProxyFactoryBean，proxyInterfaces指定了返回的接口类型。对于客户端而言，将感觉不出任何变化，但却动态加入了LogAdvisor，关系如下：<br /> <img onmousewheel="return bbimg(this)" alt="" src="http://www.crackj2ee.com/Article/UploadFiles/200604/20060402192529808.jpg" onload="javascript:resizepic(this)" border="undefined" /></p>
		<p>运行结果如下，可以很容易看到调用了哪些方法：<br /> <img onmousewheel="return bbimg(this)" alt="" src="http://www.crackj2ee.com/Article/UploadFiles/200604/20060402192542603.jpg" onload="javascript:resizepic(this)" border="undefined" /></p>
		<p>要截获指定的某些方法也是可以的。下面的例子将修改getPassword()方法的返回值：</p>
		<pre>
				<font color="#0066ff">/**<br /> * Copyright_2006, Liao Xuefeng<br /> * Created on 2006-3-9<br /> * For more information, please visit: </font>
				<a href="http://www.crackj2ee.com/">
						<font color="#0066ff">http://www.crackj2ee.com</font>
				</a>
				<br />
				<font color="#0066ff"> */<br />package com.crackj2ee.example.spring;</font>
		</pre>
		<pre>
				<font color="#0066ff">import org.aopalliance.intercept.MethodInterceptor;<br />import org.aopalliance.intercept.MethodInvocation;</font>
		</pre>
		<pre>
				<font color="#0066ff">public class PasswordAdvisor implements MethodInterceptor {<br />    public Object invoke(MethodInvocation invocation) throws Throwable {<br />        Object ret = invocation.proceed();<br />        if(ret==null)<br />            return null;<br />        String password = (String)ret;<br />        StringBuffer encrypt = new StringBuffer(password.length());<br />        for(int i=0; i&lt;password.length(); i++)<br />            encrypt.append('*');<br />        return encrypt.toString();<br />    }<br />}</font>
		</pre>
		<p>这个PasswordAdvisor将截获ServiceBean的getPassword()方法的返回值，并将其改为"***"。继续修改beans.xml：</p>
		<pre>
				<font color="#0066ff">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" <br />"</font>
				<a href="http://www.springframework.org/dtd/spring-beans.dtd">
						<font color="#0066ff">http://www.springframework.org/dtd/spring-beans.dtd</font>
				</a>
				<font color="#0066ff">"&gt;<br />&lt;beans&gt;<br />    &lt;bean id="serviceTarget" class="com.crackj2ee.example.spring.MyServiceBean" /&gt;</font>
		</pre>
		<pre>
				<font color="#0066ff">    &lt;bean id="logAdvisor" class="com.crackj2ee.example.spring.LogAdvisor" /&gt;</font>
		</pre>
		<pre>
				<font color="#0066ff">    &lt;bean id="passwordAdvisorTarget" class="com.crackj2ee.example.spring.PasswordAdvisor" /&gt;</font>
		</pre>
		<pre>
				<font color="#0066ff">    &lt;bean id="passwordAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"&gt;<br />        &lt;property name="advice"&gt;<br />            &lt;ref local="passwordAdvisorTarget"/&gt;<br />        &lt;/property&gt;<br />        &lt;property name="patterns"&gt;<br />            &lt;list&gt;<br />                &lt;value&gt;.*getPassword&lt;/value&gt;<br />            &lt;/list&gt;<br />        &lt;/property&gt;<br />    &lt;/bean&gt;</font>
		</pre>
		<pre>
				<font color="#0066ff">    &lt;bean id="service" class="org.springframework.aop.framework.ProxyFactoryBean"&gt;<br />        &lt;property name="proxyInterfaces"&gt;&lt;value&gt;com.crackj2ee.example.spring.ServiceBean&lt;/value&gt;&lt;/property&gt;<br />        &lt;property name="target"&gt;&lt;ref local="serviceTarget"/&gt;&lt;/property&gt;<br />        &lt;property name="interceptorNames"&gt;<br />            &lt;list&gt;<br />                &lt;value&gt;logAdvisor&lt;/value&gt;<br />                &lt;value&gt;passwordAdvisor&lt;/value&gt;<br />            &lt;/list&gt;<br />        &lt;/property&gt;<br />    &lt;/bean&gt;<br />&lt;/beans&gt;</font>
		</pre>
		<p>利用Spring提供的一个RegexMethodPointcutAdvisor可以非常容易地指定要截获的方法。运行结果如下，可以看到返回结果变为"******"：<br /> <img onmousewheel="return bbimg(this)" style="" alt="" src="http://www.crackj2ee.com/Article/UploadFiles/200604/20060402192623904.jpg" onload="javascript:resizepic(this)" border="undefined" /></p>
		<p>还需要继续增强ServiceBean？我们编写一个ExceptionAdvisor，在业务方法抛出异常时能做一些处理：</p>
		<pre>
				<font color="#0066ff">/**<br /> * Copyright_2006, Liao Xuefeng<br /> * Created on 2006-3-9<br /> * For more information, please visit: </font>
				<a href="http://www.crackj2ee.com/">
						<font color="#0066ff">http://www.crackj2ee.com</font>
				</a>
				<br />
				<font color="#0066ff"> */<br />package com.crackj2ee.example.spring;</font>
		</pre>
		<pre>
				<font color="#0066ff">import org.springframework.aop.ThrowsAdvice;</font>
		</pre>
		<pre>
				<font color="#0066ff">public class ExceptionAdvisor implements ThrowsAdvice {<br />    public void afterThrowing(RuntimeException re) throws Throwable {<br />        System.out.println("[Exception] " + re.getMessage());<br />    }<br />}</font>
		</pre>
		<p>将此Advice添加到beans.xml中，然后在业务Bean中删除一个不存在的用户，故意抛出异常：</p>
		<pre>
				<font color="#0066ff">service.deleteUser("not-exist");</font>
		</pre>
		<p>再次运行，注意到ExceptionAdvisor记录下了异常：<br /> <img onmousewheel="return bbimg(this)" alt="" src="http://www.crackj2ee.com/Article/UploadFiles/200604/20060402192701196.jpg" onload="javascript:resizepic(this)" border="undefined" /></p>
		<h3>5．总结</h3>
		<p>利用Spring非常强大的IoC容器和AOP功能，我们能实现非常灵活的应用，让Spring容器管理业务对象的生命周期，利用AOP增强功能，却不影响业务接口，从而避免更改客户端代码。</p>
		<p>为了实现这一目标，必须始终牢记：面向接口编程。而Spring默认的AOP代理也是通过Java的代理接口实现的。虽然Spring也可以用CGLIB实现对普通类的代理，但是，业务对象只要没有接口，就会变得难以扩展、维护和测试。</p>
		<p>可以从此处下载完整的Eclipse工程：<br /><a href="http://www.crackj2ee.com/Article/UploadFiles/200604/SpringBasic.rar">http://www.crackj2ee.com/Article/UploadFiles/200604/SpringBasic.rar</a></p>
<img src ="http://www.blogjava.net/ltc603/aggbug/41693.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ltc603/" target="_blank">阿成</a> 2006-04-18 17:28 <a href="http://www.blogjava.net/ltc603/archive/2006/04/18/41693.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring学习笔记(一)依赖注入</title><link>http://www.blogjava.net/ltc603/archive/2006/03/23/37037.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Thu, 23 Mar 2006 05:46:00 GMT</pubDate><guid>http://www.blogjava.net/ltc603/archive/2006/03/23/37037.html</guid><wfw:comment>http://www.blogjava.net/ltc603/comments/37037.html</wfw:comment><comments>http://www.blogjava.net/ltc603/archive/2006/03/23/37037.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ltc603/comments/commentRss/37037.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ltc603/services/trackbacks/37037.html</trackback:ping><description><![CDATA[
		<div>Spring学习笔记(一)依赖注入</div>
		<div> </div>
		<div>依赖注入——是Spring最灵魂的设计思想，有人也叫做控制反转。</div>
		<div>1、不管是依赖注入（DI:Dependency Injection）还是控制反转（IoC:Inversion of Control）它的思想是：控制权由应用代码中转到了外部</div>
		<div>容器，即组件之间的依赖关系由容器在运行期决定，形象的来说，即由容器动态的将某种依赖关系注入到组件之中。</div>
		<div>2、依赖注入的目标并非为软件系统带来更多的功能，而是为了提升组件重用的概率，带来灵活性。</div>
		<div>3、举个例子来说明这个问题。</div>
		<div>我曾看到夏昕的《Spring 开发指南》，上面为说明这个思想，举了电脑、USB硬盘和U盘的例子，感觉还是不太贴切，今天想了个自认为比较好</div>
		<div>理解的例子：</div>
		<div>有两种变形金刚的玩具，<br />一种是固定的，我把它比作原来那种控制权由应用代码写死的程序<br />一种可以拆开重新装配的，我把它比作用了依赖注入设计思想的程序</div>
		<div>变形金刚的各个部件就象程序的各个组件。<br />变形金刚的厂家，相对它来说是内部的。就象程序的代码<br />变形金刚的玩家，相对它来说是外部的。就象程序的容器</div>
		<div>大家试想一下，固定变形金刚的控制权是不是厂家决定的，外部无能为力<br />而可拆卸的变形金刚的控制权转移到了外部的玩家，玩家在玩之前可以重新决定各个组件的连接关系</div>
		<div>而这种组件的连接图是不是也很像依赖注入思想里的配置文件。</div>
		<div>大家再从这个例子分析一下依赖注入的目标。</div>
		<div>1)功能变化有限，你变形金刚设计的再好，可变换的东西也不过相似的几种。<br />2)真正的目的是提升组件重用的概率，带来灵活性。<br />引用地址 <a href="http://spaces.msn.com/pococoon/blog/cns%21D25B6032F7AD1992%21195.entry"><font color="#3f6242">http://spaces.msn.com/pococoon/blog/cns!D25B6032F7AD1992!195.entry</font></a></div>
<img src ="http://www.blogjava.net/ltc603/aggbug/37037.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ltc603/" target="_blank">阿成</a> 2006-03-23 13:46 <a href="http://www.blogjava.net/ltc603/archive/2006/03/23/37037.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring学习笔记(二)Bean </title><link>http://www.blogjava.net/ltc603/archive/2006/03/23/37035.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Thu, 23 Mar 2006 05:42:00 GMT</pubDate><guid>http://www.blogjava.net/ltc603/archive/2006/03/23/37035.html</guid><wfw:comment>http://www.blogjava.net/ltc603/comments/37035.html</wfw:comment><comments>http://www.blogjava.net/ltc603/archive/2006/03/23/37035.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ltc603/comments/commentRss/37035.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ltc603/services/trackbacks/37035.html</trackback:ping><description><![CDATA[
		<span class="postbody">Spring使用BeanFactory模式来管理Bean,但Spring中提到的Bean不是标准的意义上的JavaBean(仅包含一个默认的构造函数，在属性后面定义相对应的setter和getter方法),而是任何你想让它管理的类，比如连接池、甚至BeanFactory本身。 <br /><br />一)Bean的设计常用下面几种模式 <br /><br />1、标准Bean: <br /><br />使用默认的构造函数和基于setter、getter方法的依赖注射 <br /><br />Bean类代码： <br /><br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />
												<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">public</span>
												<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span> ExampleBean <span style="color: rgb(0, 0, 0);">{</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span> BeanOne beanOne; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span> BeanTwo beanTwo; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">int</span> count; <br />    <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">void</span> setBeanOne<span style="color: rgb(0, 0, 0);">(</span>BeanOne beanOne<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        this.<span style="color: rgb(0, 0, 0);">beanOne</span> = beanOne; <br />    <span style="color: rgb(0, 0, 0);">}</span><br />    <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">void</span> setBeanTwo<span style="color: rgb(0, 0, 0);">(</span>BeanTwo beanTwo<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        this.<span style="color: rgb(0, 0, 0);">beanTwo</span> = beanTwo; <br />    <span style="color: rgb(0, 0, 0);">}</span><br />    <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">void</span> setCount<span style="color: rgb(0, 0, 0);">(</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">int</span> count<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        this.<span style="color: rgb(0, 0, 0);">count</span> = count; <br />    <span style="color: rgb(0, 0, 0);">}</span>    <br /><span style="color: rgb(0, 0, 0);">}</span><br /></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />在配置文件中定义： <br /><br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />&lt;bean id="exampleBean" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">ExampleBean</span>"&gt; <br />    &lt;property name="beanOne"&gt;&lt;ref bean="bean1"/&gt;&lt;/property&gt; <br />    &lt;property name="beanTwo"&gt;&lt;ref bean="bean2"/&gt;&lt;/property&gt; <br />    &lt;property name="count"&gt;&lt;value&gt;<span style="color: rgb(0, 0, 0);" ?="">1</span>&lt;/value&gt;&lt;/property&gt; <br />&lt;/bean&gt; <br /><br />&lt;bean id="bean1" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">BeanOne</span>"/&gt; <br />&lt;bean id="bean2" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">BeanTwo</span>"/&gt; <br /></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />2、构造函数模式 <br /><br />自定义的构造函数，基于构造函数参数的依赖注射 <br /><br />Bean类代码： <br /><br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />
												<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">public</span>
												<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span> ExampleBean <span style="color: rgb(0, 0, 0);">{</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span> BeanOne beanOne; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span> BeanTwo beanTwo; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">int</span> count; <br />    <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">public</span> ExampleBean<span style="color: rgb(0, 0, 0);">(</span>BeanOne beanOne, BeanTwo beanTwo, <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">int</span> count<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        this.<span style="color: rgb(0, 0, 0);">beanOne</span> = beanOne; <br />        this.<span style="color: rgb(0, 0, 0);">beanTwo</span> = beanTwo; <br />        this.<span style="color: rgb(0, 0, 0);">count</span> = count; <br />    <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span><br /></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />在配置文件中定义： <br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />
												<br />&lt;bean id="exampleBean" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">ExampleBean</span>"&gt; <br />    &lt;constructor-arg&gt;&lt;ref bean="bean1"/&gt;&lt;/constructor-arg&gt; <br />    &lt;constructor-arg&gt;&lt;ref bean="bean2"/&gt;&lt;/constructor-arg&gt; <br />    &lt;constructor-arg&gt;&lt;value&gt;<span style="color: rgb(0, 0, 0);" ?="">1</span>&lt;/value&gt;&lt;/constructor-arg&gt; <br />&lt;/bean&gt; <br /><br />&lt;bean id="bean1" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">BeanOne</span>"/&gt; <br />&lt;bean id="bean2" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">BeanTwo</span>"/&gt; <br /></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />3、静态工厂方法模式 <br /><br />静态工厂方法必须是static的，基于方法参数的依赖注射。 <br /><br />Bean类代码： <br /><br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />
												<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">public</span>
												<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span> ExampleBean <span style="color: rgb(0, 0, 0);">{</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span> BeanOne beanOne; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span> BeanTwo beanTwo; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">int</span> count; <br />    <span style="color: rgb(102, 102, 255);">//构造函数私有</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span> ExampleBean<span style="color: rgb(0, 0, 0);">(</span>BeanOne beanOne, BeanTwo beanTwo, <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">int</span> count<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        this.<span style="color: rgb(0, 0, 0);">beanOne</span> = beanOne; <br />        this.<span style="color: rgb(0, 0, 0);">beanTwo</span> = beanTwo; <br />        this.<span style="color: rgb(0, 0, 0);">count</span> = count; <br />    <span style="color: rgb(0, 0, 0);">}</span><br />    <span style="color: rgb(102, 102, 255);">//对外提供静态的方法</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">static</span> ExampleBean createInstance<span style="color: rgb(0, 0, 0);">(</span>BeanOne beanOne, BeanTwo beanTwo, <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">int</span> count<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        ExampleBean eb = <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">new</span> ExampleBean<span style="color: rgb(0, 0, 0);">(</span>beanOne,beanTwo,count<span style="color: rgb(0, 0, 0);">)</span>; <br />        <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">return</span> eb; <br />    <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span><br /></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />在配置文件中定义： <br /><br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />&lt;bean id="exampleBean" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">ExampleBean</span>" factory-method="createInstance"&gt; <br />    &lt;constructor-arg&gt;&lt;ref bean="bean1"/&gt;&lt;/constructor-arg&gt; <br />    &lt;constructor-arg&gt;&lt;ref bean="bean2"/&gt;&lt;/constructor-arg&gt; <br />    &lt;constructor-arg&gt;&lt;value&gt;<span style="color: rgb(0, 0, 0);" ?="">1</span>&lt;/value&gt;&lt;/constructor-arg&gt; <br />&lt;/bean&gt; <br /><br />&lt;bean id="bean1" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">BeanOne</span>"/&gt; <br />&lt;bean id="bean2" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">BeanTwo</span>"/&gt; <br /></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />3、实例工厂方法模式 <br /><br />调用一个已存在的bean（这个bean应该是工厂类型）的工厂方法来创建新的bean，基于方法参数的依赖注射 <br /><br />该模式没有Bean类； <br /><br />在配置文件中定义： <br /><br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />&lt;bean id="exampleBean" <br />      factory-bean="myFactoryBean" <br />      factory-method="createInstance"/&gt; <br /><br />&lt;bean id="myFactoryBean" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">ExampleBean</span>" factory-method="createInstance"&gt; <br />    &lt;constructor-arg&gt;&lt;ref bean="bean1"/&gt;&lt;/constructor-arg&gt; <br />    &lt;constructor-arg&gt;&lt;ref bean="bean2"/&gt;&lt;/constructor-arg&gt; <br />    &lt;constructor-arg&gt;&lt;value&gt;<span style="color: rgb(0, 0, 0);" ?="">1</span>&lt;/value&gt;&lt;/constructor-arg&gt; <br />&lt;/bean&gt; <br /><br />&lt;bean id="bean1" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">BeanOne</span>"/&gt; <br />&lt;bean id="bean2" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">BeanTwo</span>"/&gt; <br /></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />二)Bean其它参数的配置 <br /><br />一个常用Bean的配置参数和解释 <br /><br />&lt;bean id="" ——标志符,用它引用唯一的Bean <br />class="" ——该Bean对应的类，前面说到实例工厂方法模式创建的Bean没有类 <br />singleton="" ——值为true或false,标识该Bean是否为单实例模式？如果为false则对这个bean <br />的每次请求都会创建一个新的bean实例 <br />init-method="" ——向应用层返回引用前执行的初始化方法 <br />destroy-method="" ——该Bean的销毁方法 <br />depends-on=""&gt; ——在Bean加载前，首先加载的指定资源 <br />.... <br />&lt;/bean&gt; <br /><br />三)property(或constructor-arg元素)的配置 <br /><br />1、用字符串形式指定常见类型的属性或参数的value值，JavaBean的PropertyEditor负责类型转化如： <br /><br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />&lt;property name="driverClassName"&gt; <br />    &lt;value&gt;com.<span style="color: rgb(0, 0, 0);">mysql</span>.<span style="color: rgb(0, 0, 0);">jdbc</span>.<span style="color: rgb(0, 0, 0);">Driver</span>&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;property name="url"&gt; <br />    &lt;value&gt;jdbc:mysql:<span style="color: rgb(102, 102, 255);">//localhost:3306/mydb&lt;/value&gt;</span><br />&lt;/property&gt; <br /></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />2、注意null和""(空串)的区别，如： <br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />
												<br />&lt;property name="email"&gt;&lt;value&gt;&lt;/value&gt;&lt;/property&gt; <br />&lt;property name="email"&gt;&lt;<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">null</span>/&gt;&lt;/property&gt; <br /></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />3、list、set、map、以及 props 元素用来定义和设置Java对应类型List、Set、Map、和 Properties ，如： <br /><br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />
												<br />&lt;property name="school"&gt; <br />   &lt;props&gt; <br />      &lt;prop key="school01"&gt;The xi<span style="color: rgb(0, 0, 255);">'an technology university&lt;/prop&gt; <br />      &lt;prop key="school02"&gt;The BeiJing university&lt;/prop&gt; <br />   &lt;/props&gt; <br />&lt;/property&gt; <br /><br />&lt;property name="someList"&gt; <br />   &lt;list&gt; <br />      &lt;value&gt;a list element followed by a reference&lt;/value&gt; <br />      &lt;ref bean="myDataSource"/&gt; <br />   &lt;/list&gt; <br />&lt;/property&gt; <br /><br />&lt;property name="someMap"&gt; <br />   &lt;map&gt; <br />      &lt;entry key="001"&gt; <br />         &lt;value&gt;just some string&lt;/value&gt; <br />      &lt;/entry&gt; <br />      &lt;entry key="yup a ref"&gt; <br />         &lt;ref bean="myDataSource"/&gt; <br />      &lt;/entry&gt; <br />   &lt;/map&gt; <br />&lt;/property&gt; <br />        <br />&lt;property name="someSet"&gt; <br />      &lt;set&gt; <br />         &lt;value&gt;just some string&lt;/value&gt; <br />         &lt;ref bean="myDataSource"/&gt; <br />      &lt;/set&gt; <br />&lt;/property&gt; <br /></span></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />4、内部Bean和ref元素引用容器管理的其他bean <br /><br />一个内部Bean的例子： <br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />
												<br />&lt;bean id="dep" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="com.<span style="color: rgb(0, 0, 0);">bean</span>.<span style="color: rgb(0, 0, 0);">Conpany</span>"&gt; <br />    &lt;property name="manager"&gt; <br />        &lt;bean <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="com.<span style="color: rgb(0, 0, 0);">bean</span>.<span style="color: rgb(0, 0, 0);">Person</span>"&gt; <br />            &lt;property name="name"&gt;&lt;value&gt;Tony&lt;/value&gt;&lt;/property&gt; <br />            &lt;property name="age"&gt;&lt;value&gt;<span style="color: rgb(0, 0, 0);" ?="">51</span>&lt;/value&gt;&lt;/property&gt; <br />        &lt;/bean&gt; <br />    &lt;/property&gt; <br />&lt;/bean&gt; <br /></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />ref元素引用的例子： <br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />
												<br />&lt;bean id="person_manger" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="com.<span style="color: rgb(0, 0, 0);">bean</span>.<span style="color: rgb(0, 0, 0);">Person</span>"&gt; <br />    &lt;property name="name"&gt;&lt;value&gt;Tony&lt;/value&gt;&lt;/property&gt; <br />    &lt;property name="age"&gt;&lt;value&gt;<span style="color: rgb(0, 0, 0);" ?="">51</span>&lt;/value&gt;&lt;/property&gt; <br />&lt;/bean&gt; <br /><br />&lt;bean id="dep" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="com.<span style="color: rgb(0, 0, 0);">bean</span>.<span style="color: rgb(0, 0, 0);">Conpany</span>"&gt; <br />    &lt;property name="manager"&gt; <br />        &lt;idref bean="person_manager"/&gt; <br />    &lt;/property&gt; <br />&lt;/bean&gt; <br /></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />注：元素引用可以是下面三种权限： <br />1)&lt;idref bean="person_manager"/&gt; <br />引用的Bean可以在同一个BeanFactory/ApplicationContext（无论是否在同一个XML文件中）中，也可以在父BeanFactory/ApplicationContext中 <br />2)&lt;idref local="person_manager"/&gt; <br />引用的bean在同一个XML文件中 <br />3)&lt;idref parent="person_manager"/&gt; <br />引用的bean必须在当前BeanFactory（ApplicationContext）的父BeanFactory（ApplicationContext）中.<br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td width="100%"><a href="http://forum.javaeye.com/viewtopic.php?p=116581#116581"><img title="有新文章" alt="有新文章" src="http://forum.javaeye.com/templates/subSilver/images/icon_minipost_new.gif" border="0" height="9" width="12" /></a><span class="postdetails">时间: 2006-3-23 12:58:26<span class="gen"> </span>   标题: Spring学习笔记(二)Bean</span></td><td nowrap="nowrap" valign="top"><a href="http://forum.javaeye.com/posting.php?mode=quote&amp;p=116581"><img title="引用回复" alt="引用回复" src="http://forum.javaeye.com/templates/subSilver/images/lang_chinese_simplified/icon_quote.gif" border="0" /></a><a href="http://forum.javaeye.com/addblog.php?type=javaeye&amp;title=Spring%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%28%E4%BA%8C%29Bean&amp;t=19366&amp;postdays=0&amp;postorder=asc&amp;start=0&amp;p=116581"><img title="将这个帖子加入我的Blog" alt="将这个帖子加入我的Blog" src="http://forum.javaeye.com/templates/subSilver/images/icon_blog.gif" border="0" /></a></td></tr><tr><td colspan="2"><hr /></td></tr><tr><td colspan="2"><span class="postbody">Spring使用BeanFactory模式来管理Bean,但Spring中提到的Bean不是标准的意义上的JavaBean(仅包含一个默认的构造函数，在属性后面定义相对应的setter和getter方法),而是任何你想让它管理的类，比如连接池、甚至BeanFactory本身。 <br /><br />一)Bean的设计常用下面几种模式 <br /><br />1、标准Bean: <br /><br />使用默认的构造函数和基于setter、getter方法的依赖注射 <br /><br />Bean类代码： <br /><br /></span><table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><span class="genmed"><b>java代码: </b></span></td></tr><tr><td class="code"><div style="font-family: 'Courier New',Courier,monospace;"><br /><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span> ExampleBean <span style="color: rgb(0, 0, 0);">{</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span> BeanOne beanOne; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span> BeanTwo beanTwo; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">int</span> count; <br />    <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">void</span> setBeanOne<span style="color: rgb(0, 0, 0);">(</span>BeanOne beanOne<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        this.<span style="color: rgb(0, 0, 0);">beanOne</span> = beanOne; <br />    <span style="color: rgb(0, 0, 0);">}</span><br />    <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">void</span> setBeanTwo<span style="color: rgb(0, 0, 0);">(</span>BeanTwo beanTwo<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        this.<span style="color: rgb(0, 0, 0);">beanTwo</span> = beanTwo; <br />    <span style="color: rgb(0, 0, 0);">}</span><br />    <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">void</span> setCount<span style="color: rgb(0, 0, 0);">(</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">int</span> count<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        this.<span style="color: rgb(0, 0, 0);">count</span> = count; <br />    <span style="color: rgb(0, 0, 0);">}</span>    <br /><span style="color: rgb(0, 0, 0);">}</span><br /></div><br /></td></tr></tbody></table><span class="postbody"><br />在配置文件中定义： <br /><br /></span><table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><span class="genmed"><b>java代码: </b></span></td></tr><tr><td class="code"><div style="font-family: 'Courier New',Courier,monospace;"><br />&lt;bean id="exampleBean" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">ExampleBean</span>"&gt; <br />    &lt;property name="beanOne"&gt;&lt;ref bean="bean1"/&gt;&lt;/property&gt; <br />    &lt;property name="beanTwo"&gt;&lt;ref bean="bean2"/&gt;&lt;/property&gt; <br />    &lt;property name="count"&gt;&lt;value&gt;<span style="color: rgb(0, 0, 0);" ?="">1</span>&lt;/value&gt;&lt;/property&gt; <br />&lt;/bean&gt; <br /><br />&lt;bean id="bean1" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">BeanOne</span>"/&gt; <br />&lt;bean id="bean2" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">BeanTwo</span>"/&gt; <br /></div><br /></td></tr></tbody></table><span class="postbody"><br />2、构造函数模式 <br /><br />自定义的构造函数，基于构造函数参数的依赖注射 <br /><br />Bean类代码： <br /><br /></span><table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><span class="genmed"><b>java代码: </b></span></td></tr><tr><td class="code"><div style="font-family: 'Courier New',Courier,monospace;"><br /><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span> ExampleBean <span style="color: rgb(0, 0, 0);">{</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span> BeanOne beanOne; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span> BeanTwo beanTwo; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">int</span> count; <br />    <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">public</span> ExampleBean<span style="color: rgb(0, 0, 0);">(</span>BeanOne beanOne, BeanTwo beanTwo, <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">int</span> count<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        this.<span style="color: rgb(0, 0, 0);">beanOne</span> = beanOne; <br />        this.<span style="color: rgb(0, 0, 0);">beanTwo</span> = beanTwo; <br />        this.<span style="color: rgb(0, 0, 0);">count</span> = count; <br />    <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span><br /></div><br /></td></tr></tbody></table><span class="postbody"><br />在配置文件中定义： <br /></span><table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><span class="genmed"><b>java代码: </b></span></td></tr><tr><td class="code"><div style="font-family: 'Courier New',Courier,monospace;"><br /><br />&lt;bean id="exampleBean" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">ExampleBean</span>"&gt; <br />    &lt;constructor-arg&gt;&lt;ref bean="bean1"/&gt;&lt;/constructor-arg&gt; <br />    &lt;constructor-arg&gt;&lt;ref bean="bean2"/&gt;&lt;/constructor-arg&gt; <br />    &lt;constructor-arg&gt;&lt;value&gt;<span style="color: rgb(0, 0, 0);" ?="">1</span>&lt;/value&gt;&lt;/constructor-arg&gt; <br />&lt;/bean&gt; <br /><br />&lt;bean id="bean1" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">BeanOne</span>"/&gt; <br />&lt;bean id="bean2" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">BeanTwo</span>"/&gt; <br /></div><br /></td></tr></tbody></table><span class="postbody"><br />3、静态工厂方法模式 <br /><br />静态工厂方法必须是static的，基于方法参数的依赖注射。 <br /><br />Bean类代码： <br /><br /></span><table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><span class="genmed"><b>java代码: </b></span></td></tr><tr><td class="code"><div style="font-family: 'Courier New',Courier,monospace;"><br /><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span> ExampleBean <span style="color: rgb(0, 0, 0);">{</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span> BeanOne beanOne; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span> BeanTwo beanTwo; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">int</span> count; <br />    <span style="color: rgb(102, 102, 255);">//构造函数私有</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">private</span> ExampleBean<span style="color: rgb(0, 0, 0);">(</span>BeanOne beanOne, BeanTwo beanTwo, <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">int</span> count<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        this.<span style="color: rgb(0, 0, 0);">beanOne</span> = beanOne; <br />        this.<span style="color: rgb(0, 0, 0);">beanTwo</span> = beanTwo; <br />        this.<span style="color: rgb(0, 0, 0);">count</span> = count; <br />    <span style="color: rgb(0, 0, 0);">}</span><br />    <span style="color: rgb(102, 102, 255);">//对外提供静态的方法</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">static</span> ExampleBean createInstance<span style="color: rgb(0, 0, 0);">(</span>BeanOne beanOne, BeanTwo beanTwo, <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">int</span> count<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        ExampleBean eb = <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">new</span> ExampleBean<span style="color: rgb(0, 0, 0);">(</span>beanOne,beanTwo,count<span style="color: rgb(0, 0, 0);">)</span>; <br />        <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">return</span> eb; <br />    <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span><br /></div><br /></td></tr></tbody></table><span class="postbody"><br />在配置文件中定义： <br /><br /></span><table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><span class="genmed"><b>java代码: </b></span></td></tr><tr><td class="code"><div style="font-family: 'Courier New',Courier,monospace;"><br />&lt;bean id="exampleBean" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">ExampleBean</span>" factory-method="createInstance"&gt; <br />    &lt;constructor-arg&gt;&lt;ref bean="bean1"/&gt;&lt;/constructor-arg&gt; <br />    &lt;constructor-arg&gt;&lt;ref bean="bean2"/&gt;&lt;/constructor-arg&gt; <br />    &lt;constructor-arg&gt;&lt;value&gt;<span style="color: rgb(0, 0, 0);" ?="">1</span>&lt;/value&gt;&lt;/constructor-arg&gt; <br />&lt;/bean&gt; <br /><br />&lt;bean id="bean1" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">BeanOne</span>"/&gt; <br />&lt;bean id="bean2" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">BeanTwo</span>"/&gt; <br /></div><br /></td></tr></tbody></table><span class="postbody"><br /><br />3、实例工厂方法模式 <br /><br />调用一个已存在的bean（这个bean应该是工厂类型）的工厂方法来创建新的bean，基于方法参数的依赖注射 <br /><br />该模式没有Bean类； <br /><br />在配置文件中定义： <br /><br /></span><table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><span class="genmed"><b>java代码: </b></span></td></tr><tr><td class="code"><div style="font-family: 'Courier New',Courier,monospace;"><br />&lt;bean id="exampleBean" <br />      factory-bean="myFactoryBean" <br />      factory-method="createInstance"/&gt; <br /><br />&lt;bean id="myFactoryBean" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">ExampleBean</span>" factory-method="createInstance"&gt; <br />    &lt;constructor-arg&gt;&lt;ref bean="bean1"/&gt;&lt;/constructor-arg&gt; <br />    &lt;constructor-arg&gt;&lt;ref bean="bean2"/&gt;&lt;/constructor-arg&gt; <br />    &lt;constructor-arg&gt;&lt;value&gt;<span style="color: rgb(0, 0, 0);" ?="">1</span>&lt;/value&gt;&lt;/constructor-arg&gt; <br />&lt;/bean&gt; <br /><br />&lt;bean id="bean1" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">BeanOne</span>"/&gt; <br />&lt;bean id="bean2" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="examples.<span style="color: rgb(0, 0, 0);">BeanTwo</span>"/&gt; <br /></div><br /></td></tr></tbody></table><span class="postbody"><br />二)Bean其它参数的配置 <br /><br />一个常用Bean的配置参数和解释 <br /><br />&lt;bean id="" ——标志符,用它引用唯一的Bean <br />class="" ——该Bean对应的类，前面说到实例工厂方法模式创建的Bean没有类 <br />singleton="" ——值为true或false,标识该Bean是否为单实例模式？如果为false则对这个bean <br />的每次请求都会创建一个新的bean实例 <br />init-method="" ——向应用层返回引用前执行的初始化方法 <br />destroy-method="" ——该Bean的销毁方法 <br />depends-on=""&gt; ——在Bean加载前，首先加载的指定资源 <br />.... <br />&lt;/bean&gt; <br /><br />三)property(或constructor-arg元素)的配置 <br /><br />1、用字符串形式指定常见类型的属性或参数的value值，JavaBean的PropertyEditor负责类型转化如： <br /><br /></span><table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><span class="genmed"><b>java代码: </b></span></td></tr><tr><td class="code"><div style="font-family: 'Courier New',Courier,monospace;"><br />&lt;property name="driverClassName"&gt; <br />    &lt;value&gt;com.<span style="color: rgb(0, 0, 0);">mysql</span>.<span style="color: rgb(0, 0, 0);">jdbc</span>.<span style="color: rgb(0, 0, 0);">Driver</span>&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;property name="url"&gt; <br />    &lt;value&gt;jdbc:mysql:<span style="color: rgb(102, 102, 255);">//localhost:3306/mydb&lt;/value&gt;</span><br />&lt;/property&gt; <br /></div><br /></td></tr></tbody></table><span class="postbody"><br />2、注意null和""(空串)的区别，如： <br /></span><table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><span class="genmed"><b>java代码: </b></span></td></tr><tr><td class="code"><div style="font-family: 'Courier New',Courier,monospace;"><br /><br />&lt;property name="email"&gt;&lt;value&gt;&lt;/value&gt;&lt;/property&gt; <br />&lt;property name="email"&gt;&lt;<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">null</span>/&gt;&lt;/property&gt; <br /></div><br /></td></tr></tbody></table><span class="postbody"><br /><br />3、list、set、map、以及 props 元素用来定义和设置Java对应类型List、Set、Map、和 Properties ，如： <br /><br /></span><table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><span class="genmed"><b>java代码: </b></span></td></tr><tr><td class="code"><div style="font-family: 'Courier New',Courier,monospace;"><br /><br />&lt;property name="school"&gt; <br />   &lt;props&gt; <br />      &lt;prop key="school01"&gt;The xi<span style="color: rgb(0, 0, 255);">'an technology university&lt;/prop&gt; <br />      &lt;prop key="school02"&gt;The BeiJing university&lt;/prop&gt; <br />   &lt;/props&gt; <br />&lt;/property&gt; <br /><br />&lt;property name="someList"&gt; <br />   &lt;list&gt; <br />      &lt;value&gt;a list element followed by a reference&lt;/value&gt; <br />      &lt;ref bean="myDataSource"/&gt; <br />   &lt;/list&gt; <br />&lt;/property&gt; <br /><br />&lt;property name="someMap"&gt; <br />   &lt;map&gt; <br />      &lt;entry key="001"&gt; <br />         &lt;value&gt;just some string&lt;/value&gt; <br />      &lt;/entry&gt; <br />      &lt;entry key="yup a ref"&gt; <br />         &lt;ref bean="myDataSource"/&gt; <br />      &lt;/entry&gt; <br />   &lt;/map&gt; <br />&lt;/property&gt; <br />        <br />&lt;property name="someSet"&gt; <br />      &lt;set&gt; <br />         &lt;value&gt;just some string&lt;/value&gt; <br />         &lt;ref bean="myDataSource"/&gt; <br />      &lt;/set&gt; <br />&lt;/property&gt; <br /></span></div><br /></td></tr></tbody></table></td></tr></tbody></table></span>
		<span class="postbody">
				<br />4、内部Bean和ref元素引用容器管理的其他bean <br /><br />一个内部Bean的例子： <br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />
												<br />&lt;bean id="dep" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="com.<span style="color: rgb(0, 0, 0);">bean</span>.<span style="color: rgb(0, 0, 0);">Conpany</span>"&gt; <br />    &lt;property name="manager"&gt; <br />        &lt;bean <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="com.<span style="color: rgb(0, 0, 0);">bean</span>.<span style="color: rgb(0, 0, 0);">Person</span>"&gt; <br />            &lt;property name="name"&gt;&lt;value&gt;Tony&lt;/value&gt;&lt;/property&gt; <br />            &lt;property name="age"&gt;&lt;value&gt;<span style="color: rgb(0, 0, 0);" ?="">51</span>&lt;/value&gt;&lt;/property&gt; <br />        &lt;/bean&gt; <br />    &lt;/property&gt; <br />&lt;/bean&gt; <br /></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />ref元素引用的例子： <br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />
												<br />&lt;bean id="person_manger" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="com.<span style="color: rgb(0, 0, 0);">bean</span>.<span style="color: rgb(0, 0, 0);">Person</span>"&gt; <br />    &lt;property name="name"&gt;&lt;value&gt;Tony&lt;/value&gt;&lt;/property&gt; <br />    &lt;property name="age"&gt;&lt;value&gt;<span style="color: rgb(0, 0, 0);" ?="">51</span>&lt;/value&gt;&lt;/property&gt; <br />&lt;/bean&gt; <br /><br />&lt;bean id="dep" <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>="com.<span style="color: rgb(0, 0, 0);">bean</span>.<span style="color: rgb(0, 0, 0);">Conpany</span>"&gt; <br />    &lt;property name="manager"&gt; <br />        &lt;idref bean="person_manager"/&gt; <br />    &lt;/property&gt; <br />&lt;/bean&gt; <br /></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />注：元素引用可以是下面三种权限： <br />1)&lt;idref bean="person_manager"/&gt; <br />引用的Bean可以在同一个BeanFactory/ApplicationContext（无论是否在同一个XML文件中）中，也可以在父BeanFactory/ApplicationContext中 <br />2)&lt;idref local="person_manager"/&gt; <br />引用的bean在同一个XML文件中 <br />3)&lt;idref parent="person_manager"/&gt; <br />引用的bean必须在当前BeanFactory（ApplicationContext）的父BeanFactory（ApplicationContext）中 <br /><br />引用注明出处：<a class="postlink" href="http://spaces.msn.com/pococoon/blog/cns%21D25B6032F7AD1992%21193.entry" target="_blank"><font color="#002c99">http://spaces.msn.com/pococoon/blog/cns!D25B6032F7AD1992!193.entry</font></a></span>
		<br />
		<br />
<img src ="http://www.blogjava.net/ltc603/aggbug/37035.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ltc603/" target="_blank">阿成</a> 2006-03-23 13:42 <a href="http://www.blogjava.net/ltc603/archive/2006/03/23/37035.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring AOP中文教程</title><link>http://www.blogjava.net/ltc603/archive/2006/03/09/34552.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Thu, 09 Mar 2006 13:32:00 GMT</pubDate><guid>http://www.blogjava.net/ltc603/archive/2006/03/09/34552.html</guid><wfw:comment>http://www.blogjava.net/ltc603/comments/34552.html</wfw:comment><comments>http://www.blogjava.net/ltc603/archive/2006/03/09/34552.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ltc603/comments/commentRss/34552.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ltc603/services/trackbacks/34552.html</trackback:ping><description><![CDATA[
		<span class="postbody">
				<font size="2">这是在网上发现的一篇关于Spring AOP编程的教程，读完这篇文章后，Spring AOP不再难以理解，因此我把它译成中文，推荐给Spring AOP的初学者。这是译文的</font>
				<a class="postlink" href="http://tools.devchannel.org/devtoolschannel/04/04/15/1457223.shtml" target="_blank">
						<font color="#006699" size="2">链接</font>
				</a>
				<font size="2">。 <br /><br />AOP正在成为软件开发的下一个圣杯。使用AOP，你可以将处理aspect的代码注入主程序，通常主程序的主要目的并不在于处理这些aspect。AOP可以防止代码混乱。 <br />为了理解AOP如何做到这点，考虑一下记日志的工作。日志本身不太可能是你开发的主程序的主要任务。如果能将“不可见的”、通用的日志代码注入主程序中，那该多好啊。AOP可以帮助你做到。 <br />Spring framework是很有前途的AOP技术。作为一种非侵略性的，轻型的AOP framework，你无需使用预编译器或其他的元标签，便可以在Java程序中使用它。这意味着开发团队里只需一人要对付AOP framework，其他人还是象往常一样编程。 <br />AOP是很多直觉难以理解的术语的根源。幸运的是，你只要理解三个概念，就可以编写AOP模块。这三个概念是：advice，pointcut和advisor。advice是你想向别的程序内部不同的地方注入的代码。pointcut定义了需要注入advice的位置，通常是某个特定的类的一个public方法。advisor是pointcut和advice的装配器，是将advice注入主程序中预定义位置的代码。 <br /><br />既然我们知道了需要使用advisor向主要代码中注入“不可见的”advice，让我们实现一个Spring AOP的例子。在这个例子中，我们将实现一个before advice，这意味着advice的代码在被调用的public方法开始前被执行。以下是这个before advice的实现代码： <br /><br /></font>
		</span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">package com.company.springaop.test; <br /><br />import java.lang.reflect.Method; <br />import org.springframework.aop.MethodBeforeAdvice; <br /><br />public class TestBeforeAdvice implements MethodBeforeAdvice { <br /><br />  public void before(Method m, Object[] args, Object target) <br />  throws Throwable { <br />    System.out.println("Hello world! (by " <br />        + this.getClass().getName() <br />        + ")"); <br />  } <br />} <br /> </td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">接口MethodBeforeAdvice只有一个方法before需要实现，它定义了advice的实现。before方法共用三个参数，它们提供了相当丰富的信息。参数Method m是advice开始后执行的方法。方法名称可以用作判断是否执行代码的条件。Object[] args是传给被调用的public方法的参数数组。当需要记日志时，参数args和被执行方法的名称，都是非常有用的信息。你也可以改变传给m的参数，但要小心使用这个功能；编写最初主程序的程序员并不知道主程序可能会和传入参数的发生冲突。Object target是执行方法m对象的引用。 <br /><br />在下面的BeanImpl类中，每个public方法调用前，都会执行advice： <br /><br /></font>
		</span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">package com.company.springaop.test; <br /><br />public class BeanImpl implements Bean { <br /><br />  public void theMethod() { <br />    System.out.println(this.getClass().getName() <br />        + "." + new Exception().getStackTrace()[0].getMethodName() <br />        + "()" <br />        + " says HELLO!"); <br />  } <br />}</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">类BeanImpl实现了下面的接口Bean： <br /><br /></font>
		</span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">package com.company.springaop.test; <br /><br />public interface Bean { <br />  public void theMethod(); <br />}</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<br />
				<font size="2">虽然不是必须使用接口，但面向接口而不是面向实现编程是良好的编程实践，Spring也鼓励这样做。 <br /><br />pointcut和advice通过配置文件来实现，因此，接下来你只需编写主方法的Java代码： <br /></font>
		</span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<br />
										<br />package com.company.springaop.test; <br /><br />import org.springframework.context.ApplicationContext; <br />import org.springframework.context.support.FileSystemXmlApplicationContext; <br /><br />public class Main { <br /><br />  public static void main(String[] args) { <br />    //Read the configuration file <br />    ApplicationContext ctx <br />        = new FileSystemXmlApplicationContext("springconfig.xml"); <br /><br />    //Instantiate an object <br />    Bean x = (Bean) ctx.getBean("bean"); <br /><br />    //Execute the public method of the bean (the test) <br />    x.theMethod(); <br />  } <br />}</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<br />
				<font size="2">我们从读入和处理配置文件开始，接下来马上要创建它。这个配置文件将作为粘合程序不同部分的“胶水”。读入和处理配置文件后，我们会得到一个创建工厂ctx。任何一个Spring管理的对象都必须通过这个工厂来创建。对象通过工厂创建后便可正常使用。 <br /><br />仅仅用配置文件便可把程序的每一部分组装起来。 <br /></font>
		</span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>
														<font size="2">代码:</font>
												</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<br />&lt;?xml version="1.0" encoding="UTF-8"?&gt; <br />&lt;!DOCTYPE beans PUBLIC  "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"&gt; <br /><br />&lt;beans&gt; <br />  &lt;!--CONFIG--&gt; <br />  &lt;bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean"&gt; <br />    &lt;property name="proxyInterfaces"&gt; <br />      &lt;value&gt;com.company.springaop.test.Bean&lt;/value&gt; <br />    &lt;/property&gt; <br />    &lt;property name="target"&gt; <br />      &lt;ref local="beanTarget"/&gt; <br />    &lt;/property&gt; <br />    &lt;property name="interceptorNames"&gt; <br />      &lt;list&gt; <br />        &lt;value&gt;theAdvisor&lt;/value&gt; <br />      &lt;/list&gt; <br />    &lt;/property&gt; <br />  &lt;/bean&gt; <br /><br />  &lt;!--CLASS--&gt; <br />  &lt;bean id="beanTarget" class="com.company.springaop.test.BeanImpl"/&gt; <br /><br />  &lt;!--ADVISOR--&gt; <br />  &lt;!--Note: An advisor assembles pointcut and advice--&gt; <br />  &lt;bean id="theAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"&gt; <br />    &lt;property name="advice"&gt; <br />      &lt;ref local="theBeforeAdvice"/&gt; <br />    &lt;/property&gt; <br />    &lt;property name="pattern"&gt; <br />      &lt;value&gt;com\.company\.springaop\.test\.Bean\.theMethod&lt;/value&gt; <br />    &lt;/property&gt; <br />  &lt;/bean&gt; <br /><br />  &lt;!--ADVICE--&gt; <br />  &lt;bean id="theBeforeAdvice" class="com.company.springaop.test.TestBeforeAdvice"/&gt; <br />&lt;/beans&gt; <br /> </td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">四个bean定义的次序并不重要。我们现在有了一个advice，一个包含了正则表达式pointcut的advisor，一个主程序类和一个配置好的接口，通过工厂ctx，这个接口返回自己本身实现的一个引用。 <br /><br />BeanImpl和TestBeforeAdvice都是直接配置。我们用一个唯一的ID创建一个bean元素，并指定了一个实现类。这就是全部的工作。 <br /><br />advisor通过Spring framework提供的一个RegexMethodPointcutAdvisor类来实现。我们用advisor的一个属性来指定它所需的advice-bean。第二个属性则用正则表达式定义了pointcut，确保良好的性能和易读性。 <br /><br />最后配置的是bean，它可以通过一个工厂来创建。bean的定义看起来比实际上要复杂。bean是ProxyFactoryBean的一个实现，它是Spring framework的一部分。这个bean的行为通过一下的三个属性来定义： <br /><br /></font>
				<ul>
						<br />
						<li>属性proxyInterface定义了接口类。 <br /></li>
						<li>属性target指向本地配置的一个bean，这个bean返回一个接口的实现。 <br /></li>
						<li>属性interceptorNames是唯一允许定义一个值列表的属性。这个列表包含所有需要在beanTarget上执行的advisor。注意，advisor列表的次序是非常重要的。 <br /></li>
				</ul>
				<br />
				<br />
				<span style="font-weight: bold;">Spring工具</span>
				<br />
				<br />虽然你可以手工修改Ant构建脚本，但使用SpringUI（译注：SpringUI现在是Spring framework的一部分，并改名为spring-ide），使用Spring AOP变得很简单，只要点点鼠标即可。你可以把SpringUI安装成Eclipse的一个plug-in。然后，你只需在你的project上右击鼠标，并选择“add Spring Project Nature”。在project属性中，你可以在“Spring Project”下添加Spring配置文件。在编译前把下面的类库加入project：aopalliance.jar，commons-logging.jar，jakarta-oro-2.0.7.jar和spring.jar。运行程序时你会看到下面的信息： <br /><br />... (logging information) <br />Hello world! (by com.company.springaop.test.TestBeforeAdvice) <br />com.company.springaop.test.BeanImpl.theMethod() says HELLO! <br /><br /><br /><span style="font-weight: bold;">优点和缺点</span><br /><br />Spring比起其他的framework更有优势，因为除了AOP以外，它提供了更多别的功能。作为一个轻型framework，它在J2EE不同的部分都可以发挥作用。因此，即使不想使用Spring AOP，你可能还是想使用Spring。另一个优点是，Spring并不要求开发团队所有的人员都会用它。学习Spring应该从Spring reference的第一页开始。读了本文后，你应该可以更好地理解Spring reference了。Spring唯一的缺点是缺乏更多的文档，但它的mailing list是个很好的补充，而且会不断地出现更多的文档。</span>
		<span class="gensmall">
				<br />
		</span>
<img src ="http://www.blogjava.net/ltc603/aggbug/34552.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ltc603/" target="_blank">阿成</a> 2006-03-09 21:32 <a href="http://www.blogjava.net/ltc603/archive/2006/03/09/34552.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于OpenSessionInViewFilter </title><link>http://www.blogjava.net/ltc603/archive/2006/03/09/34405.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Thu, 09 Mar 2006 00:52:00 GMT</pubDate><guid>http://www.blogjava.net/ltc603/archive/2006/03/09/34405.html</guid><wfw:comment>http://www.blogjava.net/ltc603/comments/34405.html</wfw:comment><comments>http://www.blogjava.net/ltc603/archive/2006/03/09/34405.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ltc603/comments/commentRss/34405.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ltc603/services/trackbacks/34405.html</trackback:ping><description><![CDATA[
		<div class="diaryBody">
				<p>转自：Potain 的BLOG</p>
				<div class="snip-title">
						<h1 class="snip-name">OpenSessionInView </h1>
						<div class="snip-info">Created by <a href="http://www.aspectoriented.org:9080//space/potian">potian</a>. Last edited by <a href="http://www.aspectoriented.org:9080//space/admin">admin</a> 61 days ago. Viewed 181 times. </div>
						<div class="snip-buttons">
								<span class="inactive">[edit]</span>
								<span class="inactive">[attach]</span>
						</div>
				</div>
				<div class="snip-content" id="snip-content">
						<div class="snip-attachments">
						</div>Hibernate的Lazy初始化1:n关系时，你必须保证是在同一个Session内部使用这个关系集合，不然Hiernate将抛出例外。 
<p class="paragraph">另外，你不愿意你的DAO测试代码每次都打开关系Session，因此，我们一般会采用OpenSessionInView模式。 </p><h3 class="heading-1"><a name="0"></a><b style="color: black; background-color: rgb(255, 255, 102);">OpenSessionInViewFilter</b>解决Web应用程序的问题 </h3>如果程序是在正常的Web程序中运行，那么Spring的<b style="color: black; background-color: rgb(255, 255, 102);">OpenSessionInViewFilter</b>能够解决问题，它： 
<p class="paragraph"></p><div class="code"><pre><span class="java-keyword">protected</span> void doFilterInternal(HttpServletRequest request, 
             HttpServletResponse response,
           FilterChain filterChain) <span class="java-keyword">throws</span> ServletException, IOException {
      SessionFactory sessionFactory = lookupSessionFactory();
      logger.debug(<span class="java-quote">"Opening Hibernate Session in <b style="color: black; background-color: rgb(255, 255, 102);">OpenSessionInViewFilter</b>"</span>);
      Session session = getSession(sessionFactory);
      TransactionSynchronizationManager.bindResource(sessionFactory, 
             <span class="java-keyword">new</span> SessionHolder(session));
      <span class="java-keyword">try</span> {
            filterChain.doFilter(request, response);
      }
      <span class="java-keyword">finally</span> {
            TransactionSynchronizationManager.unbindResource(sessionFactory);
            logger.debug(<span class="java-quote">"Closing Hibernate Session in <b style="color: black; background-color: rgb(255, 255, 102);">OpenSessionInViewFilter</b>"</span>);
            closeSession(session, sessionFactory);
      }
}</pre></div>可以看到，这个Filter在request开始之前，把sessionFactory绑定到TransactionSynchronizationManager，和这个SessionHolder相关。这个意味着所有request执行过程中将使用这个session。而在请求结束后，将和这个sessionFactory对应的session解绑，并且关闭Session。 
<p class="paragraph">为什么绑定以后，就可以防止每次不会新开一个Session呢？看看HibernateDaoSupport的情况： </p><div class="code"><pre><span class="java-keyword">public</span><span class="java-keyword">final</span> void setSessionFactory(SessionFactory sessionFactory) {
    <span class="java-keyword">this</span>.hibernateTemplate = <span class="java-keyword">new</span> HibernateTemplate(sessionFactory);
  }
 <span class="java-keyword">protected</span><span class="java-keyword">final</span> HibernateTemplate getHibernateTemplate() {
  <span class="java-keyword">return</span> hibernateTemplate;
 }</pre></div><p class="paragraph">我们的DAO将使用这个template进行操作： </p><div class="code"><pre><span class="java-keyword">public</span><span class="java-keyword">abstract</span> class BaseHibernateObjectDao
      <span class="java-keyword">extends</span> HibernateDaoSupport
      <span class="java-keyword">implements</span> BaseObjectDao {
            <p class="paragraph">
      <span class="java-keyword">protected</span> BaseEntityObject getByClassId(<span class="java-keyword">final</span><span class="java-object">long</span> id) {
            BaseEntityObject obj =
                  (BaseEntityObject) getHibernateTemplate()
                        .execute(<span class="java-keyword">new</span> HibernateCallback() {
            </p><p class="paragraph">                  <span class="java-keyword">public</span><span class="java-object">Object</span> doInHibernate(Session session)
                        <span class="java-keyword">throws</span> HibernateException {
                        <span class="java-keyword">return</span> session.get(getPersistentClass(), 
                                       <span class="java-keyword">new</span><span class="java-object">Long</span>(id));
                  }
            </p><p class="paragraph">            });
            <span class="java-keyword">return</span> obj;
      }
            </p><p class="paragraph"></p><p class="paragraph">      <span class="java-keyword">public</span> void save(BaseEntityObject entity) {
            getHibernateTemplate().saveOrUpdate(entity);
      }
            </p><p class="paragraph">      <span class="java-keyword">public</span> void remove(BaseEntityObject entity) {
            <span class="java-keyword">try</span> {
            </p><p class="paragraph">                  getHibernateTemplate().delete(entity);
            } <span class="java-keyword">catch</span> (Exception e) {
                  <span class="java-keyword">throw</span><span class="java-keyword">new</span> FlexEnterpriseDataAccessException(e);
            }
      }
            </p><p class="paragraph">      <span class="java-keyword">public</span> void refresh(<span class="java-keyword">final</span> BaseEntityObject entity) {
            getHibernateTemplate().execute(<span class="java-keyword">new</span> HibernateCallback() {
            </p><p class="paragraph">                  <span class="java-keyword">public</span><span class="java-object">Object</span> doInHibernate(Session session)
                        <span class="java-keyword">throws</span> HibernateException {
                        session.refresh(entity);
                        <span class="java-keyword">return</span><span class="java-keyword">null</span>;
                  }
            </p><p class="paragraph">            });
      }</p><p class="paragraph">      <span class="java-keyword">public</span> void replicate(<span class="java-keyword">final</span><span class="java-object">Object</span> entity) {
            getHibernateTemplate().execute(<span class="java-keyword">new</span> HibernateCallback() {
            </p><p class="paragraph">                  <span class="java-keyword">public</span><span class="java-object">Object</span> doInHibernate(Session session)
                        <span class="java-keyword">throws</span> HibernateException {
                        session.replicate(entity, 
                                ReplicationMode.OVERWRITE);
                        <span class="java-keyword">return</span><span class="java-keyword">null</span>;
                  }
            </p><p class="paragraph">            });
      }</p></pre></div>而HibernateTemplate试图每次在execute之前去获得Session，执行完就力争关闭Session 
<div class="code"><pre><span class="java-keyword">public</span><span class="java-object">Object</span> execute(HibernateCallback action) <span class="java-keyword">throws</span> DataAccessException {
      Session session = (!<span class="java-keyword">this</span>.allowCreate ?
            SessionFactoryUtils.getSession(getSessionFactory(), 
                  <span class="java-keyword">false</span>) :
            SessionFactoryUtils.getSession(getSessionFactory(),
                  getEntityInterceptor(),
                  getJdbcExceptionTranslator()));
      <span class="java-object">boolean</span> existingTransaction =  
          TransactionSynchronizationManager.hasResource(getSessionFactory());
      <span class="java-keyword">if</span> (!existingTransaction &amp;&amp; getFlushMode() == FLUSH_NEVER) {
            session.setFlushMode(FlushMode.NEVER);
      }
      <span class="java-keyword">try</span> {
            <span class="java-object">Object</span> result = action.doInHibernate(session);
            flushIfNecessary(session, existingTransaction);
            <span class="java-keyword">return</span> result;
      }
      <span class="java-keyword">catch</span> (HibernateException ex) {
            <span class="java-keyword">throw</span> convertHibernateAccessException(ex);
      }
      <span class="java-keyword">catch</span> (SQLException ex) {
            <span class="java-keyword">throw</span> convertJdbcAccessException(ex);
      }
      <span class="java-keyword">catch</span> (RuntimeException ex) {
            // callback code threw application exception
            <span class="java-keyword">throw</span> ex;
      }
      <span class="java-keyword">finally</span> {
            SessionFactoryUtils.closeSessionIfNecessary(
                    session, getSessionFactory());
      }
}</pre></div>而这个SessionFactoryUtils能否得到当前的session以及closeSessionIfNecessary是否真正关闭session，端取决于这个session是否用sessionHolder和这个sessionFactory在我们最开始提到的TransactionSynchronizationManager绑定。 
<div class="code"><pre><span class="java-keyword">public</span><span class="java-keyword">static</span> void closeSessionIfNecessary(Session session, 
    SessionFactory sessionFactory)   
    <span class="java-keyword">throws</span> CleanupFailureDataAccessException {
      <span class="java-keyword">if</span> (session == <span class="java-keyword">null</span> || 
         TransactionSynchronizationManager.hasResource(sessionFactory)) {
            <span class="java-keyword">return</span>;
      }
      logger.debug(<span class="java-quote">"Closing Hibernate session"</span>);
      <span class="java-keyword">try</span> {
            session.close();
      }
      <span class="java-keyword">catch</span> (JDBCException ex) {
            // SQLException underneath
            <span class="java-keyword">throw</span><span class="java-keyword">new</span> CleanupFailureDataAccessException(
            <span class="java-quote">"Cannot close Hibernate session"</span>, ex.getSQLException());
      }
      <span class="java-keyword">catch</span> (HibernateException ex) {
            <span class="java-keyword">throw</span><span class="java-keyword">new</span> CleanupFailureDataAccessException(
            <span class="java-quote">"Cannot close Hibernate session"</span>, ex);
      }
}</pre></div><h3 class="heading-1">HibernateInterceptor和OpenSessionInViewInterceptor的问题 </h3><p class="paragraph">使用同样的方法，这两个Interceptor可以用来解决问题。但是关键的不同之处在于，它们的力度只能定义在DAO或业务方法上，而不是在我们的Test方法上，除非我们把它们应用到TestCase的方法上，但你不大可能为TestCase去定义一个接口，然后把Interceptor应用到这个接口的某些方法上。直接使用HibernateTransactionManager也是一样的。因此，如果我们有这样的测试： </p><div class="code"><pre>Category parentCategory  = <span class="java-keyword">new</span> Category ();
      parentCategory.setName(<span class="java-quote">"parent"</span>);
      dao.save(parentCategory);
            <p class="paragraph">      Category childCategory  = <span class="java-keyword">new</span> Category();
        childCategory.setName(<span class="java-quote">"child"</span>);
            </p><p class="paragraph">      parentCategory.addChild(childCategory);
      dao.save(childCategory);</p><p class="paragraph">      Category savedParent = dao.getCategory(<span class="java-quote">"parent"</span>);
      Category savedChild = (Category ) savedParent.getChildren().get(0);
      assertEquals(savedChild, childCategory);
            </p></pre></div>将意味着两件事情： 
<ul class="minus"><li>每次DAO执行都会启动一个session和关闭一个session 
</li><li>如果我们定义了一个lazy的关系，那么最后的Category savedChild = (Category ) savedParent.getChildren().get(0);将会让hibernate报错。 </li></ul><h3 class="heading-1">解决方案 </h3><p class="paragraph">一种方法是对TestCase应用Interceptor或者TransactionManager，但这个恐怕会造成很多麻烦。除非是使用增强方式的AOP.我前期采用这种方法(Aspectwerkz)，在Eclipse里面也跑得含好。 </p><p class="paragraph">另一种方法是在TestCase的setup和teardown里面实现和Filter完全一样的处理，其他的TestCase都从这个TestCase继承，这种方法是我目前所使用的。 <br /><br /><br />转自：Karl Baum's Weblog <br /><br />Karl Baum's Weblog <br /><br />All | General | Java <br /><br /><br />Thursday July 08, 2004 <br />Lazy Initialization and the DAO pattern with Hibernate and Spring <br /><br />Hibernate and Lazy Initialization <br /><br />Hibernate object relational mapping offers both lazy and non-lazy modes of object initialization. Non-lazy initialization retrieves an object and all of its related objects at load time. This can result in hundreds if not thousands of select statements when retrieving one entity. The problem is compounded when bi-directional relationships are used, often causing entire databases to be loaded during the initial request. Of course one could tediously examine each object relationship and manually remove those most costly, but in the end, we may be losing the ease of use benefit sought in using the ORM tool. <br /><br />The obvious solution is to employ the lazy loading mechanism provided by hibernate. This initialization strategy only loads an object's one-to-many and many-to-many relationships when these fields are accessed. The scenario is practically transparent to the developer and a minimum amount of database requests are made, resulting in major performance gains. One drawback to this technique is that lazy loading requires the Hibernate session to remain open while the data object is in use. This causes a major problem when trying to abstract the persistence layer via the Data Access Object pattern. In order to fully abstract the persistence mechanism, all database logic, including opening and closing sessions, must not be performed in the application layer. Most often, this logic is concealed behind the DAO implementation classes which implement interface stubs. The quick and dirty solution is to forget the DAO pattern and include database connection logic in the application layer. This works for small applications but in large systems this can prove to be a major design flaw, hindering application extensibility. <br /><br />Being Lazy in the Web Layer <br /><br />Fortunately for us, the Spring Framework has developed an out of box web solution for using the DAO pattern in combination with Hibernate lazy loading. For anyone not familiar with using the Spring Framework in combination with Hibernate, I will not go into the details here, but I encourage you to read Hibernate Data Access with the Spring Framework. In the case of a web application, Spring comes with both the OpenSessionInViewFilter and the OpenSessionInViewInterceptor. One can use either one interchangeably as both serve the same function. The only difference between the two is the interceptor runs within the Spring container and is configured within the web application context while the Filter runs in front of Spring and is configured within the web.xml. Regardless of which one is used, they both open the hibernate session during the request binding this session to the current thread. Once bound to the thread, the open hibernate session can transparently be used within the DAO implementation classes. The session will remain open for the view allowing lazy access the database value objects. Once the view logic is complete, the hibernate session is closed either in the Filter doFilter method or the Interceptor postHandle method. Below is an example of the configuration of each component: <br /><br />Interceptor Configuration <br /><br />&lt;beans&gt; <br />&lt;bean id="urlMapping" <br />class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"&gt; <br />&lt;property name="interceptors"&gt; <br />&lt;list&gt; <br />&lt;ref bean="openSessionInViewInterceptor"/&gt; <br />&lt;/list&gt; <br />&lt;/property&gt; <br />&lt;property name="mappings"&gt; <br />... <br />&lt;/bean&gt; <br />... <br />&lt;bean name="openSessionInViewInterceptor" <br />class="org.springframework.orm.hibernate.support.OpenSessionInViewInterceptor"&gt; <br />&lt;property name="sessionFactory"&gt;&lt;ref bean="sessionFactory"/&gt;&lt;/property&gt; <br />&lt;/bean&gt; <br />&lt;/beans&gt; <br />Filter Configuration <br /><br />&lt;web-app&gt; <br />... <br />&lt;filter&gt; <br />&lt;filter-name&gt;hibernateFilter&lt;/filter-name&gt; <br />&lt;filter-class&gt; <br />org.springframework.orm.hibernate.support.OpenSessionInViewFilter <br />&lt;/filter-class&gt; <br />&lt;/filter&gt; <br />... <br />&lt;filter-mapping&gt; <br />&lt;filter-name&gt;hibernateFilter&lt;/filter-name&gt; <br />&lt;url-pattern&gt;*.spring&lt;/url-pattern&gt; <br />&lt;/filter-mapping&gt; <br />... <br />&lt;/web-app&gt; <br />Implementing the Hibernate DAO's to use the open session is simple. In fact, if you are already using the Spring Framework to implement your Hibernate DAO's, most likely you will not have to change a thing. The DAO's must access Hibernate through the convenient HibernateTemplate utility, which makes database access a piece of cake. Below is an example DAO. <br /><br />Example DAO <br /><br />public class HibernateProductDAO extends HibernateDaoSupport implements ProductDAO { <br /><br />public Product getProduct(Integer productId) { <br />return (Product)getHibernateTemplate().load(Product.class, productId); <br />} <br /><br />public Integer saveProduct(Product product) { <br />return (Integer) getHibernateTemplate().save(product); <br />} <br /><br />public void updateProduct(Product product) { <br />getHibernateTemplate().update(product); <br />} <br />} <br />Being Lazy in the Business Layer <br /><br />Even outside the view, the Spring Framework makes it easy to use lazy load initialization, through the AOP interceptor HibernateInterceptor. The hibernate interceptor transparently intercepts calls to any business object configured in the Spring application context, opening a hibernate session before the call, and closing the session afterward. Let's run through a quick example. Suppose we have an interface BusinessObject: <br /><br />public interface BusinessObject { <br />public void doSomethingThatInvolvesDaos(); <br />} <br />The class BusinessObjectImpl implements BusinessObject: <br /><br /><br />public class BusinessObjectImpl implements BusinessObject { <br />public void doSomethingThatInvolvesDaos() { <br />// lots of logic that calls <br />// DAO classes Which access <br />// data objects lazily <br />} <br />} <br />Through some configurations in the Spring application context, we can instruct the HibernateInterceptor to intercept calls to the BusinessObjectImpl allowing it's methods to lazily access data objects. Take a look at the fragment below: <br /><br />&lt;beans&gt; <br />&lt;bean id="hibernateInterceptor" class="org.springframework.orm.hibernate.HibernateInterceptor"&gt; <br />&lt;property name="sessionFactory"&gt; <br />&lt;ref bean="sessionFactory"/&gt; <br />&lt;/property&gt; <br />&lt;/bean&gt; <br />&lt;bean id="businessObjectTarget" class="com.acompany.BusinessObjectImpl"&gt; <br />&lt;property name="someDAO"&gt;&lt;ref bean="someDAO"/&gt;&lt;/property&gt; <br />&lt;/bean&gt; <br />&lt;bean id="businessObject" class="org.springframework.aop.framework.ProxyFactoryBean"&gt; <br />&lt;property name="target"&gt;&lt;ref bean="businessObjectTarget"/&gt;&lt;/property&gt; <br />&lt;property name="proxyInterfaces"&gt; <br />&lt;value&gt;com.acompany.BusinessObject&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;property name="interceptorNames"&gt; <br />&lt;list&gt; <br />&lt;value&gt;hibernateInterceptor&lt;/value&gt; <br />&lt;/list&gt; <br />&lt;/property&gt; <br />&lt;/bean&gt; <br />&lt;/beans&gt; <br /><br />When the businessObject bean is referenced, the HibernateInterceptor opens a hibernate session and passes the call onto the BusinessObjectImpl. When the BusinessObjectImpl has finished executing, the HibernateInterceptor transparently closes the session. The application code has no knowledge of any persistence logic, yet it is still able to lazily access data objects. <br /><br />Being Lazy in your Unit Tests <br /><br />Last but not least, we'll need the ability to test our lazy application from J-Unit. This is easily done by overriding the setUp and tearDown methods of the TestCase class. I prefer to keep this code in a convenient abstract TestCase class for all of my tests to extend. <br /><br />public abstract class MyLazyTestCase extends TestCase { <br /><br />private SessionFactory sessionFactory; <br />private Session session; <br /><br />public void setUp() throws Exception { <br />super.setUp(); <br />SessionFactory sessionFactory = (SessionFactory) getBean("sessionFactory"); <br />session = SessionFactoryUtils.getSession(sessionFactory, true); <br />Session s = sessionFactory.openSession(); <br />TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(s)); <br /><br />} <br /><br />protected Object getBean(String beanName) { <br />//Code to get objects from Spring application context <br />} <br /><br />public void tearDown() throws Exception { <br />super.tearDown(); <br />SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); <br />Session s = holder.getSession(); <br />s.flush(); <br />TransactionSynchronizationManager.unbindResource(sessionFactory); <br />SessionFactoryUtils.closeSessionIfNecessary(s, sessionFactory); <br />} <br />} <br /><br />( Jul 08 2004, 09:39:55 AM EDT ) Permalink Comments [2] <br /><br />Trackback URL: <a href="http://jroller.com/trackback/kbaum/Weblog/orm_lazy_initialization_with_dao" target="_new"><font color="#223355">http://jroller.com/trackback/kbaum/Weblog/orm_lazy_initialization_with_dao</font></a><br />Comments: <br /><br /><br />A few things to keep in the back of your mind if you take this approach; 1. If any errors occur while attempting to lazy load relationships in the view (JSP) it would be hard to present a nice error to the user. 2. This would result in at least 2 hibernate sessions (db connections being open for any one request), so you might want to up the number of connections available. Cheers, Dan <br />Posted by Dan Washusen on July 08, 2004 at 09:02 PM EDT # <br /><br />I am a little confused on why it would be difficult to show a nice error jsp. Couldn't we just use the provided servlet container error page mechanisms? In regards to the 2 hibernate sessions being opened. Are you saying that the OpenSessionInViewInterceptor would be run twice if an exception was thrown? Thanks for your feedback! <br /></p></div>
		</div>
<img src ="http://www.blogjava.net/ltc603/aggbug/34405.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ltc603/" target="_blank">阿成</a> 2006-03-09 08:52 <a href="http://www.blogjava.net/ltc603/archive/2006/03/09/34405.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring 编程入门十大问题解答</title><link>http://www.blogjava.net/ltc603/archive/2006/02/10/30103.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Fri, 10 Feb 2006 02:46:00 GMT</pubDate><guid>http://www.blogjava.net/ltc603/archive/2006/02/10/30103.html</guid><wfw:comment>http://www.blogjava.net/ltc603/comments/30103.html</wfw:comment><comments>http://www.blogjava.net/ltc603/archive/2006/02/10/30103.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ltc603/comments/commentRss/30103.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ltc603/services/trackbacks/30103.html</trackback:ping><description><![CDATA[
		<strong>
				<br />
		</strong>
		<p>
				<font size="3">spring下载包中doc目录下的MVC-step-by-step和sample目录下的例子都是比较好的spring开发的例子.</font>
		</p>
		<p>
				<font size="3">　1、如何学习Spring？<br /><br />　　你可以通过下列途径学习spring：<br /><br />　　(1) spring下载包中doc目录下的MVC-step-by-step和sample目录下的例子都是比较好的spring开发的例子。 <br /><br />　　(2) AppFuse集成了目前最流行的几个开源轻量级框架或者工具 Ant,XDoclet,Spring,Hibernate(iBATIS),JUnit,Cactus,StrutsTestCase,Canoo's WebTest,Struts Menu,Display Tag Library,OSCache,JSTL,Struts 。<br /><br />　　你可以通过AppFuse源代码来学习spring。<br /><br />AppFuse网站：<a href="http://raibledesigns.com/wiki/Wiki.jsp?page=AppFuse" target="_blank"><font color="#000000">http://raibledesigns.com/wiki/Wiki.jsp?page=AppFuse</font></a><br /><br />　　(3)Spring 开发指南(夏昕)（<a href="http://www.xiaxin.net/Spring_Dev_Guide.rar%EF%BC%89" target="_blank"><font color="#000000">http://www.xiaxin.net/Spring_Dev_Guide.rar）</font></a><br /><br />　　一本spring的入门书籍,里面介绍了反转控制和依赖注射的概念，以及spring的bean管理，spring的MVC，spring和hibernte，iBatis的结合。<br /><br />　　(4) spring学习的中文论坛<br /><br />　　SpringFramework中文论坛(<a href="http://spring.jactiongroup.net%29/" target="_blank"><font color="#000000">http://spring.jactiongroup.net)</font></a><br /><br />　　Java视线论坛(<a href="http://forum.javaeye.com%29%E7%9A%84spring%E6%A0%8F%E7%9B%AE/" target="_blank"><font color="#000000">http://forum.javaeye.com)的spring栏目</font></a><br /><br />　　2、利用Spring框架编程，console打印出log4j:WARN Please initialize the log4j system properly？<br /><br />　　说明你的log4j.properties没有配置。请把log4j.properties放到工程的classpath中，eclipse的classpath为bin目录，由于编译后src目录下的文件会拷贝到bin目录下，所以你可以把log4j.properties放到src目录下。<br /><br />　　这里给出一个log4j.properties的例子：<br /><br /></font>
		</p>
		<table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%">
				<tbody>
						<tr>
								<td>log4j.rootLogger=DEBUG,stdout<br />log4j.appender.stdout=org.apache.log4j.ConsoleAppender<br />log4j.appender.stdout.layout=org.apache.log4j.PatternLayout<br />log4j.appender.stdout.layout.ConversionPattern=%d %5p (%F:%L) - %m%n</td>
						</tr>
				</tbody>
		</table>
		<br />　　3、出现 java.lang.NoClassDefFoundError?<br /><br />　　一般情况下是由于你没有把必要的jar包放到lib中。<br /><br />　　比如你要采用spring和hibernate（带事务支持的话），你除了spring.jar外还需要hibernat.jar、aopalliance.jar、cglig.jar、jakarta-commons下的几个jar包。<br /><br />http://www.springframework.org/download.html下载spring开发包，提供两种zip包<br />spring-framework-1.1.3-with-dependencies.zip和spring-framework-1.1.3.zip，我建议你下载spring-framework-1.1.3-with-dependencies.zip。这个zip解压缩后比后者多一个lib目录，其中有hibernate、j2ee、dom4j、aopalliance、jakarta-commons等常用包。<br /><br />　　4、java.io.FileNotFoundException: Could not open class path resource [....hbm.xml],提示找不到xml文件？<br /><br />　　原因一般有两个：<br /><br />　　(1)该xml文件没有在classpath中。 <br /><br />　　(2)applicationContext-hibernate.xml中的xml名字没有带包名。比如：<br /><br /><br /><table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"><tbody><tr><td>＜bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean"＞<br />＜property name="dataSource"＞＜ref bean="dataSource"/＞＜/property＞<br />＜property name="mappingResources"＞<br />　＜list＞<br />　　＜value＞User.hbm.xml＜/value＞<br />　　错，改为： <br />　　＜value＞com/yz/spring/domain/User.hbm.xml＜/value＞<br />　＜/list＞<br />＜/property＞<br />＜property name="hibernateProperties"＞<br />＜props＞ <br />　＜prop key="hibernate.dialect"＞ net.sf.hibernate.dialect.MySQLDialect ＜/prop＞ <br />　＜prop key="hibernate.show_sql"＞true＜/prop＞ <br />＜/props＞ <br />＜/property＞<br />＜/bean＞</td></tr></tbody></table><br />　　5、org.springframework.beans.NotWritablePropertyException: Invalid property 'postDao' of bean class？<br /><br />　　出现异常的原因是在application-xxx.xml中property name的错误。<br /><br />　　＜property name="...."＞ 中name的名字是与bean的set方法相关的，而且要注意大小写。<br /><br />　　比如<br /><br /><br /><table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"><tbody><tr><td>public class PostManageImpl extends BaseManage implements PostManage {<br />　private PostDAO dao = null;<br />　public void setPostDAO(PostDAO postDAO){<br />　　this.dao = postDAO;<br />　}<br />}</td></tr></tbody></table><br />　　那么xml的定义应该是：<br /><br /><br /><table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"><tbody><tr><td>＜bean id="postManage" parent="txProxyTemplate"＞<br />＜property name="target"＞<br />　＜bean class="com.yz.spring.service.implement.PostManageImpl"＞<br />　　＜property name="postDAO"＞＜ref bean="postDAO"/＞＜/property＞ 对<br />　　＜property name="dao"＞＜ref bean="postDAO"/＞＜/property＞ 错<br />　＜/bean＞<br />＜/property＞<br />＜/bean＞</td></tr></tbody></table><br />　　6、Spring中如何实现事务管理？<br /><br />　　首先，如果使用mysql，确定mysql为InnoDB类型。<br /><br />　　事务管理的控制应该放到商业逻辑层。你可以写个处理商业逻辑的JavaBean，在该JavaBean中调用DAO，然后把该Bean的方法纳入spring的事务管理。<br /><br />　　比如：xml文件定义如下：<br /><br /><br /><table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"><tbody><tr><td>＜bean id="txProxyTemplate" abstract="true"<br />class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"＞<br />＜property name="transactionManager"＞＜ref bean="transactionManager"/＞＜/property＞<br />＜property name="transactionAttributes"＞<br />＜props＞<br />＜prop key="save*"＞PROPAGATION_REQUIRED＜/prop＞<br />＜prop key="remove*"＞PROPAGATION_REQUIRED＜/prop＞<br />＜prop key="*"＞PROPAGATION_REQUIRED＜/prop＞<br />＜/props＞<br />＜/property＞<br />＜/bean＞<br /><br />＜bean id="userManage" parent="txProxyTemplate"＞<br />　＜property name="target"＞<br />　　＜bean class="com.yz.spring.service.implement.UserManageImpl"＞<br />　　　＜property name="userDAO"＞＜ref bean="userDAO"/＞＜/property＞<br />　　＜/bean＞<br />　＜/property＞<br />＜/bean＞</td></tr></tbody></table><br />　　com.yz.spring.service.implement.UserManageImpl就是我们的实现商业逻辑的JavaBean。我们通过parent元素声明其事务支持。<br /><br />　　7、如何管理Spring框架下更多的JavaBean？<br /><br />　　JavaBean越多，spring配置文件就越大，这样不易维护。为了使配置清晰，我们可以将JavaBean分类管理，放在不同的配置文件中。 应用启动时将所有的xml同时加载。<br /><br />　　比如：<br /><br />　　DAO层的JavaBean放到applicationContext-hibernate.xml中，商业逻辑层的JavaBean放到applicationContext-service.xml中。然后启动类中调用以下代码载入所有的ApplicationContext。<br /><br /><br /><table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"><tbody><tr><td>String[] paths = {"com/yz/spring/dao/hibernate/applicationContext-hibernate.xml",<br />"com/yz/spring/service/applicationContext-service.xml"};<br />ctx = new ClassPathXmlApplicationContext(paths);</td></tr></tbody></table><br />　　8、web应用中如何加载ApplicationContext？<br /><br />　　可以通过定义web.xml，由web容器自动加载。<br /><br /><br /><table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"><tbody><tr><td>＜servlet＞<br />＜servlet-name＞context＜/servlet-name＞<br />＜servlet-class＞org.springframework.web.context.ContextLoaderServlet＜/servlet-class＞<br />＜load-on-startup＞1＜/load-on-startup＞<br />＜/servlet＞<br /><br />＜context-param＞<br />＜param-name＞contextConfigLocation＜/param-name＞<br />＜param-value＞/WEB-INF/applicationContext-hibernate.xml＜/param-value＞<br />＜param-value＞/WEB-INF/applicationContext-service.xml＜/param-value＞<br />＜/context-param＞</td></tr></tbody></table><br />　　9、在spring中如何配置的log4j?<br /><br />　　在web.xml中加入以下代码即可。<br /><br /><br /><table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"><tbody><tr><td>＜context-param＞<br />＜param-name＞log4jConfigLocation＜/param-name＞<br />＜param-value＞/WEB-INF/log4j.properties＜/param-value＞<br />＜/context-param＞</td></tr></tbody></table><br />　　10、Spring框架入门的编程问题解决了，我该如何更深地领会Spring框架呢？<br /><br />　　这两本书你该去看看。这两本书是由Spring的作者Rod Johnson编写的。<br /><br /><br /><table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"><tbody><tr><td>Expert One on one J2EE Design and Development<br />Expert One on one J2EE Development Without EJB</td></tr></tbody></table><br />　　你也该看看martinfowler的Inversion of Control Containers and the Dependency Injection pattern。<br /><br /><br /><table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"><tbody><tr><td>http://www.martinfowler.com/articles/injection.html</td></tr></tbody></table>　<br />　　再好好研读一下spring的文档。<br /><br /><br /><table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"><tbody><tr><td>http://www.jactiongroup.net/reference/html/index.html（中文版，未全部翻译）</td></tr></tbody></table><br />　　还有就是多实践吧。<img src ="http://www.blogjava.net/ltc603/aggbug/30103.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ltc603/" target="_blank">阿成</a> 2006-02-10 10:46 <a href="http://www.blogjava.net/ltc603/archive/2006/02/10/30103.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Spring邮件抽象层发送简单邮件 </title><link>http://www.blogjava.net/ltc603/archive/2006/01/12/27760.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Thu, 12 Jan 2006 07:14:00 GMT</pubDate><guid>http://www.blogjava.net/ltc603/archive/2006/01/12/27760.html</guid><wfw:comment>http://www.blogjava.net/ltc603/comments/27760.html</wfw:comment><comments>http://www.blogjava.net/ltc603/archive/2006/01/12/27760.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/ltc603/comments/commentRss/27760.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ltc603/services/trackbacks/27760.html</trackback:ping><description><![CDATA[Spring提供了一个发送电子邮件的高级抽象层，它向用户屏蔽了底层邮件系统的一些细节，同时负责低层次的代表客户端的资源处理。Spring邮件抽象层的主要包为org.springframework.mail。它包括了发送电子邮件的主要接口MailSender和 封装了简单邮件的属性如from, to,cc, subject, text的值对象叫做SimpleMailMessage。 <br /><br />　　1、我们定义一个发送邮件的接口:OrderManager.java <br /><br /><table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%"><tbody><tr><td>1 public interface OrderManager extends BaseManager{<br />2 　/**<br />3 　*email,要发送的邮件地址;<br />4 　*Code:激活码<br />5 　*/<br />6 　public void placeOrder(String email);<br />7 }</td></tr></tbody></table><br />　　2、我们需要对该接口进行实现的方法:OrderManagerImpl.java<br /><br /><table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%"><tbody><tr><td>1 import javax.mail.Message;<br />2 import javax.mail.MessagingException;<br />3 import javax.mail.internet.InternetAddress;<br />4 import javax.mail.internet.MimeMessage;<br />5 import org.springframework.mail.MailException;<br />6 import org.springframework.mail.javamail.JavaMailSender;<br />7 import org.springframework.mail.javamail.MimeMessagePreparator;<br />8 import service.OrderManager;<br />9 <br />11 public class OrderManagerImpl extends BaseManagerImpl implements OrderManager {<br />12 <br />13　 private JavaMailSender mailsender;<br />14　 private MyMailMessage message;<br />15 <br />16 <br />17　 public void setMessage(CityMailMessage message)<br />18　 {<br />19　　 this.message = message;<br />20　 }<br />21　 public void setMailsender(JavaMailSender mailsender) {<br />22　　 this.mailsender = mailsender;<br />23　 }<br />24　 public void placeOrder(final String email) {<br />25 <br />26 <br />27　　 MimeMessagePreparator preparator = new MimeMessagePreparator() {<br />28　　 public void prepare(MimeMessage mimeMessage) throws MessagingException {<br />29　　　 mimeMessage.setRecipient(Message.RecipientType.TO, <br />30　　　 new InternetAddress(email));<br />31　　　 mimeMessage.setFrom(new InternetAddress(message.getFrom()));<br />32　　　 /**转换编码为GBK*/<br />33　　　 mimeMessage.setSubject(message.getSubject(),"GBK");<br />36　　　 mimeMessage.setText(email+"＜br＞"+message.getSubject()+message.getText(),"GBK");<br />37 <br />38　　 }<br />39　 };<br />40　 try{<br />41　　 mailsender.send(preparator);<br />42　 }<br />43　 catch(MailException ex) {<br />44　　 //log it and go on<br />45　　 System.err.println(ex.getMessage()); <br />46　 }<br />47 }<br />48 }</td></tr></tbody></table><br />　　3、spring配置发送email的applicationContext-email.xml<br /><br /><table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%"><tbody><tr><td>1 ＜?xml version="1.0" encoding="UTF-8"?＞<br />2 ＜!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"<br />3 "http://www.springframework.org/dtd/spring-beans.dtd"＞<br />4 <br />5 ＜beans＞<br />6 　＜bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"＞<br />7 　＜property name="host"＞<br />8 　　＜value＞smtp.163.com＜/value＞<br />9 　＜/property＞<br />10　＜property name="username"＞<br />11　　＜value＞username＜/value＞<br />12　＜/property＞<br />13　＜property name="password"＞<br />14 　＜value＞password＜/value＞<br />15　＜/property＞<br />16 ＜property name="javaMailProperties"＞<br />17 　＜props＞<br />18 　　＜prop key="mail.smtp.auth"＞true＜/prop＞<br />19 　　＜prop key="mail.smtp.timeout"＞25000＜/prop＞<br />20 　＜/props＞<br />21 ＜/property＞<br />22 ＜/bean＞<br />23 <br />24 ＜bean id="mailMessage" class="org.springframework.mail.SimpleMailMessage"＞<br />25 　＜property name="from"＞<br />26 　　＜value＞Email＜/value＞<br />27 　＜/property＞<br />28 　＜property name="subject"＞<br />29 　　＜value＞标题＜/value＞<br />30 　＜/property＞<br />31 　＜property name="text"＞<br />32 　　＜value＞内容＜/value＞<br />33 　＜/property＞<br />46 ＜/bean＞<br />47 <br />48 ＜bean id="orderManager" class="cn.cityyouth.service.impl.OrderManagerImpl"＞<br />49 　＜property name="mailsender"＞<br />50 　　＜ref bean="mailSender" /＞<br />51 　＜/property＞<br />52 　＜property name="message"＞<br />53 　　＜ref bean="mailMessage" /＞<br />54 　＜/property＞<br />55 ＜/bean＞<br />56 <br />57 ＜/beans＞</td></tr></tbody></table><br />　　4、最后配置自己的jsp页面以及action<br /><br /><table align="center" bgcolor="#e3e3e3" border="1" bordercolor="#cccccc" width="90%"><tbody><tr><td>1 package cn.cityyouth.web.action;<br />2 <br />3 import javax.servlet.http.HttpServletRequest;<br />4 import javax.servlet.http.HttpServletResponse;<br />5 import org.apache.struts.action.ActionForm;<br />6 import org.apache.struts.action.ActionForward;<br />7 import org.apache.struts.action.ActionMapping;<br />8 import org.apache.struts.action.ActionMessage;<br />9 import org.apache.struts.action.ActionMessages;<br />10 import com.test.service.OrderManager;<br />11 <br />12 public class SendMailAction extends BaseAction {<br />13 <br />14　 /**<br />15　 * Method execute<br />16　 * <br />17　 * @param mapping<br />18　 * @param form<br />19　 * @param request<br />20　 * @param response<br />21　 * @return ActionForward<br />22　 */<br />23 public ActionForward execute(ActionMapping mapping, ActionForm form,<br />24 HttpServletRequest request, HttpServletResponse response) {<br />25　 OrderManager omi=(OrderManager)this.getBean("orderManager");<br />26　 String useremail="123@163.com";<br />27　 omi.placeOrder(useremail);<br />28 }<br />29 }</td></tr></tbody></table><br />　　到此所有的开发以结束。<br /><br />　　Sring邮件抽象层的主要包是：org.springframework.mail 包。它包含叫MailSender为发送邮件的核心接口和包含简单邮件属性例如from,to,cc,subject,text叫SimpleMailMessage的值对象. 这个包也包含一个检查异常的层次，它支持一个更高级别的抽象超过低级别的邮件系统异常伴随根异常存在MailException. 请参考JavaDocs为更多的信息杂邮件异常层次。<br /><br />　　Spring也支持一个MailSender的专用于JavaMail特征例如MIME消息子接口，命名为org.springframework.javamail.JavaMailerSener。它也支持一个为JavaMail MIME信息的准备回调接口，命名为org.springframework.mail.JavaMail.MimeMessagePreparator.<img src ="http://www.blogjava.net/ltc603/aggbug/27760.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ltc603/" target="_blank">阿成</a> 2006-01-12 15:14 <a href="http://www.blogjava.net/ltc603/archive/2006/01/12/27760.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>