﻿<?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-MicroFish-随笔分类-spring</title><link>http://www.blogjava.net/liulu/category/15186.html</link><description>Open &amp; Open
&lt;a href="http://www.fastwebcounter.com" title="Free Web Counter"&gt;&lt;font color="red"&gt;&lt;script src="http://fastwebcounter.com/secure.php?s=www.blogjava.net/liulu"&gt;&lt;/script&gt;hits&lt;/font&gt;&lt;/a&gt;</description><language>zh-cn</language><lastBuildDate>Fri, 02 Mar 2007 02:39:13 GMT</lastBuildDate><pubDate>Fri, 02 Mar 2007 02:39:13 GMT</pubDate><ttl>60</ttl><item><title>《Pro Spring》学习笔记(9)－－基础进阶(4)</title><link>http://www.blogjava.net/liulu/archive/2006/12/21/89217.html</link><dc:creator>刘璐</dc:creator><author>刘璐</author><pubDate>Thu, 21 Dec 2006 02:25:00 GMT</pubDate><guid>http://www.blogjava.net/liulu/archive/2006/12/21/89217.html</guid><wfw:comment>http://www.blogjava.net/liulu/comments/89217.html</wfw:comment><comments>http://www.blogjava.net/liulu/archive/2006/12/21/89217.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/liulu/comments/commentRss/89217.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/liulu/services/trackbacks/89217.html</trackback:ping><description><![CDATA[
		<h4 class="TextColor1" id="subjcns!24C2F96D552BF2FB!143" style="MARGIN-BOTTOM: 0px"> </h4>
		<div id="msgcns!24C2F96D552BF2FB!143">
				<div>      到目前为止，我们都是使用BeanFactory接口以及它的子接口来使用Spring，尽管使用BeanFactory也是一种不错的方式，但正如前面看到的，有些时候，我们还是不得不自己编写代码来调用诸如preInstantiateSingletons，<font color="#000000">postProcessBeanFactory等方法。</font></div>
				<div>      为了使用的方便，Spring提供了BeanFactory的一个扩展：<strong>ApplicationContext</strong>。使用ApplicationContext，我们可以减少需要编写的代码的数量，并且ApplicationContext也增加了一些新的功能。如果在Web工程中使用Spring，我们甚至可以让Spring自动加载ApplicationContext，而无需自己编写代码来创建它。</div>
				<div>      ApplicationContext具备一些BeanFactory不具备的功能：国际化（Internationalization），事件发布（Event publication），资源管理和访问（Resource management and access），更多的生命周期控制接口（Additional lifecycle interfaces）以及底层组件的自动配置（Improved automatic configuration of infrastructure components）。</div>
				<div>      Spring为ApplicationContext接口提供了三种实现：FileSystemXmlApplicationContext，ClasspathXmlApplicationContext和XmlWebApplicationContext。其中XmlWebApplicationContext是专为Web工程定制的，并且我们可以使用ContextLoaderListener或ContextLoaderServlet来自动加载ApplicationContext配置。</div>
				<div>      通常国际化是通过使用MessageSource接口来实现的，为了在ApplicationContext中使用MessageSource，我们需要配置一个类型为MessageSource，名称为messageSource的bean。</div>
				<div>
						<font color="#993366">&lt;beans&gt;<br />    &lt;bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"&gt;<br />        &lt;property name="basenames"&gt;<br />            &lt;list&gt;<br />                &lt;value&gt;buttons&lt;/value&gt;<br />                &lt;value&gt;labels&lt;/value&gt;<br />            &lt;/list&gt;<br />        &lt;/property&gt;<br />     &lt;/bean&gt;<br />&lt;/beans&gt;</font>
				</div>
				<div>      在配置了messageSource后，我们就可以使用ApplicationContext的getMessage方法来获取资源内容了。</div>
				<div>      ApplicationContext的另一个重要特性就是对发布和接收事件的支持，ApplicationContext会在其被配置的时候自动注册所有的侦听器（listener），事件的发布是通过ApplicationContext的publishEvent方法来实现的。</div>
				<div>
						<font color="#99cc00">//Event class</font>
				</div>
				<div>
						<font color="#666699">
								<strong>public class </strong>MessageEvent <strong>extends </strong>ApplicationEvent {<br />    <strong>private </strong>String msg;<br />    <strong>public </strong>MessageEvent(Object source, String msg) {<br />        <strong>super</strong>(source);<br />        <strong>this</strong>.msg = msg;<br />    }<br />    <strong>public </strong>String getMessage() {<br />        <strong>return </strong>msg;<br />    }<br />}</font>
				</div>
				<div>
						<font color="#99cc00">//Listener class</font>
				</div>
				<div>
						<font color="#666699">
								<strong>public class</strong> MessageEventListener <strong>implements </strong>ApplicationListener {<br /><strong>    public void</strong> onApplicationEvent(ApplicationEvent event) {<br /><strong>        if</strong>(event instanceof MessageEvent) {<br />            MessageEvent msgEvt = (MessageEvent)event;<br />            System.out.println("Received: " + msgEvt.getMessage());<br />        }<br />    }<br />}</font>
				</div>
				<div>
						<font color="#99cc00">//Publish class</font>
				</div>
				<div>
						<font color="#666699">
								<strong>public class</strong> Publisher <strong>implements </strong>ApplicationContextAware {<br /><strong>    private </strong>ApplicationContext ctx;<br /><strong>    public static void</strong> main(String[] args) {<br />        ApplicationContext ctx = </font>
				</div>
				<div>
						<font color="#666699">                new FileSystemXmlApplicationContext("./ch5/src/conf/events/events.xml");<br />        Publisher pub = (Publisher) ctx.getBean("publisher");<br />        pub.publish("Hello World!");<br />        pub.publish("The quick brown fox jumped over the lazy dog");<br />    }<br /><strong>    public void</strong> setApplicationContext(ApplicationContext applicationContext) </font>
				</div>
				<div>
						<font color="#666699">            <strong>throws </strong>BeansException {<br /><strong>        this</strong>.ctx = applicationContext;<br />    }<br /><strong>    public void </strong>publish(String message) {<br />        ctx.publishEvent(new MessageEvent(<strong>this</strong>, message));<br />    }<br />}</font>
				</div>
				<div>
						<font color="#993366">&lt;beans&gt;<br />    &lt;bean id="publisher" class="com.apress.prospring.ch5.event.Publisher"/&gt;<br />    &lt;bean id="messageEventListener" class="com.apress.prospring.ch5.event.MessageEventListener"/&gt;<br />&lt;/beans&gt;</font>
				</div>
				<div>
						<font color="#993366">      </font>
						<font color="#000000">资源访问是我们经常碰到的，这些资源有可能存在于一个文件中，类路径中的一个jar包中，抑或是在远程服务器上。Spring为我们提供了统一的，协议无关的方式来访问各种各样的资源，这给我们访问各种资源提供了极大的方便。</font>
				</div>
				<div>
						<font color="#666699">
								<strong>public class</strong> ResourceDemo {<br />    <strong>public static void </strong>main(String[] args) <strong>throws </strong>Exception {<br />        ApplicationContext ctx = </font>
				</div>
				<div>
						<font color="#666699">                <strong>new </strong>FileSystemXmlApplicationContext("./ch5/src/conf/events/events.xml");<br />        Resource res1 = ctx.getResource("</font>
						<a>
								<font color="#666699">file:///d:/tmp/test.txt</font>
						</a>
						<font color="#666699">");<br />        displayInfo(res1);<br />        Resource res2 = ctx.getResource("classpath:lib/commons-logging.jar");<br />        displayInfo(res2);<br />        Resource res3 = ctx.getResource("</font>
						<a href="http://www.google.co.uk/">
								<font color="#666699">http://www.google.co.uk</font>
						</a>
						<font color="#666699">");<br />        displayInfo(res3);<br />    }<br />    <strong>private static void </strong>displayInfo(Resource res) <strong>throws </strong>Exception {<br />        System.out.println(res.getClass());<br />        System.out.println(res.getURL().getContent());<br />        System.out.println("");<br />    }<br />}</font>
				</div>
		</div>
<img src ="http://www.blogjava.net/liulu/aggbug/89217.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liulu/" target="_blank">刘璐</a> 2006-12-21 10:25 <a href="http://www.blogjava.net/liulu/archive/2006/12/21/89217.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《Pro Spring》学习笔记(8)－－基础进阶(3)</title><link>http://www.blogjava.net/liulu/archive/2006/12/21/89216.html</link><dc:creator>刘璐</dc:creator><author>刘璐</author><pubDate>Thu, 21 Dec 2006 02:24:00 GMT</pubDate><guid>http://www.blogjava.net/liulu/archive/2006/12/21/89216.html</guid><wfw:comment>http://www.blogjava.net/liulu/comments/89216.html</wfw:comment><comments>http://www.blogjava.net/liulu/archive/2006/12/21/89216.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/liulu/comments/commentRss/89216.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/liulu/services/trackbacks/89216.html</trackback:ping><description><![CDATA[
		<h4 class="TextColor1" id="subjcns!24C2F96D552BF2FB!142" style="MARGIN-BOTTOM: 0px"> </h4>
		<div id="msgcns!24C2F96D552BF2FB!142">
				<div>      如果bean无法简单地通过<strong>new</strong>关键字来创建怎么办，通常碰到这样的情况时，我们都会使用工厂模式来处理，Spring也提供了对FactoryBean的支持，当我们配置了一个bean为FactoryBean时，随后我们获取的则并不是该FactoryBean，Spring会通过调用FactoryBean.getObject()方法，返回真正的目标bean。FactoryBean在Spring中的最著名应用就是对声明式事务的处理。</div>
				<div>      在Spring中使用FactoryBean，我们需要编写一个实现了FactoryBean接口的类，以一个信息摘要FactoryBean为例，它主要实现根据不同的参数，创建不同的MessageDigest的实例。</div>
				<div>
						<font color="#666699">
								<strong>public class </strong>MessageDigestFactoryBean <strong>implements </strong>FactoryBean, InitializingBean {<br />    <strong>private </strong>String algorithmName = "MD5";<br />    <strong>private </strong>MessageDigest messageDigest = null;<br />    <strong>public </strong>Object getObject() <strong>throws </strong>Exception {<br />        <strong>return </strong>messageDigest.clone();<br />    }<br />    <strong>public Class </strong>getObjectType() {<br />        <strong>return </strong>MessageDigest.class;<br />    }<br />    <strong>public boolean </strong>isSingleton() {</font>
				</div>
				<div>
						<font color="#666699">        <strong>return </strong>true;<br />    }<br />    <strong>public void </strong>afterPropertiesSet() <strong>throws </strong>Exception {<br />        messageDigest = MessageDigest.getInstance(algorithmName);<br />    }<br />    <strong>public void</strong> setAlgorithmName(String algorithmName) {<br />        <strong>this</strong>.algorithmName = algorithmName;<br />    }<br />}</font>
				</div>
				<div>
						<font color="#666699">      </font>
						<font color="#000000">getObject方法是供Spring调用，用来返回真正的bean给其它bean的（而不是FactoryBean本身），getObjectType方法可以返回null，但如果指定了类型，就可以使用Spring的自动装载功能了。isSingleton方法是指定bean是否是单例的，注意不能通过FactoryBean的配置文件来指定bean是否为单例，因为那样指定的是FactoryBean本身，而不是真正的目标bean。</font>
				</div>
				<div>      FactoryBean的配置和普通bean并没有什么区别。</div>
				<div>      由于Bean配置文件中，各个属性都是以String的形式配置的（除了使用<strong>ref</strong>引用其它bean外），因此，Spring在组装bean的时候，需要把String类型的值转化成合适的类型，这就需要用到JavaBean中的概念：<strong>PropertyEditor</strong>。</div>
				<div>      Spring内置了7种预先注册的PropertyEditor：ByteArrayPropertyEditor，ClassEditor，FileEditor，LocaleEditor，PropertiesEditor，StringArrayPropertyEditor，URLEditor。通过名字，我们就能清楚地知道它们对应的类型了。</div>
				<div>      尽管内置的PropertyEditor可以处理大部分常见的类型，我们仍然会碰到需要创建自己的PropertyEditor的情况。为了简化自定义PropertyEditor的创建，Spring提供了PropertyEditorSupport类，我们只需要扩展该类，并实现其中的setAsText方法即可。</div>
				<div>
						<font color="#666699">
								<strong>public class </strong>PatternPropertyEditor <strong>extends </strong>PropertyEditorSupport {<br />    <strong>public void </strong>setAsText(String text) <strong>throws </strong>IllegalArgumentException {<br />        Pattern pattern = Pattern.compile(text);<br />        setValue(pattern);<br />    }<br />}</font>
				</div>
				<div>
						<font color="#000000">      可以看到，实现一个自定义的PropertyEditor是很容易的，但怎么才能让它起作用呢，也就是通常所说的注册PropertyEditor。Spring提供了两种注册的方式：1.通过ConfigurableBeanFactory的registerCustomEditor方法；2.在BeanFactory的配置文件中定义CustomEditorConfigurer。</font>
				</div>
				<div>
						<font color="#993366">&lt;bean name="customEditorConfigurer"<br />class="org.springframework.beans.factory.config.CustomEditorConfigurer"&gt;<br />    &lt;property name="customEditors"&gt;<br />        &lt;map&gt;<br />            &lt;entry key="java.util.regex.Pattern"&gt;<br />                &lt;bean class="com.apress.prospring.ch5.pe.PatternPropertyEditor"/&gt;<br />            &lt;/entry&gt;<br />        &lt;/map&gt;<br />    &lt;/property&gt;<br />&lt;/bean&gt;</font>
				</div>
				<div>      自定义的PropertyEditor是通过CustomEditorConfigurer的一个类型为Map的属性添加的，key值是自定义PropertyEditor对应的类型的全类名。</div>
				<div>      在使用时需要先调用：</div>
				<div>
						<font color="#666699">CustomEditorConfigurer config = </font>
				</div>
				<div>
						<font color="#666699">    (CustomEditorConfigurer) factory.getBean("customEditorConfigurer");<br />config.postProcessBeanFactory(factory);</font>
				</div>
				<div>      来将所有自定义的ProperyEditor注册到BeanFactory中。</div>
		</div>
<img src ="http://www.blogjava.net/liulu/aggbug/89216.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liulu/" target="_blank">刘璐</a> 2006-12-21 10:24 <a href="http://www.blogjava.net/liulu/archive/2006/12/21/89216.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《Pro Spring》学习笔记(6)－－基础进阶(1)</title><link>http://www.blogjava.net/liulu/archive/2006/12/21/89214.html</link><dc:creator>刘璐</dc:creator><author>刘璐</author><pubDate>Thu, 21 Dec 2006 02:23:00 GMT</pubDate><guid>http://www.blogjava.net/liulu/archive/2006/12/21/89214.html</guid><wfw:comment>http://www.blogjava.net/liulu/comments/89214.html</wfw:comment><comments>http://www.blogjava.net/liulu/archive/2006/12/21/89214.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/liulu/comments/commentRss/89214.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/liulu/services/trackbacks/89214.html</trackback:ping><description><![CDATA[
		<h4 class="TextColor1" id="subjcns!24C2F96D552BF2FB!140" style="MARGIN-BOTTOM: 0px"> </h4>
		<div id="msgcns!24C2F96D552BF2FB!140">
				<div>      Spring不仅提供了基本的IOC功能，借助于BeanFactory以及其它组件，我们还可以使用其它一些更高级的功能。但是需要注意的是，使用这些高级功能，将不可避免的使得我们的工程依赖于Spring。这些高级功能大致包括：管理bean的生命周期，让bean感知Spring（Spring aware），使用方法注入，使用FactoryBean，使用PropertyEditor以及了解Spring的ApplicationContext<br />      有时候，我们需要在bean的生命周期中的某些阶段做一些相应的操作（类似于Servlet和EJB），像其它IOC容器一样，Spring也提供了管理bean生命周期的功能。两个主要的阶段是：</div>
				<div>post-initialization（bean初始化之后）和pre-destruction（bean销毁之前）.<br />      post-initialization是指在Spring完成了bean的所有依赖注入以及相应的检测之后，</div>
				<div>      pre-destruction是指在Spring销毁bean之前。<br />      post-initialization和pre-destruction只能应用于<strong>sigleton</strong>模式的bean，因为非sigleton的bean的生命周期并不由Spring控制（它们是由JVM控制的）。<br />      Spring提供了两种机制来实现bean生命周期的管理：基于接口的和基于指定方法的。</div>
				<div>      使用基于接口的机制，我们需要实现Spring的相关接口，然后，Spring会使用回调机制在指定的阶段调用接口中定义的方法，从而实现bean生命周期的管理。而使用基于指定方法的机制，我们需要在BeanFactory的配置中指定相应的方法名称，Spring会使用Java的反射机制在指定的阶段调用我们指定的方法，从而实现bean生命周期的管理。<br />      选择哪种机制取决于我们的工程的需要。基于接口的机制要求我们实现Spring的接口，这会带来对Spring的依赖，但是当我们定义了很多相同类型的bean时，使用基于接口的机制可以免去我们为每个bean定义指定相应方法的麻烦。基于指定方法的机制则可以让我们避免对Spring的依赖，这在当我们使用第三方的类库（因此，我们无法修改其代码来实现Spring的接口）时是非常有用的。<br />      以post-initialization为例：<br />      使用基于接口的机制，我们需要实现Spring的InitializingBean接口的afterPropertiesSet方法<br />      <font color="#666699"><strong>public class </strong>SimpleBeanWithInterface <strong>implements </strong>InitializingBean {<br />          ...<br />          <strong>public void </strong>afterPropertiesSet() <strong>throws </strong>Exception {<br />              ...<br />          }<br />          ...<br />      }<br /></font>      <font color="#993366">&lt;beans&gt;<br />         &lt;bean id="simpleBean1"<br />         class="com.apress.prospring.ch5.lifecycle.SimpleBeanWithInterface"&gt;<br />             ...<br />         &lt;/bean&gt;<br />      &lt;/beans&gt;<br /></font>      使用基于指定方法的机制，我们只需在BeanFactory的配置中指定相应的方法名称<br /><font color="#993366">      &lt;beans&gt;<br />          &lt;bean id="simpleBean1"<br />          class="com.apress.prospring.ch5.lifecycle.SimpleBean"<br />          init-method="init"&gt;<br />              ...<br />          &lt;/bean&gt;<br />      &lt;/beans&gt;</font><br />      SimpleBean中包含对应的init方法<br /><font color="#666699">      <strong>public class</strong> SimpleBean {<br />          ...<br />          <strong>public void</strong> init() {<br />              ...<br />          }<br />          ...<br />      }</font><br />      需要注意的是，init方法必须不包含任何参数，尽管我们可以为init方法指定任意的返回值，但Spring会忽略它，因此最好的做法是在init方法中抛出异常来表明初始化失败了。<br />      我们也可以同时使用这两种机制，这时，Spring会先调用InitializingBean接口的afterPropertiesSet方法，再调用我们自己指定的init方法。<br />      相对的，pre-destruction使用DisposableBean接口的destroy方法和bean标签的destroy-method属性<br />      相对于依赖查找（Dependency Lookup），依赖注入（Dependency Injection）最大的卖点就是容器的无关性，但是有时候，我们确实需要和容器进行一些交互，例如访问BeanFactory或者是获得bean的名称等。<br />      为了获得bean的名称，我们需要实现Spring的BeanNameAware接口，BeanNameAware只有一个方法，void setBeanName(String name)，只要我们的bean实现了BeanNameAware接口，Spring就会在bean配置结束，其它生命周期相关的回调函数（initialization或者 destroy）调用之前，回调该方法置入bean的名称。</div>
				<div>      类似的，为了访问beanFactory，我们需要实现Spring的BeanFactoryAware接口的</div>
				<div>void setBeanFactory(BeanFactory factory)方法。</div>
		</div>
<img src ="http://www.blogjava.net/liulu/aggbug/89214.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liulu/" target="_blank">刘璐</a> 2006-12-21 10:23 <a href="http://www.blogjava.net/liulu/archive/2006/12/21/89214.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《Pro Spring》学习笔记(7)－－基础进阶(2)</title><link>http://www.blogjava.net/liulu/archive/2006/12/21/89215.html</link><dc:creator>刘璐</dc:creator><author>刘璐</author><pubDate>Thu, 21 Dec 2006 02:23:00 GMT</pubDate><guid>http://www.blogjava.net/liulu/archive/2006/12/21/89215.html</guid><wfw:comment>http://www.blogjava.net/liulu/comments/89215.html</wfw:comment><comments>http://www.blogjava.net/liulu/archive/2006/12/21/89215.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/liulu/comments/commentRss/89215.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/liulu/services/trackbacks/89215.html</trackback:ping><description><![CDATA[
		<h4 class="TextColor1" id="subjcns!24C2F96D552BF2FB!141" style="MARGIN-BOTTOM: 0px"> </h4>
		<div id="msgcns!24C2F96D552BF2FB!141">
				<div>
						<div>      Spring1.1中引入了一个很有用的IOC新特性－－方法注入（Method Injection）。这能让我们在组装bean时获得极大的灵活性。Spring的方法注入可以分为两种形式：查询方法注入（Lookup Method Injection）和方法替换（Method Replacement）。查询方法注入提供了另一种机制来让bean获取它依赖的其它bean，方法替换则可以在不修改源代码的基础上，修改任意bean的任何方法的实现。为了提供这两个功能，Spring借助了CGLIB包。</div>
						<div>      先来看看查询方法注入的使用。想象这样的情形：我们有一个singleton类型的bean A，它需要使用另一个非singleton类型的bean B来执行一些操作。由于两个bean的生命周期是不同的，因此我们不能简单的在bean A的配置中使用ref标签来要求Spring注入bean B，因为那样会让我们每次取得bean A时都使用同一个bean B的实例。回想前面介绍过的BeanFactoryAware接口，我们可以让bean A实现该接口，这样就可以在bean A内部使用beanFactory的genBean方法来获取bean B了。只要我们将bean B配置为非singleton类型，每次使用getBean方法就会得到一个新的bean B的实例。</div>
						<div>      使用查询方法注入，我可以不必实现任何的Spring的接口，也不需要在bean A中显示的使用getBean方法来获得bean B。我们只需要在bean A中申明一个查询方法，然后在bean A的配置文件中指明该查询方法，那么Spring就会自动的将bean B注入到bean A中去了。由于查询方法注入的概念相对比较复杂，因此我们还是通过具体的例子来直观的感受它是如何工作的。</div>
						<div>      在这个例子中，我们创建一个非singleton的bean和两个实现了同一个接口的singleton的bean，一个通过传统的设值方法注入获得非singleton的bean，另一个则通过查询方法注入。</div>
						<div>
								<font color="#99cc00">
										<strong>//The MyHelper Bean</strong>
										<br />
								</font>
								<font color="#666699">
										<strong>public class</strong> MyHelper {<br />    <strong>public void </strong>doSomethingHelpful() {<br />        // do something!<br />    }<br />}</font>
						</div>
						<div>
								<font color="#99cc00">
										<strong>//The DemoBean Interface</strong>
								</font>
						</div>
						<div>
								<font color="#666699">
										<strong>public interface </strong>DemoBean {<br />    <strong>public</strong> MyHelper getMyHelper();<br />    <strong>public void</strong> someOperation();<br />}</font>
						</div>
						<div>
								<font color="#99cc00">
										<strong>//The StandardLookupDemoBean</strong>
								</font>
						</div>
						<div>
								<font color="#666699">
										<strong>public class</strong> StandardLookupDemoBean <strong>implements </strong>DemoBean {<br /><strong>    private </strong>MyHelper helper;<br /><strong>    public void</strong> setMyHelper(MyHelper helper) {<br /><strong>        this</strong>.helper = helper;<br />    }<br /><strong>    public </strong>MyHelper getMyHelper() {<br /><strong>        return this</strong>.helper;<br />    }<br /><strong>    public void</strong> someOperation() {<br />        helper.doSomethingHelpful();<br />    }<br />}</font>
						</div>
						<div>
								<font color="#99cc00">
										<strong>//The AbstractLookupDemoBean</strong>
								</font>
						</div>
						<div>
								<font color="#666699">
										<strong>public abstract class</strong> AbstractLookupDemoBean <strong>implements </strong>DemoBean {<br />    <strong>public abstract</strong> MyHelper getMyHelper();<br />    <strong>public void </strong>someOperation() {<br />        getMyHelper().doSomethingHelpful();<br />    }<br />}</font>
						</div>
						<div>
								<font color="#993366">&lt;beans&gt;<br />    &lt;bean id="helper" class="com.apress.prospring.ch5.mi.MyHelper" singleton="false"/&gt;<br />    &lt;bean id="abstractLookupBean" </font>
						</div>
						<div>
								<font color="#993366">class="com.apress.prospring.ch5.mi.AbstractLookupDemoBean"&gt;<br />        &lt;lookup-method name="getMyHelper" bean="helper"/&gt;<br />    &lt;/bean&gt;<br />    &lt;bean id="standardLookupBean"<br />    class="com.apress.prospring.ch5.mi.StandardLookupDemoBean"&gt;<br />        &lt;property name="myHelper"&gt;<br />            &lt;ref local="helper"/&gt;<br />        &lt;/property&gt;<br />    &lt;/bean&gt;<br />&lt;/beans&gt;</font>
						</div>
						<div>
								<font color="#993366">      </font>
								<font color="#000000">可以看到，我们使用了<strong>lookup-method</strong>来对查询方法注入进行配置，<strong>name</strong>属性告诉Spring需要覆写bean中的哪个方法，该方法必须是没有参数的，并且返回类型是我们需要获得的bean的类型，<strong>bean</strong>属性告诉Spring查询方法需要返回哪个bean。</font>
						</div>
						<div>      通过DemoBean standardBean = (DemoBean)factory.getBean("standardLookupBean");获得standardBean，然后比较standardBean.getMyHelper() == standardBean.getMyHelper()，可以发现，直接使用设置方法注入，每次获得的非singleton的bean实际上是同一个实例。而使用查询方法注入，则会每次得到一个新的实例，这实际上是因为我们使用factory.getBean("abstractLookupBean")获得abstractBean时，Spring根据<strong>lookup-method</strong>的配置，覆写了查询方法，从而返回一个新的bean实例，正如前面提到的，这是通过CGLIB包来实现的。</div>
						<div>      值得注意的是，我们将查询方法定义为抽象的，这不是必须的，但这么做能防止我们忘记了配置<strong>lookup-method</strong>，从而使用了空的（当然不是我们期望的）查询方法。</div>
						<div>      好了，让我们再来看看方法替换，虽然它被划分为方法注入的一种，但它和我们以前接触到的注入方式有着很大的差异，以前我们都是注入一个bean，而方法替换则是替换bean中的方法实现。同查询方法注入一样，我们还是通过一个例子来理解方法替换的使用。</div>
						<div>
								<strong>
										<font color="#99cc00">//The ReplacementTarget Class</font>
								</strong>
						</div>
						<div>
								<font color="#666699">
										<font color="#666699">
												<strong>public class </strong>
										</font>ReplacementTarget {<br /><strong>    public </strong>String formatMessage(String msg) {<br /><strong>        return</strong> "&lt;h1&gt;" + msg + "&lt;/h1&gt;";<br />    }<br /><strong>    public </strong>String formatMessage(Object msg) {<br /><strong>        return</strong> "&lt;h1&gt;" + msg + "&lt;/h1&gt;";<br />    }<br />}</font>
						</div>
						<div>
								<font color="#666699">     </font>
								<font color="#000000">现在由于某些原因，我们需要修改以String为参数的方法的实现方式，并且不能修改ReplacementTarget类的源代码，借助于Spring的方法替换，我们可以轻松地实现。</font>
						</div>
						<div>     首先，创建一个实现了MethodReplacer接口的类。</div>
						<div>
								<font color="#666699">
										<strong>public class</strong> FormatMessageReplacer <strong>implements </strong>MethodReplacer {<br /><strong>    public </strong>Object reimplement(Object target, Method method, Object[] args)<br /><strong>throws </strong>Throwable {</font>
						</div>
						<div>
								<font color="#666699">        ...<br />        String msg = (String) args[0];<br /><strong>        return </strong>"&lt;h2&gt;" + msg + "&lt;/h2&gt;";</font>
						</div>
						<div>
								<font color="#666699">        ...</font>
						</div>
						<div>
								<font color="#666699">    }<br />}</font>
						</div>
						<div>
								<font color="#993366">&lt;beans&gt;<br />    &lt;bean id="methodReplacer"<br />    class="com.apress.prospring.ch5.mi.FormatMessageReplacer"/&gt;<br />    &lt;bean id="replacementTarget"<br />    class="com.apress.prospring.ch5.mi.ReplacementTarget"&gt;<br />        &lt;replaced-method name="formatMessage" replacer="methodReplacer"&gt;<br />            &lt;arg-type&gt;String&lt;/arg-type&gt;<br />        &lt;/replaced-method&gt;<br />    &lt;/bean&gt;<br />    &lt;bean id="standardTarget"<br />    class="com.apress.prospring.ch5.mi.ReplacementTarget"/&gt;<br />&lt;/beans&gt;</font>
						</div>
						<div>
								<font color="#993366">      </font>
								<font color="#000000">通过<strong>replaced-method</strong>标签来配置需要替换的方法，<strong>name</strong>属性指明了需要替换的方法名，<strong>replacer</strong>属性指明了用哪个bean来实现替换操作。<strong>arg-type</strong>是用来指明需要替换的方法的参数类型的，在bean中有重载方法时（像ReplacementTarget类一样），指明参数类型可以让Spring明确知道需要替换的是哪个方法。值得注意的是，<strong>arg-type</strong>是模式匹配的，因此，String将匹配String和StringBuffer。</font>
						</div>
						<div>      方法替换在很多场合都是有用的，比如我们只想为一个特殊的bean改变它所依赖的另一个bean的实现方法，而不影响其它bean的引用。最好是为每个需要替换的方法，或者是一组重载的方法定义一个替换类，而不要为众多毫不相关的方法使用同一个替换类。这可以减少很多没必要的比较，从而提高代码的执行效率。</div>
				</div>
		</div>
<img src ="http://www.blogjava.net/liulu/aggbug/89215.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liulu/" target="_blank">刘璐</a> 2006-12-21 10:23 <a href="http://www.blogjava.net/liulu/archive/2006/12/21/89215.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《Pro Spring》学习笔记(4)－－配置BeanFactory(1)</title><link>http://www.blogjava.net/liulu/archive/2006/12/21/89211.html</link><dc:creator>刘璐</dc:creator><author>刘璐</author><pubDate>Thu, 21 Dec 2006 02:22:00 GMT</pubDate><guid>http://www.blogjava.net/liulu/archive/2006/12/21/89211.html</guid><wfw:comment>http://www.blogjava.net/liulu/comments/89211.html</wfw:comment><comments>http://www.blogjava.net/liulu/archive/2006/12/21/89211.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/liulu/comments/commentRss/89211.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/liulu/services/trackbacks/89211.html</trackback:ping><description><![CDATA[
		<h4 class="TextColor1" id="subjcns!24C2F96D552BF2FB!138" style="MARGIN-BOTTOM: 0px"> </h4>
		<div id="msgcns!24C2F96D552BF2FB!138">
				<div>      Spring使用spring-beans.dtd文件来定义BeanFactory的XML配置规范。可以在<a href="http://www.springframework.org/dtd/spring-beans.dtd"><font color="#4b7001">http://www.springframework.org/dtd/spring-beans.dtd</font></a>找到该dtd文件，当然，Spring的下载文件中也已经包含了该dtd文件。它被放在dist文件夹中。</div>
				<div>      配置文件的根元素是<strong>beans</strong>，每个组件使用<strong>bean</strong>元素来定义，bean元素可以有许多属性，其中有两个是必须的：<strong>id</strong>和<strong>class</strong>（这里说的id是必须的并不意味着在配置文件中必须指定id，后面会详细说明）。id表示组件的默认名称，class表示组件的类型。</div>
				<div>      如果使用设值注入，则需要使用<strong>property</strong>子标签，来指定组件的属性。</div>
				<div>
						<font color="#993366">&lt;bean id="renderer" class="com.apress.prospring.ch2.StandardOutMessageRenderer"&gt;<br />    &lt;property name="messageProvider"&gt;<br />        &lt;ref local="provider"/&gt;<br />    &lt;/property&gt;<br />&lt;/bean&gt;</font>
				</div>
				<div>
						<font color="#993366">      </font>
						<font color="#000000">使用构造子注入时，则使用<strong>constructor-arg</strong>子标签，来指定构造函数的参数。</font>
				</div>
				<div>
						<font color="#993366">&lt;bean id="provider" class="com.apress.prospring.ch4.ConfigurableMessageProvider"&gt;<br />    &lt;constructor-arg&gt;<br />        &lt;value&gt;This is a configurable message&lt;/value&gt;<br />    &lt;/constructor-arg&gt;<br />&lt;/bean&gt;</font>
				</div>
				<div>
						<font color="#993366">     </font>
						<font color="#000000">当构造函数有多个参数时，可以使用<strong>constructor-arg</strong>标签的<strong>index</strong>属性，index属性的值从0开始。</font>
				</div>
				<div>
						<font color="#993366">&lt;bean id="provider" class="com.apress.prospring.ch4.ConfigurableMessageProvider"&gt;<br />    &lt;constructor-arg index="0"&gt;<br />        &lt;value&gt;first parameter&lt;/value&gt;<br />    &lt;/constructor-arg&gt;</font>
				</div>
				<div>
						<font color="#993366">    &lt;constructor-arg index="1"&gt;<br />        &lt;value&gt;second parameter&lt;/value&gt;<br />    &lt;/constructor-arg&gt;<br /><br />&lt;/bean&gt;</font>
				</div>
				<div>     在使用构造子注入时，需要注意的问题是要避免构造子冲突的情况发生。考虑下面的情况：</div>
				<div>
						<font color="#666699">
								<strong>public class </strong>ConstructorConfusion {</font>
				</div>
				<div>
						<font color="#666699">    <strong>public </strong>ConstructorConfusion(String someValue) {<br />        System.out.println("ConstructorConfusion(String) called");<br />    }<br />    <strong>public </strong>ConstructorConfusion(<strong>int </strong>someValue) {<br />        System.out.println("ConstructorConfusion(int) called");</font>
				</div>
				<div>
						<font color="#666699">    }</font>
				</div>
				<div>
						<font color="#666699">}</font>
				</div>
				<div>
						<font color="#666699">     </font>
						<font color="#000000">使用如下配置文件</font>
				</div>
				<div>
						<font color="#993366">&lt;bean id="constructorConfusion" class="com.apress.prospring.ch4.ConstructorConfusion"&gt;<br />    &lt;constructor-arg&gt;<br />        &lt;value&gt;90&lt;/value&gt;<br />    &lt;/constructor-arg&gt;<br />&lt;/bean&gt;</font>
				</div>
				<div>     那么，当实例化组件<em>constructorConfusion</em>时，将输出<font color="#000000">ConstructorConfusion(String) called，也就是说参数类型为String的构造函数被调用了，这显然不符合我们的要求。为了让Spring调用参数为int的构造函数来实例化组件<em>constructorConfusion</em>，我们需要在配置文件中明确的告诉Spring，需要使用哪个构造函数，这需要使用<strong>constructor-arg</strong>的<strong>type</strong>属性。</font></div>
				<div>
						<font color="#993366">&lt;bean id="constructorConfusion" class="com.apress.prospring.ch4.ConstructorConfusion"&gt;<br />    &lt;constructor-arg type="int"&gt;<br />        &lt;value&gt;90&lt;/value&gt;<br />    &lt;/constructor-arg&gt;<br />&lt;/bean&gt;</font>
				</div>
				<div>
						<font color="#000000">     我们不仅可以构造单个BeanFactory，而且可以建立有继承关系的多个BeanFactory。只需要将父BeanFactory作为参数传给子BeanFactory的构造函数即可。</font>
				</div>
				<div>
						<font color="#666699">BeanFactory parent = </font>
				</div>
				<div>
						<font color="#666699">    <strong>new </strong>XmlBeanFactory(<strong>new </strong>FileSystemResource("./ch4/src/conf/parent.xml"));<br />BeanFactory child = </font>
				</div>
				<div>
						<font color="#666699">    <strong>new </strong>XmlBeanFactory(<strong>new </strong>FileSystemResource("./ch4/src/conf/beans.xml"), parent);</font>
				</div>
				<div>
						<font color="#000000">     如果子BeanFactory和父BeanFactory中含有名称相同的Bean，那么在子BeanFactory中使用</font>
				</div>
				<div>
						<font color="#000000">
								<font color="#993366">&lt;ref bean="sameNameBean"/&gt;</font>引用的将是子BeanFactory中的bean，为了引用父BeanFactory中的bean，我们需要使用<strong>ref</strong>标签的<strong>parent</strong>属性<font color="#993366">，&lt;ref parent="sameNameBean"/&gt;</font>。</font>
				</div>
				<div>     为了注入集合属性，Spring提供了<strong>list</strong>,<strong>map</strong>,<strong>set</strong>和<strong>props</strong>标签，分别对应List,Map,Set和Properties,我们甚至可以嵌套的使用它们（List of Maps of Sets of Lists）。</div>
				<div>
						<font color="#993366">&lt;bean id="injectCollection" class="com.apress.prospring.ch4.CollectionInjection"&gt;<br />    &lt;property name="map"&gt;<br />        &lt;map&gt;<br />            &lt;entry key="someValue"&gt;<br />                &lt;value&gt;Hello World!&lt;/value&gt;<br />            &lt;/entry&gt;<br />            &lt;entry key="someBean"&gt;<br />                &lt;ref local="oracle"/&gt;<br />            &lt;/entry&gt;<br />        &lt;/map&gt;<br />    &lt;/property&gt;<br />    &lt;property name="props"&gt;<br />        &lt;props&gt;<br />            &lt;prop key="firstName"&gt;<br />                Rob<br />            &lt;/prop&gt;<br />            &lt;prop key="secondName"&gt;<br />                Harrop<br />            &lt;/prop&gt;<br />        &lt;/props&gt;<br />    &lt;/property&gt;<br />    &lt;property name="set"&gt;<br />        &lt;set&gt;<br />            &lt;value&gt;Hello World!&lt;/value&gt;<br />            &lt;ref local="oracle"/&gt;<br />        &lt;/set&gt;<br />    &lt;/property&gt;<br />    &lt;property name="list"&gt;<br />        &lt;list&gt;<br />            &lt;value&gt;Hello World!&lt;/value&gt;<br />            &lt;ref local="oracle"/&gt;<br />        &lt;/list&gt;<br />    &lt;/property&gt;<br />&lt;/bean&gt;</font>
				</div>
		</div>
<img src ="http://www.blogjava.net/liulu/aggbug/89211.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liulu/" target="_blank">刘璐</a> 2006-12-21 10:22 <a href="http://www.blogjava.net/liulu/archive/2006/12/21/89211.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《Pro Spring》学习笔记(5)－－配置BeanFactory(2)</title><link>http://www.blogjava.net/liulu/archive/2006/12/21/89213.html</link><dc:creator>刘璐</dc:creator><author>刘璐</author><pubDate>Thu, 21 Dec 2006 02:22:00 GMT</pubDate><guid>http://www.blogjava.net/liulu/archive/2006/12/21/89213.html</guid><wfw:comment>http://www.blogjava.net/liulu/comments/89213.html</wfw:comment><comments>http://www.blogjava.net/liulu/archive/2006/12/21/89213.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/liulu/comments/commentRss/89213.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/liulu/services/trackbacks/89213.html</trackback:ping><description><![CDATA[
		<h4 class="TextColor1" id="subjcns!24C2F96D552BF2FB!139" style="MARGIN-BOTTOM: 0px"> </h4>
		<div id="msgcns!24C2F96D552BF2FB!139">
				<div>      BeanFactory中的每个bean都必须至少有一个唯一的名字，Spring为了灵活的支持各种情形，使用了相对复杂的命名体系。如果我们为bean指定了<strong>id</strong>属性，那么id属性的值将成为bean的名称，如果没有指定id属性，Spring将使用<strong>name</strong>属性的第一个值（多个值用逗号或者分号分隔）作为bean的名称，如果name属性也没有指定，Spring将使用bean的类名（包括package的完整类名）来作为bean的名称，对于多个bean使用相同类名的情况，Spring会在类名后面添加#2,#3等序号来加以区别。不管怎么说，使用<strong>id</strong>属性来指定bean的名称总是一个不错的选择。</div>
				<div>     在Spring中，所有bean默认都是以单例（<strong>singleton</strong>）形态存在的，也就是说我们通过BeanFactory的getBean方法获取的同一名称的bean是完全相同的，即：beanFactory.getBean("name")==beanFactory.getBean("name")。更改bean的形态为非singleton（原型的，<strong>prototype</strong>）是很容易的，只需在bean标签中，指定<strong>singleton</strong>属性为false就可以了。</div>
				<div>
						<font color="#993366">&lt;bean id="nonSingleton" class="java.lang.String" singleton="false"&gt;<br />    ...<br />&lt;/bean&gt;</font>
				</div>
				<div>
						<font color="#993366">      </font>
						<font color="#000000">为了简化配置，Spring还提供了自动组装（Auto-Wiring）bean的功能，有四种自动组装方式：根据名称（byName），根据类型（byType），构造子（Constructor）以及自动侦测（autodetect）。</font>
				</div>
				<div>
						<font color="#000000">      使用根据名称自动组装时，Spring根据bean的属性的名称去寻找同名的bean配置。</font>
				</div>
				<div>
						<font color="#000000">      使用根据类型自动组装时，Spring根据bean的属性的类型去寻找同类型的bean配置，如果有多个同类型的bean配置，那么Spring将会抛出异常，以表示无法确定使用哪个。</font>
				</div>
				<div>
						<font color="#000000">      使用构造子自动组装和使用根据类型自动组装比较类似，需要注意的是，使用构造子自动组装时，Spring会匹配尽可能多的参数。例如，我们有一个bean拥有两个构造函数，第一个接收一个String类型的参数，第二个接收一个String类型和一个Integer类型的参数，这时，如果在beanFactory的配置文件中有一个String类型的bean配置和一个Integer类型的bean配置，那么Spring将会使用第二个拥有两个参数的构造函数。</font>
				</div>
				<div>       使用自动侦测组装时，Spring会在根据类型自动组装和根据构造子自动组装之间自动作出选择，依据是：如果bean拥有默认的（无参数的）构造函数，那么Spring使用根据类型自动组装的方式，否则，使用根据构造子自动组装的方式。</div>
				<div>       有时候，我们可能会有多个bean拥有共同的类型，或是实现一些共同的接口，因此它们会有一些相同的配置，如果能将这些相同的配置提取出来，各个bean只要继承这些相同的配置，然后添加自己特有的配置，将会大大减少重复的配置，降低发生错误的可能。Spring的bean继承机制就是出于这样的目的而提供的。在Spring中，我们可以将这些相同的配置提取出来，配置成一个parent bean，然后各个bean（child bean）可以继承parent bean，在child bean中，可以覆写parent bean中的配置，也可以添加自己的配置。parent bean是通过child bean的bean标签的<strong>parent</strong>属性来指定的。</div>
				<div>
						<font color="#993366">&lt;bean id="inheritParent" class="com.apress.prospring.ch4.inheritance.SimpleBean"&gt;<br />    &lt;property name="name"&gt;<br />        &lt;value&gt;Rob Harrop&lt;/value&gt;<br />    &lt;/property&gt;<br />    &lt;property name="age"&gt;<br />        &lt;value&gt;22&lt;/value&gt;<br />    &lt;/property&gt;<br />&lt;/bean&gt;<br />&lt;bean id="inheritChild" class="com.apress.prospring.ch4.inheritance.SimpleBean"<br />parent="inheritParent"&gt;<br />    &lt;property name="age"&gt;<br />        &lt;value&gt;35&lt;/value&gt;<br />    &lt;/property&gt;<br />&lt;/bean&gt;</font>
				</div>
				<div>
						<font color="#993366">      </font>
						<font color="#000000">需要注意的是，bean的继承体系并不完全等同于java的类继承体系，我们完全可以在数个拥有相同类型的bean上使用继承，这不会带来任何问题。因此，相对于java的继承体系来说，Spring 的bean继承体系更类似于模板类型。</font>
				</div>
		</div>
<img src ="http://www.blogjava.net/liulu/aggbug/89213.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liulu/" target="_blank">刘璐</a> 2006-12-21 10:22 <a href="http://www.blogjava.net/liulu/archive/2006/12/21/89213.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《Pro Spring》学习笔记(2)－－何为Spring</title><link>http://www.blogjava.net/liulu/archive/2006/12/21/89209.html</link><dc:creator>刘璐</dc:creator><author>刘璐</author><pubDate>Thu, 21 Dec 2006 02:20:00 GMT</pubDate><guid>http://www.blogjava.net/liulu/archive/2006/12/21/89209.html</guid><wfw:comment>http://www.blogjava.net/liulu/comments/89209.html</wfw:comment><comments>http://www.blogjava.net/liulu/archive/2006/12/21/89209.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/liulu/comments/commentRss/89209.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/liulu/services/trackbacks/89209.html</trackback:ping><description><![CDATA[
		<h4 class="TextColor1" id="subjcns!24C2F96D552BF2FB!127" style="MARGIN-BOTTOM: 0px"> </h4>
		<div id="msgcns!24C2F96D552BF2FB!127">
				<div>      Spring通常被称为是构造Java工程的轻量级框架。这其中包含了两方面的内容：首先，你可以使用Spring构造各种Java工程，而不是像Apache的Struts那样，仅仅局限于Web工程。其次，所谓轻量级框架，并不是指类的数量或是工程的规模是轻量级的，用Spring的话说，轻量级就意味着更少的影响，你可以很容易的修改你的程序来获得Spring提供的各种好处，也可以很容易的从你的工程中去除Spring。当然，需要注意的是，这仅仅是指Spring的核心组件。Spring还提供了很多其它的组件，像数据访问等，使用这些组件，将使得你的工程与Spring框架形成耦合，但是，相比于你获得的好处而言，这些耦合根本算不得什么。</div>
				<div>      Spring框架的核心是基于控制反转(Invdersion Of Control, IOC)理论的，控制反转使得我们可以在外部来创建和管理组件之间的依赖关系。例如：类Foo依赖于一个Bar类型的实例来执行某些操作，传统的方式是，Foo使用new关键字或者从某个工厂类来创建一个Bar类的实例。然而，使用控制反转，一个Bar类型的实例将在运行时由外部程序提供。这种方式可以很形象的看作是在运行时，将依赖的组件实例注入到当前组件中。因此，在某些时候，控制反转也被称为依赖注入(Dependency Injection, DI)。在Spring中，你可以认为控制反转就等同于依赖注入。</div>
				<div>      依赖注入给我们带来的好处包括：</div>
				<div>      1.减少了组件关联的代码：你不再需要在组件内部自己创建需要使用的其它组件，它们会在运行时自动被注入进来，特别是当某些组件需要通过JNDI来获得，或是根本无法直接获得，例如远程资源时，DI带来的好处就更加明显了。</div>
				<div>      2.将依赖关系移到代码外：这会带来两点好处，首先，你可以在外部方便的管理组件间的依赖关系，而不需要重新编译代码。其次，你可以方便的切换某些依赖的实现类，例如将PostgreSQL的DAO实现切换为Oracle的DAO实现。</div>
				<div>      3.统一的依赖管理：传统的散布在工程各处的管理依赖关系的代码将不复存在，所有的依赖信息都集中在一个统一的地方，这使得维护变得容易，同时降低了发生错误的可能。</div>
				<div>      4.提高了可测试性：你可以很容易的替换依赖类的实现方式，如使用mock实现来代替真正的实现方式。假设我们需要测试业务对象(Business Object, BO)，我们就可以使用mock实现来代替真正的DAO实现，从而避免真正地访问数据库，这大大提高了测试的效率。</div>
				<div>      5.遵循良好的设计方式：使用DI通常意味着遵循面向接口的设计方式。毫无疑问，面向接口是一种良好的设计方式。</div>
				<div>      Spring框架还包括了以下这些方面的内容：</div>
				<div>      1.面向方面的编程(Aspect Oriented Programming, AOP)</div>
				<div>      2.数据访问(Accessing Data in Spring)</div>
				<div>      3.事务管理(Managing Transactions)</div>
				<div>      4.简化J2EE的整合(Simplifying and Integrating with J2EE)</div>
				<div>      5.Web层的MVC框架(MVC in the Web Tier)</div>
				<div>      6.对远程访问的支持(Remoting Support)</div>
				<div>      7.邮件支持(Mail Support)</div>
				<div>      8.任务安排的支持(Job Scheduling Support)</div>
				<div>      9.简化的异常处理(Simplified Exception Handling)</div>
				<div>      10.源代码级的元数据(Source Level Metadata)</div>
		</div>
<img src ="http://www.blogjava.net/liulu/aggbug/89209.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liulu/" target="_blank">刘璐</a> 2006-12-21 10:20 <a href="http://www.blogjava.net/liulu/archive/2006/12/21/89209.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《Pro Spring》学习笔记(3)－－Spring中的IOC</title><link>http://www.blogjava.net/liulu/archive/2006/12/21/89210.html</link><dc:creator>刘璐</dc:creator><author>刘璐</author><pubDate>Thu, 21 Dec 2006 02:20:00 GMT</pubDate><guid>http://www.blogjava.net/liulu/archive/2006/12/21/89210.html</guid><wfw:comment>http://www.blogjava.net/liulu/comments/89210.html</wfw:comment><comments>http://www.blogjava.net/liulu/archive/2006/12/21/89210.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/liulu/comments/commentRss/89210.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/liulu/services/trackbacks/89210.html</trackback:ping><description><![CDATA[
		<h4 class="TextColor1" id="subjcns!24C2F96D552BF2FB!129" style="MARGIN-BOTTOM: 0px"> </h4>
		<div id="msgcns!24C2F96D552BF2FB!129">
				<div>      控制反转包括两种类型：依赖查找（Dependency Lookup）和依赖注入（Dependency Injection），我们主要讨论的是依赖注入。</div>
				<div>      依赖注入可以分为两种类型：构造子注入（Constructor Dependency Injection）和设值注入（Setter Dependency Injection）</div>
				<div>      构造子注入，组件的依赖关系是通过构造函数来提供的，每个依赖关系对应构造函数的各个参数，IOC容器在实例化组件时，通过构造函数注入依赖关系。</div>
				<div>
						<font color="#666699">
								<strong>public class </strong>ConstructorInjection {<br />    <strong>private </strong>Dependency dep;</font>
				</div>
				<div>
						<font color="#666699">    <strong>public </strong>ConstructorInjection(Dependency dep) {</font>
				</div>
				<div>
						<font color="#666699">        <strong>this</strong>.dep = dep;<br />    }<br />}</font>
				</div>
				<div>构造子注入适用于在使用某个组件之前，确保所有的依赖关系都已注入。</div>
				<div>      设值注入，组件的依赖关系是通过JavaBean形式的setter方法注入的，IOC容器通过调用相应的set方法注入依赖关系。<br /><font color="#666699"><strong>public class </strong>SetterInjection {<br />    <strong>private </strong>Dependency dep;<br />    <strong>public void </strong>setMyDependency(Dependency dep) {<br />        <strong>this</strong>.dep = dep;<br />    }<br />}</font></div>
				<div>设值注入适用于需要给某些依赖关系提供默认值的情况。</div>
				<div>      Spring IOC容器的核心是BeanFactory，BeanFactory负责管理组件以及组件间的依赖关系。术语<strong>bean</strong>在Spring中代表由容器管理的任何组件。Spring提供了两种常用的BeanFactory实现：DefaultListableBeanFactory和XmlBeanFactory。</div>
				<div>      在BeanFactory中，每个bean都至少有一个名称，作为唯一标识，如果bean拥有多个名称的话，那么除第一个名称外的其它名称都将被认为是别名。</div>
				<div>      DefaultListableBeanFactory可以使用PropertiesBeanDefinitionReader或者XmlBeanDefinitionReader（当然还可以是其它任何实现了BeanDefinitionReader接口的Bean定义读取器）来读取配置文件。</div>
				<div>
						<font color="#99cc00">//使用PropertiesBeanDefinitionReader</font>
				</div>
				<div>
						<font color="#666699">
								<strong>private static </strong>BeanFactory getBeanFactory() <strong>throws </strong>Exception {<br /></font>    <font color="#99cc00">// get the bean factory<br /></font>    <font color="#666699">DefaultListableBeanFactory factory = <strong>new </strong>DefaultListableBeanFactory();<br /></font>    <font color="#99cc00">// create a definition reader<br /></font>    <font color="#666699">PropertiesBeanDefinitionReader rdr = <strong>new </strong>PropertiesBeanDefinitionReader(factory);<br /></font>    <font color="#99cc00">// load the configuration options<br />    </font><font color="#666699">Properties props = <strong>new </strong>Properties();<br />    props.load(<strong>new </strong>FileInputStream("./ch2/src/conf/beans.properties"));<br />    rdr.registerBeanDefinitions(props);<br />    <strong>return </strong>factory;</font></div>
				<div>
						<font color="#666699">}</font>
				</div>
				<div>
						<font color="#99cc00">//使用XmlBeanDefinitionReader</font>
				</div>
				<div>
						<div>
								<font color="#666699">
										<strong>private static </strong>BeanFactory getBeanFactory() <strong>throws </strong>Exception {<br /></font>    <font color="#99cc00">// get the bean factory<br /></font>    <font color="#666699">DefaultListableBeanFactory factory = <strong>new </strong>DefaultListableBeanFactory();<br /></font>    <font color="#99cc00">// create a definition reader<br /></font>    <font color="#666699">XmlBeanDefinitionReader rdr = <strong>new </strong>XmlBeanDefinitionReader(factory);</font></div>
						<div>    <font color="#99cc00">// load the configuration options</font><br />    <font color="#666699">rdr.loadBeanDefinitions(<strong>new </strong>FileSystemResource("ch4/src/conf/beans.xml"));</font></div>
						<div>
								<font color="#666699">    <strong>return </strong>factory;</font>
						</div>
						<div>
								<font color="#666699">}</font>
						</div>
						<div>      XmlBeanFactory继承了DefaultListableBeanFactory，在使用XML配置文件时可以简化代码的编写，这也是我们最常用的BeanFactory。</div>
						<div>
								<div>
										<font color="#666699">
												<strong>private static </strong>BeanFactory getBeanFactory() <strong>throws </strong>Exception {<br />    XmlBeanFactory factory = </font>
								</div>
								<div>
										<font color="#666699">        <strong>new </strong>XmlBeanFactory(<strong>new </strong>FileSystemResource("ch4/src/conf/beans.xml"));</font>
								</div>
								<div>
										<font color="#666699">    <strong>return </strong>factory;</font>
								</div>
								<div>
										<font color="#666699">}</font>
								</div>
								<div>      获得了BeanFactory对象后，我们就可以使用bean的名称来获取我们需要的组件对象了。</div>
								<div>
										<font color="#666699">Oracle oracle = (Oracle)factoyr.get("oracle");</font>
								</div>
						</div>
				</div>
		</div>
<img src ="http://www.blogjava.net/liulu/aggbug/89210.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liulu/" target="_blank">刘璐</a> 2006-12-21 10:20 <a href="http://www.blogjava.net/liulu/archive/2006/12/21/89210.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转)《Pro Spring》学习笔记(1)－－写在前面的话</title><link>http://www.blogjava.net/liulu/archive/2006/12/21/89208.html</link><dc:creator>刘璐</dc:creator><author>刘璐</author><pubDate>Thu, 21 Dec 2006 02:19:00 GMT</pubDate><guid>http://www.blogjava.net/liulu/archive/2006/12/21/89208.html</guid><wfw:comment>http://www.blogjava.net/liulu/comments/89208.html</wfw:comment><comments>http://www.blogjava.net/liulu/archive/2006/12/21/89208.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/liulu/comments/commentRss/89208.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/liulu/services/trackbacks/89208.html</trackback:ping><description><![CDATA[不是刚开始接触Spring了，也用Spring做过一些东西。我的感觉是用Spring会有一种很爽的感觉，一切都是那么的简单高效，顺理成章。
<div>      在网上也看到过很多牛人对Spring的评论文章，其中不乏一些颇有微词的评论。当然，任何事务都不可能十全十美的，我只是一个普通的Java程序员，还无法站在一定的高度，看到Spring这样那样的不足。我感觉到的只是Spring给我带来的好处和便利，因此我选择了Spring。</div><div>      接下来的文字，记录的只是在学习《Pro Spring》这本书的过程中，我觉得需要着重了解的部分，大部分文字属于抄书，外加一点点个人的理解。</div><div>      感谢Rob Harrop和Jan Machacek给我们带来了这本通俗易懂的Spring入门书籍。</div><img src ="http://www.blogjava.net/liulu/aggbug/89208.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liulu/" target="_blank">刘璐</a> 2006-12-21 10:19 <a href="http://www.blogjava.net/liulu/archive/2006/12/21/89208.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>springIDE</title><link>http://www.blogjava.net/liulu/archive/2006/11/18/81936.html</link><dc:creator>刘璐</dc:creator><author>刘璐</author><pubDate>Sat, 18 Nov 2006 08:13:00 GMT</pubDate><guid>http://www.blogjava.net/liulu/archive/2006/11/18/81936.html</guid><wfw:comment>http://www.blogjava.net/liulu/comments/81936.html</wfw:comment><comments>http://www.blogjava.net/liulu/archive/2006/11/18/81936.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/liulu/comments/commentRss/81936.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/liulu/services/trackbacks/81936.html</trackback:ping><description><![CDATA[
		<p>首先尝试link方式安装，无法使用。上网查询后，网友都认为应该用updata方式安装</p>
		<p>1.打开eclipse，菜单"help"-&gt;"software updates"-&gt;"find and install"<br />2.在弹出的界面中选择“Search for new features to install”<br />3.这一步可分成两种情况：<br />a.如果本地已经下载SpringIDE的压缩包，请解压到一个目录（比如SpringIDE），里面有两个目录（features、plugins）和一个文件site.xml，在弹出的界面中选择"New Local Site"，指到前面的解压后目录（SpringIDE），点“OK”，在"Name"中输入“SpringIDE Update”<br />b.如果没有下载SpringIDE的压缩包，在弹出的界面中选择“New Remote Site”，在"Name"中输入“SpringIDE Update”，在“URL”中输入“http://springide.org/updatesite/”，点“OK”<br />4.选中"SpringIDE Update"，点“finish”,开始搜索站点的更新信息<br />5.在搜索界面的界面中选中要更新的，继续<br />因为我的网络有防火墙隔离，所以直接下载了springide_updatesite_1.2.1.zip在本地安装。</p>
		<p>安装过程中，出现error retrieving “feature.xml“的错误，这时候删除了根目录的site.xml文件，就可以updata了</p>
		<p>另外，springIDE的使用方法可以参考 <a href="http://www.volitation.net/Dynamic/print.asp?SelectID=101">http://www.volitation.net/Dynamic/print.asp?SelectID=101</a></p>
<img src ="http://www.blogjava.net/liulu/aggbug/81936.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liulu/" target="_blank">刘璐</a> 2006-11-18 16:13 <a href="http://www.blogjava.net/liulu/archive/2006/11/18/81936.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring 编程入门十大问题解答</title><link>http://www.blogjava.net/liulu/archive/2006/09/14/69521.html</link><dc:creator>刘璐</dc:creator><author>刘璐</author><pubDate>Thu, 14 Sep 2006 00:25:00 GMT</pubDate><guid>http://www.blogjava.net/liulu/archive/2006/09/14/69521.html</guid><wfw:comment>http://www.blogjava.net/liulu/comments/69521.html</wfw:comment><comments>http://www.blogjava.net/liulu/archive/2006/09/14/69521.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/liulu/comments/commentRss/69521.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/liulu/services/trackbacks/69521.html</trackback:ping><description><![CDATA[1、如何学习Spring？<br />你可以通过下列途径学习spring：<br />(1) spring下载包中doc目录下的MVC-step-by-step和sample目录下的例子都是比较好的spring开发的例子。
<p>(2) AppFuse集成了目前最流行的几个开源轻量级框架或者工具Ant,XDoclet,Spring,Hibernate(iBATIS),JUnit,Cactus,StrutsTestCase,Canoo's WebTest,Struts Menu,Display Tag Library,OSCache,JSTL,Struts 。<br />你可以通过AppFuse源代码来学习spring。<br />AppFuse网站：<a href="http://raibledesigns.com/wiki/Wiki.jsp?page=AppFuse"><font color="#002c99">http://raibledesigns.com/wiki/Wiki.jsp?page=AppFuse</font></a></p><p>(3)Spring 开发指南(夏昕)（<a href="http://www.xiaxin.net/Spring_Dev_Guide.rar"><font color="#002c99">http://www.xiaxin.net/Spring_Dev_Guide.rar</font></a>）<br />一本spring的入门书籍,里面介绍了反转控制和依赖注射的概念，以及spring的bean管理，spring的MVC，spring和hibernte，iBatis的结合。</p><p>(4) spring学习的中文论坛<br />SpringFramework中文论坛(<a href="http://spring.jactiongroup.net/"><font color="#002c99">http://spring.jactiongroup.net</font></a>)<br />Java视线论坛(<a href="http://forum.javaeye.com/"><font color="#002c99">http://forum.javaeye.com</font></a>)的spring栏目</p><p>2、利用Spring框架编程，console打印出log4j:WARN Please initialize the log4j system properly？<br />说明你的log4j.properties没有配置。请把log4j.properties放到工程的classpath中，eclipse的classpath为bin目录，由于编译后src目录下的文件会拷贝到bin目录下，所以你可以把log4j.properties放到src目录下。<br />这里给出一个log4j.properties的例子：</p><p>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</p><p><br />3、出现 java.lang.NoClassDefFoundError?<br />一般情况下是由于你没有把必要的jar包放到lib中。</p><p>比如你要采用spring和hibernate（带事务支持的话），你除了spring.jar外还需要hibernat.jar、aopalliance.jar、cglig.jar、jakarta-commons下的几个jar包。</p><p><a href="http://www.springframework.org/download.html"><font color="#002c99">http://www.springframework.org/download.html</font></a>下载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 /></p><p>4、java.io.FileNotFoundException: Could not open class path resource [....hbm.xml],提示找不到xml文件？<br />原因一般有两个：<br />(1)该xml文件没有在classpath中。<br />(2)applicationContext-hibernate.xml中的xml名字没有带包名。比如：<br />&lt;bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean"&gt;<br />        &lt;property name="dataSource"&gt;&lt;ref bean="dataSource"/&gt;&lt;/property&gt;<br />        &lt;property name="mappingResources"&gt;<br />            &lt;list&gt;<br />                &lt;value&gt;User.hbm.xml&lt;/value&gt;         错，改为： &lt;value&gt;com/yz/spring/domain/User.hbm.xml&lt;/value&gt;<br />            &lt;/list&gt;<br />        &lt;/property&gt;<br />        &lt;property name="hibernateProperties"&gt;<br />         &lt;props&gt; <br />         &lt;prop key="hibernate.dialect"&gt; net.sf.hibernate.dialect.MySQLDialect &lt;/prop&gt; <br />         &lt;prop key="hibernate.show_sql"&gt;true&lt;/prop&gt; <br />        &lt;/props&gt; <br />        &lt;/property&gt;<br />&lt;/bean&gt;</p><p><br />5、org.springframework.beans.NotWritablePropertyException: Invalid property 'postDao' of bean class？<br />出现异常的原因是在application-xxx.xml中property name的错误。<br />&lt;property name="...."&gt; 中name的名字是与bean的set方法相关的，而且要注意大小写。<br />比如<br />public class PostManageImpl extends BaseManage implements PostManage {<br />    private PostDAO dao = null;<br />    public void setPostDAO(PostDAO postDAO){<br />        this.dao = postDAO;<br />    }<br />}<br />那么xml的定义应该是：<br />&lt;bean id="postManage" parent="txProxyTemplate"&gt;<br />        &lt;property name="target"&gt;<br />            &lt;bean class="com.yz.spring.service.implement.PostManageImpl"&gt;<br />                &lt;property name="postDAO"&gt;&lt;ref bean="postDAO"/&gt;&lt;/property&gt;    对<br />                &lt;property name="dao"&gt;&lt;ref bean="postDAO"/&gt;&lt;/property&gt;             <font style="BACKGROUND-COLOR: #ff0000">错<br /></font>            &lt;/bean&gt;<br />        &lt;/property&gt;<br />&lt;/bean&gt;<br /></p><p>6、Spring中如何实现事务管理？<br />        首先，如果使用mysql，确定mysql为InnoDB类型。<br />        事务管理的控制应该放到商业逻辑层。你可以写个处理商业逻辑的JavaBean，在该JavaBean中调用DAO，然后把该Bean的方法纳入spring的事务管理。<br /><br />比如：xml文件定义如下：<br />&lt;bean id="txProxyTemplate" abstract="true"<br />        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"&gt;<br />        &lt;property name="transactionManager"&gt;&lt;ref bean="transactionManager"/&gt;&lt;/property&gt;<br />        &lt;property name="transactionAttributes"&gt;<br />            &lt;props&gt;<br />                &lt;prop key="save*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;<br />                &lt;prop key="remove*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;<br />                &lt;prop key="*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;<br />            &lt;/props&gt;<br />        &lt;/property&gt;<br />&lt;/bean&gt;</p><p>&lt;bean id="userManage" parent="txProxyTemplate"&gt;<br />      &lt;property name="target"&gt;<br />          &lt;bean class="com.yz.spring.service.implement.UserManageImpl"&gt;<br />              &lt;property name="userDAO"&gt;&lt;ref bean="userDAO"/&gt;&lt;/property&gt;<br />          &lt;/bean&gt;<br />      &lt;/property&gt;<br />&lt;/bean&gt;</p><p>com.yz.spring.service.implement.UserManageImpl就是我们的实现商业逻辑的JavaBean。我们通过parent元素声明其事务支持。<br /></p><p>7、如何管理Spring框架下更多的JavaBean？<br />        JavaBean越多，spring配置文件就越大，这样不易维护。为了使配置清晰，我们可以将JavaBean分类管理，放在不同的配置文件中。 应用启动时将所有的xml同时加载。<br />比如：<br />        DAO层的JavaBean放到applicationContext-hibernate.xml中，商业逻辑层的JavaBean放到applicationContext-service.xml中。然后启动类中调用以下代码载入所有的ApplicationContext。<br /><br />String[] paths = {"com/yz/spring/dao/hibernate/applicationContext-hibernate.xml",<br />                          "com/yz/spring/service/applicationContext-service.xml"};<br />ctx = new ClassPathXmlApplicationContext(paths);</p><p><br />8、web应用中如何加载ApplicationContext？<br />可以通过定义web.xml，由web容器自动加载。</p><p> &lt;servlet&gt;<br />  &lt;servlet-name&gt;context&lt;/servlet-name&gt;<br />  &lt;servlet-class&gt;org.springframework.web.context.ContextLoaderServlet&lt;/servlet-class&gt;<br />  &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br /> &lt;/servlet&gt;<br /> <br /> &lt;context-param&gt;<br />  &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;<br />  &lt;param-value&gt;/WEB-INF/applicationContext-hibernate.xml&lt;/param-value&gt;<br />  &lt;param-value&gt;/WEB-INF/applicationContext-service.xml&lt;/param-value&gt;<br /> &lt;/context-param&gt;</p><p>9、在spring中如何配置的log4j?<br />在web.xml中加入以下代码即可。<br />&lt;context-param&gt;<br />  &lt;param-name&gt;log4jConfigLocation&lt;/param-name&gt;<br />  &lt;param-value&gt;/WEB-INF/log4j.properties&lt;/param-value&gt;<br />&lt;/context-param&gt;<br /></p><p>10、Spring框架入门的编程问题解决了，我该如何更深地领会Spring框架呢？<br />这两本书你该去看看。这两本书是由Spring的作者Rod Johnson编写的。<br />Expert One on one J2EE Design and Development<br />Expert One on one J2EE Development Without EJB<br />你也该看看martinfowler的Inversion of Control Containers and the Dependency Injection pattern。<br /><a href="http://www.martinfowler.com/articles/injection.html"><font color="#002c99">http://www.martinfowler.com/articles/injection.html</font></a></p><p>再好好研读一下spring的文档。<br /><a href="http://www.jactiongroup.net/reference/html/index.html"><font color="#002c99">http://www.jactiongroup.net/reference/html/index.html</font></a>（中文版，未全部翻译）<br /><br />还有就是多实践吧。</p><img src ="http://www.blogjava.net/liulu/aggbug/69521.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liulu/" target="_blank">刘璐</a> 2006-09-14 08:25 <a href="http://www.blogjava.net/liulu/archive/2006/09/14/69521.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>