﻿<?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-J2EE之巅-文章分类-Design Pattern</title><link>http://www.blogjava.net/chaocai/category/8363.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 12:16:36 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 12:16:36 GMT</pubDate><ttl>60</ttl><item><title>依赖注入（Dependency Injection）模式的特点分析与实现</title><link>http://www.blogjava.net/chaocai/articles/34913.html</link><dc:creator>超越巅峰</dc:creator><author>超越巅峰</author><pubDate>Sun, 12 Mar 2006 07:50:00 GMT</pubDate><guid>http://www.blogjava.net/chaocai/articles/34913.html</guid><wfw:comment>http://www.blogjava.net/chaocai/comments/34913.html</wfw:comment><comments>http://www.blogjava.net/chaocai/articles/34913.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chaocai/comments/commentRss/34913.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chaocai/services/trackbacks/34913.html</trackback:ping><description><![CDATA[<P align=center><B><SPAN>依赖注入（</SPAN><SPAN lang=EN-US>Dependency Injection</SPAN></B><B><SPAN>）</SPAN></B><B><SPAN>模式的特点分析与实现</SPAN></B><B></B></P>
<P align=center><B><SPAN>――构造子注入</SPAN></B><B><SPAN>（</SPAN></B><B><SPAN lang=EN-US>Constructor Injection</SPAN></B><B><SPAN>）</SPAN></B><B><SPAN>模式的分析与实现</SPAN></B><B></B></P>
<P align=center><B><SPAN lang=EN-US></SPAN></B>&nbsp;</P>
<P align=center><B><SPAN lang=EN-US></SPAN></B>&nbsp;</P>
<P align=center><SPAN>蔡</SPAN><SPAN lang=EN-US><SPAN>&nbsp; </SPAN><SPAN>超</SPAN></P>
<P align=center><SPAN>（</SPAN><SPAN lang=EN-US>chaocai2001@yahoo.com.cn</SPAN><SPAN>）</SPAN></P>
<P align=center><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P><B><SPAN>摘要</SPAN></B><SPAN>：本文对</SPAN><SPAN lang=EN-US>IoC</SPAN><SPAN>模式、依赖注入</SPAN><SPAN lang=EN-US>(Dependency Injection) </SPAN><SPAN>模式做了简要介绍，文中分析构造子注入模式与其他模式相比较的优势和特点，并给出了在</SPAN><SPAN lang=EN-US>JAVA</SPAN><SPAN>中实现该模式的方法。</SPAN></P>
<P><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P><SPAN lang=EN-US></SPAN>&nbsp;</P>
<H1><SPAN lang=EN-US><SPAN>1<SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN>引言</SPAN></H1>
<P><SPAN lang=EN-US>IoC</SPAN><SPAN>（</SPAN><SPAN lang=EN-US>Inversion of Control</SPAN><SPAN>）模式以被目前的轻量级容器所广泛应用，通过</SPAN><SPAN lang=EN-US>IoC</SPAN><SPAN>模式这些容器帮助开发者将来自不同项目的组件装配成一个内聚的应用程序。轻量级的</SPAN><SPAN lang=EN-US>IoC</SPAN><SPAN>容器（如</SPAN><SPAN lang=EN-US>Spring</SPAN><SPAN>、</SPAN><SPAN lang=EN-US>pico-container</SPAN><SPAN>）虽然为我们的开发提供了很大的便利，但是在很多情况下这些轻量级容器所提供的功能并不一定非常适合我们的需要，也许这些容器的功能过于庞大了，或者所提供的功能缺乏对特定应用的针对性，或者我们需要更高的运行效率，这时我们可以在了解</SPAN><SPAN lang=EN-US>IoC</SPAN><SPAN>的原理的基础上利用</SPAN><SPAN lang=EN-US>JAVA</SPAN><SPAN>的反射机制自己实现灵活的、可扩展的组件机制。</SPAN></P>
<H1><SPAN lang=EN-US><SPAN>2<SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US>IoC</SPAN><SPAN>与依赖注入（</SPAN><SPAN lang=EN-US>Dependency Injection</SPAN><SPAN>）模式简介</SPAN></H1>
<P><SPAN>与</SPAN><SPAN lang=EN-US>GoF</SPAN><SPAN>的设计模式相同，</SPAN><SPAN lang=EN-US>IoC</SPAN><SPAN>模式同样是关注重用性，但与</SPAN><SPAN lang=EN-US>GoF</SPAN><SPAN>模式不同的是</SPAN><SPAN lang=EN-US>IoC</SPAN><SPAN>模式更加关注二进制级的重用性和可扩展性，即可以直接通过二进制级进行扩充，复用的模块通常被称为组件或者插件，组件和插件都是在运行时进行装载的。</SPAN></P>
<P><SPAN lang=EN-US>GoF</SPAN><SPAN>的设计模式中我们大量看到的是面向接口编程：</SPAN><SPAN lang=EN-US>Interface Driven Design </SPAN><SPAN>接口驱动，接口驱动有很多好处，可以提供不同灵活的子类实现，增加代码稳定和健壮性等等，但是接口一定是需要实现的，也就是如下语句迟早要执行：</SPAN></P>
<P><SPAN lang=EN-US>AInterface a = new AInterfaceImp(); </SPAN></P>
<P><SPAN>由于以上的代码被写入了调用者程序中，同时象</SPAN><SPAN lang=EN-US>AinterfaceImp</SPAN><SPAN>这样的接口的实现类是在编译时被装载的，如果以后想加入新的接口实现类则必须修改调用者的代码。</SPAN></P>
<P><SPAN lang=EN-US>IoC</SPAN><SPAN>模式与以上情况不同，接口的实现类是在运行时被装载的，这样即使以后新添加了接口实现类是也不需修改调用者的代码（可以通过特定的方式来定位新增的实现类，如配置文件指定）。</SPAN><SPAN lang=EN-US>IoC</SPAN><SPAN>英文为</SPAN><SPAN lang=EN-US> Inversion of Control</SPAN><SPAN>，即反转模式，这里有著名的好莱坞理论：你呆着别动，到时我会找你。</SPAN></P>
<P><SPAN lang=EN-US>IoC</SPAN><SPAN>模式可以延缓接口的实现，根据需要实现，有个比喻：接口如同空的模型套，在必要时，需要向模型套注射石膏，这样才能成为一个模型实体，因此，</SPAN><SPAN>对于这些新生的容器，它们反转的是“如何定位插件的具体实现”。因此，</SPAN><SPAN> </SPAN><SPAN lang=EN-US>Martin Fowler</SPAN><SPAN lang=EN-US> </SPAN><SPAN>给这种模式起了一个形象的名称</SPAN><SPAN>“依赖注入”</SPAN><SPAN>（</SPAN><SPAN lang=EN-US>Dependency Injection</SPAN><SPAN>）</SPAN><SPAN>。<INPUT class="" id=Image1 title="" type=image src="http://chaocai.cnblogs.com/Files/chaocai/1.jpg" value=Image1><BR></SPAN></P>
<P></P>
<P align=center><SPAN>图表</SPAN> <SPAN lang=EN-US><SPAN><SPAN>1</SPAN> </SPAN><SPAN>采用</SPAN><SPAN lang=EN-US>Dependency Injection</SPAN><SPAN>前后的依赖关系变化</SPAN></P>
<P><SPAN>依赖注入的形式主要有三种，分别将它们叫做构造子注入（</SPAN><SPAN lang=EN-US>Constructor Injection</SPAN><SPAN>）、设值方法注入（</SPAN><SPAN lang=EN-US>Setter Injection</SPAN><SPAN>）和接口注入（</SPAN><SPAN lang=EN-US>Interface Injection</SPAN><SPAN>）。</SPAN></P>
<P><SPAN>这三种方式在<SPAN lang=EN-US>Martin Fowler的《</SPAN><SPAN lang=EN-US>Inversion of Control Containers and the Dependency Injection pattern</SPAN><SPAN>》中都给出了详细的定义及说明，本文就不再赘述了，下面的内容将着重介绍</SPAN><SPAN>构造子注入模式的特点及实现方法。</SPAN></P>
<H1><SPAN lang=EN-US><SPAN>3<SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN>构造子注入模式的特点及实现</SPAN></H1>
<H2><SPAN lang=EN-US><SPAN>3.1<SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN>构造子注入模式的特点</SPAN></H2>
<P><SPAN>通常情况下设</SPAN><SPAN>值</SPAN><SPAN>方法注入和接口注入较易于被开发人员接受，而构造子注入则应用较少，实际上构造子注入具有很多其他两者所不具有的优势：</SPAN></P>
<P><SPAN lang=EN-US>1 </SPAN><SPAN>构造子注入形成了一种更强的依赖契约</SPAN></P>
<P><SPAN lang=EN-US>2 </SPAN><SPAN>可以获得更加简明的代码</SPAN></P>
<P><SPAN lang=EN-US>3 </SPAN><SPAN>更加简明的依赖声明机制，无须定义</SPAN><SPAN lang=EN-US>XML</SPAN><SPAN>配置文件或设</SPAN><SPAN>值</SPAN><SPAN>方法</SPAN></P>
<P><SPAN lang=EN-US>4 </SPAN><SPAN>更加符合接口与实现分离的组件特征，组件接口表明能够向其它组件提供的服务，而实现则应该是所提供服务的实现应该与服务契约无关（即不应包含用于获得依赖的设值方法等）。</SPAN></P>
<P><SPAN lang=EN-US>5 </SPAN><SPAN>不会出现不确定的状态。在设值方法注入中，由于并不是所有的设值方法（</SPAN><SPAN lang=EN-US>setter</SPAN><SPAN>）都一定会被调用的，所以会有不确定状态。</SPAN></P>
<P><SPAN>从以上几点我们还可以分析出构造子注入对于组件代码的入侵性远小于其它两种模式</SPAN><SPAN lang=EN-US>(</SPAN><SPAN>接口注入使得组件必须实现特定接口，设值方法同样要求组件提供特定的</SPAN><SPAN lang=EN-US>setter</SPAN><SPAN>方法</SPAN><SPAN lang=EN-US>)</SPAN><SPAN>，代码更加易于维护</SPAN><SPAN>。<INPUT class="" id=Image2 title="" type=image src="http://chaocai.cnblogs.com/Files/chaocai/2.jpg" value=Image2></SPAN></P>
<P align=center></P>
<P align=center><SPAN>图表</SPAN> <SPAN lang=EN-US><SPAN><SPAN>2</SPAN> </SPAN><SPAN>示例中类的关系</SPAN></P>
<P><SPAN lang=EN-US>Client</SPAN><SPAN>的实现依赖于接口</SPAN><SPAN lang=EN-US>A</SPAN><SPAN>、</SPAN><SPAN lang=EN-US>B</SPAN><SPAN>和</SPAN><SPAN lang=EN-US>C</SPAN><SPAN>的实现，但是为了提供系统更好的灵活性和可扩展性，各接口的实现以组件的方式利用</SPAN><SPAN lang=EN-US>java</SPAN><SPAN>的反射机制进行运行时装载，注意到组件间可能会存在某种依赖关系，例如组件</SPAN><SPAN lang=EN-US>AX</SPAN><SPAN>依赖与接口</SPAN><SPAN lang=EN-US>B</SPAN><SPAN>的实现类，而这中依赖关系必须在运行时动态注入，组件为了告诉组件的调用者这种依赖关系以便注入，可以使用上文提到的各种模式：</SPAN></P>
<P><SPAN lang=EN-US>1 </SPAN><SPAN>使用接口注入模式</SPAN></P>
<P><SPAN lang=EN-US>public interface InjectB{</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public void injectB(B bImp);</SPAN></P>
<P><SPAN lang=EN-US>}</SPAN></P>
<P><SPAN lang=EN-US>public interface InjectC{</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public void injectC(C cImp);</SPAN></P>
<P><SPAN lang=EN-US>}</SPAN></P>
<P><SPAN lang=EN-US>public class AImp implements A,InjectB,InjectC{</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>…</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public void injectB(B bImp);</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public void injectC(C cImp);</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>…</SPAN></P>
<P><SPAN lang=EN-US>}</SPAN></P>
<P><SPAN lang=EN-US>2 </SPAN><SPAN>使用设值注入模式</SPAN></P>
<P><SPAN lang=EN-US>public class AImp implements A {</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>…</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public void setB(B bImp);</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public void setC(C cImp);</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>…</SPAN></P>
<P><SPAN lang=EN-US>}</SPAN></P>
<P><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P><SPAN lang=EN-US>3 </SPAN><SPAN>使用构造子注入模式</SPAN></P>
<P><SPAN lang=EN-US>public class AImp implements A {</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>…</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public AImp(B bImp, C cImp){</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>…</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>…</SPAN></P>
<P><SPAN lang=EN-US>}</SPAN></P>
<P><SPAN>由以上实例可以清楚的看出采用构造子注入模式的实现组件代码最为简单，且所受的入侵性最小。</SPAN></P>
<H2><SPAN lang=EN-US><SPAN>3.2<SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN>在</SPAN><SPAN lang=EN-US>JAVA</SPAN><SPAN>中实现构造子注入模式</SPAN></H2>
<P><SPAN>在</SPAN><SPAN lang=EN-US>java</SPAN><SPAN>及</SPAN><SPAN lang=EN-US>.NET</SPAN><SPAN>这样具有反射功能的语言中实现类型的运行时载入并不复杂，只要通过</SPAN><SPAN lang=EN-US>Class.forName</SPAN><SPAN>或生成自己的</SPAN><SPAN lang=EN-US>ClassLoader</SPAN><SPAN>就可以实现。</SPAN></P>
<P><SPAN>同样我们可以通过反射机制获取组件构造函数的参数，注入相应接口的实现，作者将此过程进行了封装，以下是代码：</SPAN></P>
<P><SPAN lang=EN-US>public class RefectHelper {</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public Object ConstructorHelper(String className,ConstructorParamDeal pd) throws Exception{</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>try{</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>//</SPAN><SPAN>获取类中的构造函数</SPAN></P>
<P><SPAN lang=EN-US>Constructor[] constructs=Class.forName(className).getConstructors();<SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>//</SPAN><SPAN>实现中默认使用第一个构造函数类创建实例</SPAN><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Class [] classes=constructs[0].getParameterTypes();<SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>//</SPAN><SPAN>获取要注入的参数实例</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Object []obj=pd.dealParam(classes);</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>//</SPAN><SPAN>创建实例</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>return constructs[0].newInstance(obj);</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}catch(Exception e){</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>throw e;</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</SPAN></P>
<P><SPAN lang=EN-US>}</SPAN></P>
<P><SPAN lang=EN-US>/**</SPAN></P>
<P><SPAN lang=EN-US>*</SPAN><SPAN>构造函数参数注入</SPAN></P>
<P><SPAN lang=EN-US>**/</SPAN></P>
<P><SPAN lang=EN-US>public interface ConstructorParamDeal {</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>/**</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>*</SPAN><SPAN>根据构造函数中参数的类型注入</SPAN><SPAN lang=EN-US>,</SPAN><SPAN>相应的实现</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>@param classes </SPAN><SPAN>构造函数的参数类型</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN>◎</SPAN><SPAN lang=EN-US>return </SPAN><SPAN>注入构造函数的参数实现</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>**/</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public Object [] dealParam(Class [] classes);</SPAN></P>
<P><SPAN lang=EN-US>}</SPAN></P>
<P><SPAN lang=EN-US>public class ParamDeal implements ConstructorParamDeal{</SPAN></P>
<P><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>/* (non-Javadoc)</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN>&nbsp;</SPAN>* @see com.topsec.tsm.agent.helper.ConstructorParamDeal#dealParam(java.lang.Class[])</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN>&nbsp;</SPAN>*/</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>public Object [] dealParam(Class[] classes) {</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Object [] obj=new Object[classes.length];</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>for (int i=0;i&lt;obj.length;i++){</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>//</SPAN><SPAN>为不同类型注入选择不同实例</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>if (classes[i].equals(String.class)){</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>obj[i]=”Hello World”;<SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>return obj;</SPAN></P>
<P><SPAN lang=EN-US><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}</SPAN></P>
<P><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P><SPAN lang=EN-US>}</SPAN></P>
<P><SPAN>上面的程序中</SPAN><SPAN lang=EN-US>ConstructorHelper</SPAN><SPAN>用于利用反射机制枚举出载入类的构造函数及构造函数的参数的类型，至于不同类型注入什么样的实例则由</SPAN><SPAN lang=EN-US>ContructorParamDeal</SPAN><SPAN>的实现者来决定，</SPAN><SPAN lang=EN-US>ContructorParamDeal</SPAN><SPAN>的实现者同样可以以组件的形式在运行时动态载入。由于组件间的依赖关系的制约，所以组件实例化的顺序需要特别考虑。</SPAN></P>
<H1><SPAN lang=EN-US><SPAN>4<SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN>结束语</SPAN></H1>
<P><SPAN>三种依赖注入模式各有其特点和优势，只有充分理解这些模式间的不同，才能为自己的应用选择正确的依赖注入模式，文中介绍的构造子注入模式实现方法，在使用其他具有反射功能的语言（如：</SPAN><SPAN lang=EN-US>.NET</SPAN><SPAN>）时同样可以参考。</SPAN></P>
<P><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P><B><SPAN lang=EN-US><SPAN>&nbsp;</SPAN>[</SPAN></B><B><SPAN>参考文献</SPAN></B><B><SPAN lang=EN-US>]</SPAN></B></P>
<P><SPAN lang=EN-US>1 </SPAN><SPAN lang=EN-US>Martin Fowler,Inversion of Control Containers and the Dependency Injection pattern,<A href="http://www.martinfowler.com/articles/injection.html"><SPAN>http://www.martinfowler.com/articles/injection.html</SPAN></A>,2004</SPAN></P>
<P><SPAN lang=EN-US>2 Erich Gamma,Design Patterns,Addison Wesley,1999</SPAN></P>
<P><SPAN lang=EN-US>3 <A href="http://www.picocontainer.org/"><SPAN>http://www.picocontainer.org/</SPAN></A></SPAN></P>
<P><SPAN lang=EN-US>4 </SPAN><SPAN lang=EN-US><A href="http://www.jdon.com/aboutme.htm"><SPAN>彭晨阳</SPAN></A>,</SPAN><SPAN lang=EN-US>Ioc</SPAN><SPAN>模式</SPAN><SPAN lang=EN-US>,</SPAN><SPAN lang=EN-US> http://www.jdon.com,2004</SPAN></P></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN><img src ="http://www.blogjava.net/chaocai/aggbug/34913.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chaocai/" target="_blank">超越巅峰</a> 2006-03-12 15:50 <a href="http://www.blogjava.net/chaocai/articles/34913.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>