??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲GV天堂无码男同在线观看,亚洲国产精品va在线播放 ,亚洲精品专区在线观看http://www.tkk7.com/alex/category/13521.html不求多得,只求一? about java,hibernate,spring,design,database,linux,etc. <br/><br/> 最q关?j)的内容关键?web快速开发方案,建模,workshop studio,Ajax zh-cnTue, 27 Feb 2007 14:56:09 GMTTue, 27 Feb 2007 14:56:09 GMT60[转]SOA实践 -- 使用IoC和AOP重构SOA应用http://www.tkk7.com/alex/archive/2006/07/28/60552.htmlAlexAlexFri, 28 Jul 2006 05:29:00 GMThttp://www.tkk7.com/alex/archive/2006/07/28/60552.htmlhttp://www.tkk7.com/alex/comments/60552.htmlhttp://www.tkk7.com/alex/archive/2006/07/28/60552.html#Feedback0http://www.tkk7.com/alex/comments/commentRss/60552.htmlhttp://www.tkk7.com/alex/services/trackbacks/60552.htmlU别: 初

易立, IBM 中国软g开发实验室 SOA设计中心(j) 高软g工程?br /> 赵勇, IBM 中国软g开发实验室 SOA设计中心(j) 高软g工程?br />

2006 q? 4 ? 20 ?/p>

在本文中Q作者通过一个Web Service讉K的实例,具体描述?jin)SOA应用中所遇到的一pd具体问题Qƈ描述如何利用IoC和AOP{技术进行代码重构,从而构建结构更加良好、灵zȝSOA应用?/blockquote>

1.引言

SOA是一U构造分布式pȝ的方法,它将业务应用功能以服务的形式提供出来Q以便更好的复用、组装和与外部系l集成,从而降低开发成本,提高开发效率。SOA的目标是Z业构Z个灵z,可扩展的IT基础架构来更好地支持随需应变的商务应用?/p>

随着SOA技术和产品的不断成熟,现在来多的用户开始了(jin)解ƈ认同SOA的理念,但对SOA目的实施还~Z信心(j)。其主要原因是:(x)SOA应用开发还相对比较复杂?/p>

一q多来,本文作者所在的部门已经从事?jin)许多国内外的SOA目的实施和支持工作Q积累了(jin)许多SOA应用开发经验。我们希望能够通过一pd的文章与读者分享这些想法,帮助(zhn)更好地构徏SOA应用?/p>

? 文将从Web Service调用入手Q在解决一pd具体问题的过E中Q用IoC (Inversion of Control) 和AOP (Aspect- Oriented Programming) {方法重构Web Service的访问代码,使得业务逻辑与Web Service讉K解耦,为?zhn)提供一个更加灵zd易于扩展的访问模式?/p>

Spring是一个流行的轻量U容器,对IoC和AOP提供?jin)良好? 支持。本文ؓ(f)(zhn)提供了(jin)一个基于Spring的实C(zhn)下载学?fn)。示例代码工E用Eclipse3.1/3.02和JDK1.4开? (zhn)还需要Spring 1.2.5和Axis1.3提供的支持。详l的下蝲信息请参见参考资源部分?/p>



回页?/b>


2.Web Service调用

Web Service是目前实现SOA应用的一基本的Q适用的技术,它ؓ(f)服务的访问提供了(jin)一个被q泛接受的开放标准。ؓ(f)?jin)便于说明问题,我们用XMethods |站Q?a >http://www.xmethods.net/Q发布的货币兑换服务作ؓ(f)CZ。ƈ针对JAX-RPC 1.1Q说明如何编写Web Service 的调用代码?/p>

2.1 CZ说明

http://xmethods.net 作ؓ(f)最早推出Web Service实际CZ的网站,提供?jin)很多优U的Web Service 样例。其中有一个汇率计服务,可以q回两个国家之间的货币兑换比例。获取该服务的详l信息,请参考该服务的服务描q文(获取WSDL 文Q?。在此就不具体解析该服务描述文?jin)。读者可以从WSDL2Java生成的接口中?jin)解该服务的用法Q?/p>
												
														
public interface CurrencyExchangePortType extends java.rmi.Remote {
public float getRate(String country1, String country2) throws java.rmi.RemoteException;
}

2.2 客户端调用方?/span>

JAX-RPC作ؓ(f)Javaq_的RPC服务调用标准接口Qؓ(f)Web Service客户端调用提供了(jin)3U方法,分别是DIIQ动态代理,和静(rn)态Stub? DIIQDynamic Invocation InterfaceQ采用直接调用方式,可以在程序中讄诸多的调用属性,使用较ؓ(f)灉|Q但是调用过E却相对J琐复杂Q易造成代码膨胀且可重用性低Q每ơ调用不同的Web Service都要重复q行大量~码?/p>

JAX-RPC中动态代理(Dynamic ProxyQ的Ҏ(gu)实现对Web Service的动态调用,可以在运行时Ҏ(gu)用户定义的Client端接口创建适配对象。从而避免了(jin)直接操作底层的接口,减少?jin)客L(fng)的冗余,屏蔽?jin)调用相关的复杂性?/p>

? 用静(rn)态Stub和Service Locator是目前最常用的调用方式。JAX-RPC使用?rn)态的Stub方式包装对底层接口的调用Q从而提供一U更为简便的调用方式。用该方式需要利 用支持环境(比如AxisQ所提供的工h据WSDL预生成Web Service客户端的实现代码。因此如果服务的WSDL发生变化Q就必须重新生成新的客户端代码ƈq行重新部v?/p>

Z(jin)更详l的?jin)解静(rn)态Stub的调用方式,(zhn)可以将CZ代码的WebServiceClient.jar导入到?zhn)现有Eclipse工作Z中?/p>

客户端生成代码包括如?个类Q如?1 所C:(x)


?1Q?客户端代码类?/b>
?1Q?客户端代码类? border=

在上图中包括的几个类中:(x)

CurrencyExchangePortTypeQ服务端Ҏ(gu)口,定义?jin)Web Service的方法签名?/p>

CurrencyExchangeServiceQService接口Q定义了(jin)获取服务端点接口的方法?/p>

CurrencyExchangeServiceLocatorQServiceLocatorc,实现?jin)Service接口?/p>

CurrencyExchangeBindingStubQ?Stub实现c,实现?jin)服务端?gu)口,装?jin)对Web Service讉K的底层逻辑?/p>

使用Stub调用Web Service的过E也非常单,读者可以参考清?1Q?/p>
清单 1QWeb Service 调用代码CZ
												
														
try {
//创徏ServiceLocator
CurrencyExchangeServiceLocator locator = new
CurrencyExchangeServiceLocator();
//讑֮端点地址
URL endPointAddress = new URL("http://services.xmethods.net:80/soap");
//创徏Stub实例
CurrencyExchangePortType stub =
locator.getCurrencyExchangePort(endPointAddress);
//讑֮时?20U?br /> ((CurrencyExchangeBindingStub)stub).setTimeout(120000);
//调用Web Service计算人民币与元的汇?br /> float newPrice = stub.getRate("China", "USA") * 100;
} catch (MalformedURLException mex) {
//...
} catch (ServiceException sex) {
//...
} catch (RemoteException rex) {
//...
}





回页?/b>


3.重构Web Service调用代码

3.1 实例代码中的"坏味?

上面的基于Service Locator的Web Service讉K代码虽然单但暴露Z下几个问题:(x)

1Q访问Web Service所需的配|代码被嵌入应用逻辑之中
在Web Service调用中,我们需要设定一pd必要的参数。比如:(x)服务端点地址、用户名/密码、超时设定等{。这些参数在开发和q行环境中都有可能发生变化。我们必L供一U机Ӟ(x)在环境变化时Q不必修Ҏ(gu)代码可以改变Web Service的访问配|?/p>

2 客户端代码与Web Service讉K代码l定
在上面的代码中,业务逻辑与Web Service的Stub创徏和配|代码绑定在一赗这也不是一U良好的~程方式。客L(fng)代码只应兛_(j)服务的接口,而不应关?j)服务的实现和访问细节。比 如,我们既可以通过Web Service的方式访问远E服务,也可以通过EJB的方式进行访问。访问方式对业务逻辑应该是透明的?/p>

q? U分dL(fng)代码与服务访问代码的方式也有利于试。这样在开发过E中Q负责集成的E序员就可能在远E服务还未完全实现的情况下,Z服务接口~写集成? 码,q过~写POJOQPlain Old Java ObjectQ构Z服务实现来进行单元测试和模拟q行。这U开发方式对于保证分布式pȝ代码质量h重要意义?/p>

因此Qؓ(f)?jin)解决上面的问题我们需要:(x)

1、将Web Service讉K的配|管理与代码分离Q?/p>

2、解除客L(fng)代码与远E服务之间的依赖关系Q?/p>

3.2 利用IoC模式q行重构代码

? 们先介绍在Core J2EE Patterns一书中提到的一U业务层模式QBusiness Delegate。它所要解决的问题是屏蔽远E服务访问的复杂性。它的主要思想是Business Delegate作ؓ(f)q程服务的客L(fng)抽象Q隐藏服务访问细节。Business Delegateq可以封装ƈ改变服务调用q程Q比如将q程服务调用抛出的异常(例如RemoteExceptionQ{换ؓ(f)应用U别的异常类型?/p>

其类囑֦?2 所C:(x)


?2QBusiness Delegate 模式的类囑֛?/b>
?2QBusiness Delegate 模式的类囑֛? border=

Business Delegate模式实现很好地实C(jin)客户端与q程讉K代码的解耦,但它q不xDelegate与远E服务之间的解耦。ؓ(f)?jin)更好解决Business Delegate和远E服务之间的依赖关系Qƈ更好地进行配|管理,我们可以用IoC模式来加以解冟?/p>

IoCQInversion of ControQl意ؓ(f)控制反{Q其背后的概念常被表qCؓ(f)"好莱坞法?Q?Don't call me, I'll call you." IoC一部分责Q从应用代码交lframeworkQ或者控制器Q来做。通过IoC可以实现接口和具体实现的高度分离Q降低对象之间的耦合E度? Spring是一个非常流行的IoC容器Q它通过配置文g来定义对象的生命周期和依赖关p,q提供了(jin)良好的配|管理能力?/p>

现在我们来重构我们的Web Service应用E序Q我们首先ؓ(f)Business Delegate定义一个接口类型,它提供了(jin)一个应用lg接口Q所有客L(fng)都应通过它来执行汇率计算Q而不必关?j)实现细节,如清?2 所C:(x)


清单 2Q接口定义的代码CZ
												
														

Public interface CurrencyExchangeManager {
//货币兑换计算
//Ch(hun)?= 汇率 * h
public float calculate(String country1, String country2, float price)
throws CurrencyExchangeException;
}

Business Delegate的实现非常简单,主要工作是包装汇率计?Web Service的调用,如清?3 所C?/p>
清单 3QBusiness Delegate的代码示?/b>
												
														
public class CurrencyExchangeManagerImpl implements CurrencyExchangeManager {
//服务实例
private CurrencyExchangePortType stub;
//获取服务实例
public CurrencyExchangePortType getStub() {
return stub;
}
//讑֮服务实例
public void setStub(CurrencyExchangePortType stub) {
this.stub = stub;
}
//实现货币兑换
public float calculate(String country1, String country2, float price)
throws CurrencyExchangeException {
try {
//通过Stub调用WebService
float rate = stub.getRate(country1, country2);
return rate * price;
} catch (RemoteException rex) {
throw new CurrencyExchangeException(
"Failed to get exchange rate!", rex);
}
}
}

下面我们需要讨论如何利用Spring的IoC机制Q来创徏和配|对象,q定义它们的依赖关系?/p>

Spring 利用cd厂来创徏和配|对象。在Spring框架中,已经为基于JAXQRPC的Web Service调用提供?jin)一个客L(fng)代理的类工厂实现QJaxRpcPortProxyFactoryBean。在配置文gbean.xml中,我们 用JaxRpcPortProxyFactoryBean来创建和配置Web Service的客L(fng)代理"CurrencyExchangeService"Q如清单 5 所C。我们还定义一个名?CurrencyExchangeManager"的CurrencyExchangeManagerImpl实例Qƈ建立 它与CurrencyExchangeService之间的依赖关pR有关Spring 配置和JaxRpcPortProxyFactoryBean的用细节请参见参考资料?/p>
清单 5Qbean.xml的配|文?/b>
												
														

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="CurrencyExchangeService"
class="org.springframework.remoting.jaxrpc.JaxRpcPortProxyFactoryBean">
<property name="serviceInterface">
<value>net.xmethods.www.sd.CurrencyExchangeService_wsdl.
CurrencyExchangePortType</value>
</property>
<property name="wsdlDocumentUrl">
<value>http://www.xmethods.net/sd/2001/CurrencyExchangeService.
wsdl</value>
</property>
<property name="namespaceUri">
<value>http://www.xmethods.net/sd/CurrencyExchangeService.
wsdl</value>
</property>
<property name="serviceName">
<value>CurrencyExchangeService</value>
</property>
<property name="portName">
<value>CurrencyExchangePort</value>
</property>
<property name="endpointAddress">
<value>http://services.xmethods.net:80/soap</value>
</property>
</bean>
<bean id="CurrencyExchangeManager"
class="test.ws.CurrencyExchangeManagerImpl">
<property name="stub">
<ref bean="CurrencyExchangeService"/>
</property>
</bean>
</beans>

最后我们创Z个测试程序来验证我们的代码,如清? 所C:(x)


清单 6Q测试代?/b>
												
														

public class Main {
// For test only
public static void main(String[] args) {
// Spring Framework根据配|文件创建ƈ配置CurrencyExchangeManager实例
ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml");
// 获取CurrencyExchangeManager实例
CurrencyExchangeManager manager = (CurrencyExchangeManager) ctx
.getBean("CurrencyExchangeManager");
try {
System.out.println(manager.calculate("China", "USA", 100));
System.out.println(manager.calculate("China", "Japan", 200));
System.out.println(manager.calculate("China", "USA", 200));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

此时q行试客户端,{待片刻会(x)看见试l果Q如清单 7 所C:(x)


清单 7Q测试结果?/b>
												
														
12.34
2853.26
24.68

注:(x)该结果会(x)随着汇率的变化而出C同的倹{?/p>

该程序的cd和顺序图如图3?qing)?所C:(x)


?3Q示例程序的cd
?3Q示例程序的cd

? 上面的类图我们可以看刎ͼ我们的测试程序(Main.javaQ通过Spring框架获取?jin)BusinessDelegate的实例。而且Spring 框架q会(x)Ҏ(gu)配置中的依赖关系Q在q行时将Web Service的客L(fng)代理" 注射"到CurrencyExchangeManagerImpl实例中,q就是依赖注入(Dependency InjectionQ。通过q种方式解决?jin)应用逻辑和BusinessDelegate之间的依赖关p,以及(qing)BusinessDelegate的实Cq程服务之间的依赖关p,如图 4 所C?/p>
?4: CZE序的顺序图
?4:  CZE序的顺序图

Spring 框架提供的ApplicationContext实现?x)根据配|文件中的描qC息来实现对象生命周期理Q配|管理以?qing)依赖管理等功能。这一切对于应用程 序是透明的,应用E序代码只依赖接口进行编E,而无需考虑其它复杂问题。无论是Web Service的配|发生变化,或是改用不同的服务实现时Q都不会(x)对客L(fng)应用代码的生媄(jing)响。这很好地实C(jin)业务逻辑与Web Service调用之间的解耦?/p>

3.3 构徏自己?Web Service代理工厂

Spring 所提供的JaxRpcPortProxyFactoryBean装?jin)构造Web Service客户端代理的l节Q可以通过参数配置来创建Dynamic Proxy和DIIcd的Web Service客户端代理。(如果(zhn)希望深入了(jin)解其实现l节可以参考org.springframework.remoting.jaxrpc包下的源? 码。)(j)但由于JaxRpcPortProxyFactoryBean需要用者对WSDL中PortQServiceQ名I间{概忉|深入的了(jin)解;而且? 果Web Service使用?jin)复杂数据类型,开发h员需要手工定义类型映代码。所以JaxRpcPortProxyFactoryBeanq不适合Web Service的初学者来使用?/p>

Z(jin)q一步简化Web Service代理的创建,q帮助读者更好地理解cd厂在Spring框架下的作用。我们提供了(jin)一个基于静(rn)态Stub的Web Service客户端代理工厂实现。其核心(j)代码非常单,是通过ServiceLocator提供的方法来创徏Web Service客户端代理?/p>

其主要代码如清单8所C:(x)


清单8Q静(rn)态代理工厂的代码
												
														
public class WebServiceStubFactoryBean implements FactoryBean,
InitializingBean {
private Class serviceInterface;
private Class serviceLocator;
private Object stub;
?br /> public void afterPropertiesSet() throws Exception {
//利用serviceLocator和服务接口创建Web Service客户端代?br /> stub = ((javax.xml.rpc.Service)
serviceLocator.newInstance()).getPort(serviceInterface);
//为Stub讑֮endpointAddressQusernam, 时{参?br /> preparePortStub((javax.xml.rpc.Stub) stub);
}
public Object getObject() {
// q回客户端代?br /> return stub;
}
public Class getObjectType() {
// q回服务接口
return serviceInterface;
}
public boolean isSingleton() {
return true;
}
}

我们需要修攚w|文件bean.xml中有关Web Service代理创徏的部分,让新的Web Service 代理工厂发挥作用。如清单9所C:(x)


清单9Q修改后的bean.xml的配|文?/b>
												
														

<bean id="CurrencyExchangeService" class="test.ws.WebServiceStubFactoryBean">
<property name="serviceInterface">
<value>net.xmethods.www.sd.CurrencyExchangeService_wsdl.CurrencyExchangePortType</value>
</property>
<property name="serviceLocator">
<value>net.xmethods.www.sd.CurrencyExchangeService_wsdl.CurrencyExchangeServiceLocator</value>
</property>
<property name="endpointAddress2">
<value>http://services.xmethods.net:80/soap</value>
</property>
<property name="timeout">
<value>120000</value>
</property>
</bean>

得益于Spring框架Q虽然我们已l替换了(jin)对象的类工厂Q却q不需要更改应用代码。通过Spring框架的IoC机制Q我们可以完全用面向接口的~程方式Q而将实现的创建、配|和依赖理交由Spring在运行时完成。即使实现发生了(jin)变化Q也不需要改变应用程序结构?/p>



回页?/b>


4.新的思?/span>

故事q没有结束,在开发过E中Q我们又遇到?jin)一pd关于Web Service调用的问题?/p>

4.1性能

p? l性能是分布式应用中的一个重要问题。许多用户都担心(j)由Web Service技术所引入的额外开销是否?x)?jing)响到产品的性能。随着技术的不断发展QW(xu)eb Service引擎性能已经有了(jin)很大提高Q一般来说用Web Service的系l的性能可以满l大部分应用的需求。但在特定情况下Q如果系l性能无法满客户需求,我们首先需要对pȝ性能q行U学地分析和定? 能定位真正的性能瓉。这个问题在上文单的CZ中ƈ不难解决Q只需要在Web Service调用前后加入日志代码记录调用旉卛_实现。但在实际系l中Q比如一个品目录的Web Service可能提供数十U查询方法,而程序中很多lg都会(x)依赖于该服务提供的查询功能。如果在pȝ中所有的地方加入性能定代码Q这个工作就变得非常 J琐和困难。我们需要用一U更加优雅的解决方式Q在增添新功能的同时q不影响pȝ代码或结构?/p>

4.2~存

? 目实践中,一个有效的改善Web Servicepȝ性能的方法就是利用缓存来减少Web Service的重复调用。在具体实现中我们可以采用客L(fng)~存和服务器端缓存等不同方式Q他们具有不同的特点和适用范围。在本文例子中,我们希望实现? L(fng)~存来提高系l性能。但׃Web Service业务逻辑的差别,我们希望能够为特定的Web Service提供特定的缓存策略,而且q些{略应该是能够被灉|配置的,它们不应于应用程序的逻辑代码耦合在一赗?/p>

4.3故障恢复Q?/span>

? 于Web Service应用Q系l的可用性也是一个需要考虑的重要问题。在q行时由于网l运行环境的复杂性和不确定性,用户希望能够对Web Service讉K提供一定的故障恢复机制Q比如重试或者访问备份服务(当系l在调用Web Servicep|后,使用备䆾W(wng)eb Service的服务地址来l访问)(j)。这些故障恢复策略应该是可配|的Q对应用逻辑透明的?/p>



回页?/b>


5.使用AOP解决SOA应用中的Crosscutting Concern

通过对上边一pd问题的分析,读者也怼(x)发现q些问题q不是Web Service讉K的核?j)问题,但?x)影响pȝ中许多不同的lg。而且其中一些问题需要我们能够灵z配|不同的实现{略Q因此我们不应该处理这些问题的代码与应用代码؜合?/p>

? 面我们将利用AOPQAspect-Oriented ProgrammingQ提供的Ҏ(gu)来解决上q的问题。AOP是一U新兴的Ҏ(gu)学,它最基本的概念就是关注隔(Separation of ConcernQ。AOP提供?jin)一pd的技术得我们能够从代码中分那些媄(jing)响到许多pȝ模块的crosscutting concernsQƈ他们模块化为Aspects。AOP的主要目的仍然是解耦,在分d注点后,才能关注点的变更控制一定范围内Q增加程序的灉| 性,才能使得x能够Ҏ(gu)需求和环境作出随时调整?/p>

我们利用Spring所提供的AOP功能支持来解决以上问题。这里我们只单地介绍涉及(qing)到的AOP基本概念以及(qing)实现Q如果?zhn)希望更好C(jin)解AOP的概念以?qing)Spring AOP支持的细节请参见参考资料?/p>

  • Joinpoint 是程序的q行炏V在Spring AOP中,一个Joinpoint对应着一个方法调用?/li>
  • Advice 定义?jin)AOP框架在特定的Joinpoint的处理逻辑。Spring AOP框架通过interceptor方式实现?jin)adviceQƈ且提供了(jin)多种advicecd。其中最基本?around advice"?x)在一个方法调用之前和之后被执行?/li>

下面我们利用Spring提供的MethodInterceptor来ؓ(f)Web Service调用实现我们的定义的处理逻辑?/p>

5.1 PerformanceMonitorInterceptor

性能量是AOP最单的例子之一Q我们可以直接利用Spring提供的实现在bean.xml中声明我们的WebServicePerformanceMonitorInterceptor?/p>

5.2 CacheInterceptor

? ?jin)不引入~存{略的复杂性,我们只提供了(jin)一个利用HashMap的简单实玎ͼ(x)它利?Web Service的调用参数列表作为HashMap键倹{在Web Service调用之前Q首先检查缓存中是否拥有与现在参数列表相同的,如果有则q回~存的结果,否则调用Web Serviceq将<参数列表Q结?gt;记录在HashMap中。在实际应用中,(zhn)应该根据具体情冉|选择、构造适合Web Service的业务特性的Cache实现Q也可以采用成熟的Cache实现?/p>

在下面代码实C有一个生成Web Service调用主键的小技巧。因为Web Service引擎要求所有调用参数必L可序列化的,所以我们可以利用Java提供的序列化功能来实现对象的克隆。如清单10所C:(x)


清单10QSimpleCacheInterceptor的代码示?/b>
												
														

public class SimpleCacheInterceptor implements MethodInterceptor {
private Map cache = new HashMap();
private Object cloneObject(Object obj) throws Exception {
Object newObj = null;
if (obj != null) {
// 通过序列?反序列化来克隆对?br /> ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(obj);
out.flush();
out.close();
ObjectInputStream in = new ObjectInputStream(
new ByteArrayInputStream(bos.toByteArray()));
newObj = in.readObject();
}
return newObj;
}
//Z参数列表数组Q生成用于HashMap的键?br />public Object generateKey(Object[] args) throws Exception {
Object[] newArgs = (Object[]) cloneObject(args);
List key = Arrays.asList(newArgs);
return key;
}
//实现使用~存技术的invokeҎ(gu)
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
Object result = null;
Object data = null;
Object key = null;

try {
key = generateKey(methodInvocation.getArguments());
data = cache.get(key);
} catch (Exception ex) {
logger.error("Failed to find from the cache", ex);
}

if (data == null) {
//如果Cache中没有缓存结果,调用服务执行生成用于HashMap的键?br /> result = methodInvocation.proceed();
try {
data = cloneObject(result);
cache.put(key, data);
} catch (Exception ex) {
logger.error("Failed to cache the result!", ex);
}
} else {
result = data;
}
return result;
}
}

5.3 FailoverInterceptor

下面代码提供?jin)一个基于服务备份切换的故障恢复实现Q在q行Ӟ如果Interceptor(g)到服务调用׃|络故障抛出异常Ӟ它将使用备䆾服务的端点地址q新调用。如清单11所C:(x)


清单 11Q?SimpleFailoverInterceptor的代码示?/b>
												
														

public class SimpleFailoverInterceptor implements MethodInterceptor { ?br /> ?br /> //实现支持端点q行时切换的invokeҎ(gu)
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
Object result = null;
try {
result = methodInvocation.proceed();
} catch (Throwable ex) {
if (isNetworkFailure(ex)) {
//切换服务端点地址
switchEndPointAddress((Stub) methodInvocation.getThis());
result = methodInvocation.proceed();
} else {
throw ex;
}
}
return result;
}
}

Z(jin)支持备䆾服务切换的功能,我们在WebServicePortProxyFactoryBean中ؓ(f)填加?jin)配|参?endpointAddress2"Q它?x)在创徏的Web Service客户端代理对象中记录备䆾URL?/p>

? 们可以在CurrencyExchangeService加入下列参数来试验SimpleFailoverInterceptor的功能。其中第一个端? 地址Z个错误的URL。在W一ơ调用服务时QSimpleFailoverInterceptor?x)侦到|络故障的发生,q自动切换用第二个端点? 址l箋讉K。如清单12所C:(x)


清单12Q配|文件种增加的属?/b>
												
														


<property name="endpointAddress">
<value>http://localhost/wrong_endpoint_address</value>
</property>
<property name="endpointAddress2">
<value>http://services.xmethods.net:80/soap</value>
</property>

5.4配置文g和运行结?/span>

? 在我们需要在Spring配置文g中,为所有interceptord定义Qƈ描述如何为CurrencyExchangeService构徏AOP Proxy。需要指出的是,我们要在interceptorName列表中声明interceptor铄调用序Q还要将原有 CurrencyExchangeManager引用的stub对象替换为新AOP Proxy。如清单13所C:(x)


清单13Q修改后的配|文件片D?/b>
												
														


<bean id="WebServicePerformanceMonitorInterceptor"
class="org.springframework.aop.interceptor.PerformanceMonitorInterceptor">
<property name="prefix">
<value>Web Service </value>
</property>
<property name="suffix">
<value></value>
</property>
</bean>
<bean id="CacheInterceptor" class="test.ws.SimpleCacheInterceptor"/>
<bean id="FailoverInterceptor" class="test.ws.SimpleFailoverInterceptor"/>
<bean id="CurrencyExchangeProxy"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>net.xmethods.www.sd.CurrencyExchangeService_wsdl.
CurrencyExchangePortType</value>
</property>
<property name="target">
<ref local="CurrencyExchangeService"/>
</property>
<property name="interceptorNames">
<list>
<value>WebServicePerformanceMonitorInterceptor</value>
<value>CacheInterceptor</value>
<value>FailoverInterceptor</value>
</list>
</property>
</bean>
<bean id="CurrencyExchangeManager"
class="test.ws.CurrencyExchangeManagerImpl">
<property name="stub">
<ref bean="CurrencyExchangeProxy"/>
</property>
</bean>

q里我们通过为AOP 的ProxyFactoryBean?Web Service Stub创徏?jin)一个AOP代理Qƈ且徏立了(jin)一个Interceptor链。这样在调用Web ServiceӞSpring框架?x)依ơ调用Interceptor执行。实例执行的序囑ְ如图5所C:(x)


?pȝq行序?/b>
?pȝq行序? border=

5.5 Interceptor与JAX-RPC Handler的关pM区别

SOAP Message Handler是JAX-RPC为用戯定义Web Service处理q程提供的一U扩展机制。在处理Web Serviceh/响应q程中,W(xu)eb Service 引擎?x)根据部|描qC的定义,按照一定的ơ序调用Handler的处理代码。用L(fng)写的Handler实现可以截获q修改Web Service消息和处理流E,从而实现对Web Service引擎处理行ؓ(f)的定制和增强?/p>

比如Q我们可以实C个服务器端HandlerQ记录Web Service在受到请求消息和发出响应消息之间的时间间隔来实现Ҏ(gu)务器端业务性能的测定。而且我们只需在部|描qC增加Handler声明卛_Q无需修改M服务器端代码?/p>

? 此可以看出,JAX-RPC Handler与我们在上文中所提供的AOP Interceptor都可以帮助我们的SOA应用E序实现x分离QSeparate ConcernQ的目标Q在不改变应用代码的同时Q增强或改变Web Service服务讉K的功能。虽然我们可以利用它们实C些类似的功能Q但它们h着不同的特点和适用范围?/p>

JAX-RPC Handler是Web Service引擎的扩展机制。如果我们需要实现对SOAP消息q行的修改和处理Q加入自定义的SOAP Header或对消息内容q行加密QHandler是我们的最佳选择。而AOP是针对对象别的扩展机制Q它更适合对应用层逻辑q行操作?/p>

? 如,我们在上文展C的利用AOP实现的CacheInterceptorQ它~存的是Web Service调用参数和结果。而我们也可以通过JAX-RPC Handler实现一个面向SOAP消息的实玎ͼ它将~存Web Service的请求消息和响应消息。这两个实现相比Q基于AOP的实现更加简单、直观、快速、对资源消耗也比较?yu)。而面向SOAP消息的实现则更加? z,对于不采用RPC方式的Web Service讉K也能提供支持?/p>

所以在具体的实践过E中Q开发h员应该根据具体的需求选择合适的技术,也可以将q两U技术结合用?/p>



回页?/b>


6.ȝ

"分而治?的方法是Z解决复杂问题的一U常见做法。而IoC、AOP{技术都体现?jin)这U思想。通过更好的切分程序逻辑Q得程序结构更加良好,更加富有Ҏ(gu),易于变化。也使得开发h员可以更加专注于业务逻辑本nQ而将一部分其他逻辑交给容器和框架进行处理?/p>

在本文中Q我们通过一个Web Service讉K的实例,具体描述?jin)SOA应用中所遇到的一pd具体问题Qƈ描述如何利用IoC和AOP{技术进行代码重构,构徏更加l构良好、灵zȝSOA应用。综上所qͼ我们可以看到Q?/p>

1使用IoC框架来实现对象的生命周期理、配|管理和依赖理Q可以解除业务逻辑Ҏ(gu)务调用的依赖关系Q?/p>

2 使用AOPҎ(gu)来解决Web Service调用中的crosscutting concernsQ将为系l增加新的功能而不必更改应用程序?/p>

3通过IoC和AOP来屏蔽Web Service讉K的复杂性,使得开发h员可以更加专注于业务逻辑本nQ也使得pȝ更加E_和富有弹性?/p>




回页?/b>


下蝲

描述 名字 大小 下蝲Ҏ(gu)
code sample code.zip 27 KB HTTP
关于下蝲Ҏ(gu)的信?/a> Get Adobe] Reader]




回页?/b>


参考资?





回页?/b>


作者简?/span>


易立 IBM 中国软g开发实验室 SOA设计中心(j) 高软g工程师?/p>



赵勇 IBM 中国软g开发实验室 SOA设计中心(j) 软g工程师?/p>



Alex 2006-07-28 13:29 发表评论
]]>[转]Z么现在要选择SOAQ?/title><link>http://www.tkk7.com/alex/archive/2006/07/28/60522.html</link><dc:creator>Alex</dc:creator><author>Alex</author><pubDate>Fri, 28 Jul 2006 03:29:00 GMT</pubDate><guid>http://www.tkk7.com/alex/archive/2006/07/28/60522.html</guid><wfw:comment>http://www.tkk7.com/alex/comments/60522.html</wfw:comment><comments>http://www.tkk7.com/alex/archive/2006/07/28/60522.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/alex/comments/commentRss/60522.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/alex/services/trackbacks/60522.html</trackback:ping><description><![CDATA[key words: SOA<br /><br />come from <a >here</a><br /><h1><span style="font-size: 10pt; font-family: ˎ̥; color: rgb(51, 51, 51);" lang="EN-US">2004</span><span style="font-size: 10pt; font-family: 宋体; color: rgb(51, 51, 51);">q?/span><span style="font-size: 10pt; font-family: ˎ̥; color: rgb(51, 51, 51);" lang="EN-US">5</span><span style="font-size: 10pt; font-family: 宋体; color: rgb(51, 51, 51);">?/span><span style="font-size: 10pt; font-family: ˎ̥; color: rgb(51, 51, 51);" lang="EN-US">12</span><span style="font-size: 10pt; font-family: 宋体; color: rgb(51, 51, 51);">?/span><span style="font-size: 10pt; font-family: ˎ̥; color: rgb(51, 51, 51);"></span><span style="font-size: 10pt; font-family: 宋体; color: black;">据业内分析,面向服务的架构(</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">Q的基本概念</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">--</span><span style="font-size: 10pt; font-family: 宋体; color: black;">重用性和互用?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">--</span><span style="font-size: 10pt; font-family: 宋体; color: black;">已经提出?jin)大U?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">20</span><span style="font-size: 10pt; font-family: 宋体; color: black;">q。那?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">h哪些新的特色呢?Z么其他技术和标准都惨遭失败,?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">却能够成功呢Q?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">BEA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">的首席信息官</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">Rhonda Hocker</span><span style="font-size: 10pt; font-family: 宋体; color: black;">回答?jin)有?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">如何发挥</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">IT</span><span style="font-size: 10pt; font-family: 宋体; color: black;">潜力斚w的问题?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><o:p></o:p></span></h1><p class="MsoNormal"><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><br /></span><span style="font-size: 10pt; font-family: 宋体; color: rgb(204, 0, 0);">问:(x)</span><span style="font-size: 10pt; font-family: 宋体; color: black;">(zhn)认?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">的哪些方面在其成功中起到?jin)至关重要的作用Q?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><br /><br /></span><span style="font-size: 10pt; font-family: 宋体; color: rgb(204, 0, 0);">{:(x)</span><span style="font-size: 10pt; font-family: 宋体; color: black;">W一点就是灵zL。就长期以来在广大公怸的知名度而言Q?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">可能名列</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">IT</span><span style="font-size: 10pt; font-family: 宋体; color: black;">架构W一Q而内容一直在变化。一?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">实质上就是一套松散耦合的服务。在必要的情况下Q每一Ҏ(gu)务都可以q行构造和替换Q而相关的费用很低。松散耦合甚至q可以让架构适应一些改变,q不像传l的紧耦合架构表现得那么脆弱;在一?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">中,(zhn)能够用一U服务替换另一U服务,无需考虑下列技术:(x)接口问题Q它是否?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">Web</span><span style="font-size: 10pt; font-family: 宋体; color: black;">服务?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">XML</span><span style="font-size: 10pt; font-family: 宋体; color: black;">的通用标准中已l定义。这是通过互用性所体现出来的灵zL。灵zL还表现为利用现有资产、遗留应用程序和数据库的能力Q通过他们扩展到</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">中,而非q行替换Q其成为整个企业解x案的l成部分。最l结果就是具备快速高效发展的能力Q换句话_(d)是按照业务需?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">"</span><span style="font-size: 10pt; font-family: 宋体; color: black;">有机?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">"</span><span style="font-size: 10pt; font-family: 宋体; color: black;">q行适应。这是真正的新特色?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><br /><br /></span><span style="font-size: 10pt; font-family: 宋体; color: black;">W二点就?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">"</span><span style="font-size: 10pt; font-family: 宋体; color: black;">业务相关?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">"</span><span style="font-size: 10pt; font-family: 宋体; color: black;">Q?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">是最l表Cؓ(f)对业务h员意义重大这一层面上的</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">IT</span><span style="font-size: 10pt; font-family: 宋体; color: black;">架构。如果?zhn)也相?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">IT</span><span style="font-size: 10pt; font-family: 宋体; color: black;">架构的核?j)问题就是业务?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">IT</span><span style="font-size: 10pt; font-family: 宋体; color: black;">专家的联盟和协作Q那么这是关键。今天的</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">服务能够完成映射Z务流E活动的各部分工作:(x)例如Q想起一个命名ؓ(f)</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">"</span><span style="font-size: 10pt; font-family: 宋体; color: black;">更新客户订单状?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">"</span><span style="font-size: 10pt; font-family: 宋体; color: black;">的服务。这U服务与那些能够参与创造和使用q些服务定义新流E的业务分析人员密切相关Q因而能够Ş成那U服务驱动型的企业。因?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">Web</span><span style="font-size: 10pt; font-family: 宋体; color: black;">服务已将其大部分技术作?jin)摘要,所以几乎不再需要技术说明。公司和</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">IT</span><span style="font-size: 10pt; font-family: 宋体; color: black;">业能够将x的重点{Ud业务逻辑和通讯上。他们最l共?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">"</span><span style="font-size: 10pt; font-family: 宋体; color: black;">服务</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">"</span><span style="font-size: 10pt; font-family: 宋体; color: black;">的通用语言。也是_(d)是真正的新特Ԍ?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">IT</span><span style="font-size: 10pt; font-family: 宋体; color: black;">架构的交付中h深刻的蕴c(din)?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><br /><br /></span><span style="font-size: 10pt; font-family: 宋体; color: rgb(204, 0, 0);">问:(x)</span><span style="font-size: 10pt; font-family: 宋体; color: black;">(zhn)认Z么是</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">成功的最大障呢Q?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><br /></span><span style="font-size: 10pt; font-family: 宋体; color: rgb(204, 0, 0);">{:(x)</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">是新?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">IT</span><span style="font-size: 10pt; font-family: 宋体; color: black;">架构的蓝图。由于L伴随着大的变化发生Q因此最大的障碍是l织Q而非技术。主要包括以下几个方面:(x)</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><br /><br /></span><span style="font-size: 10pt; font-family: 宋体; color: black;">理Q共享服务是</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">Ҏ(gu)的核?j)。这U快速组装应用或~排程的能力是在一些现有的能被׃n的服务的基础上实现的。共享资源需要进行管理?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><br /><br /></span><span style="font-size: 10pt; font-family: 宋体; color: black;">开发文化:(x)切换?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">要求开发风格发生极大的变化。大多数开发h员仍焉应那种每一个应用程序作Z个独立的问题解决的方式。目前可以重用的代码q非常少。在</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">中,开发h员需要编写自q应用E序Q同时还要留意要让自q写的代码可以重用Q不仅包括用现有代码,q要包括计划在未来的应用E序中重用他们的代码?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><br /><br /></span><span style="font-size: 10pt; font-family: 宋体; color: black;">业务程架构技能:(x)</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">Ҏ(gu)让公司和</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">IT</span><span style="font-size: 10pt; font-family: 宋体; color: black;">合作伙伴能够在业务流E的创造中完成更高效率的协同工作。他们的成功有赖于其实施业务流E架构的技能。也需要他们灵zd对业务流Eƈ且要自q作是业务程架构设计师?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><br /><br /></span><span style="font-size: 10pt; font-family: 宋体; color: black;">q些斚w的确都具有极大的挑战性,但是便于理。最后,那些善于理Q?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">IT</span><span style="font-size: 10pt; font-family: 宋体; color: black;">和业务h员知道如何有效合作,程和架构技能受到重视的公司会(x)从自w的</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">中得到更多的回报。这几乎是最好的方式Q它有助于解?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">IT </span><span style="font-size: 10pt; font-family: 宋体; color: black;">问题?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><br /><br /></span><span style="font-size: 10pt; font-family: 宋体; color: rgb(204, 0, 0);">问:(x)</span><span style="font-size: 10pt; font-family: 宋体; color: black;">现在?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">与以前的集成</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">/</span><span style="font-size: 10pt; font-family: 宋体; color: black;">q通标准,?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">CORBA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">有哪些不同之处?</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><br /><br /></span><span style="font-size: 10pt; font-family: 宋体; color: rgb(204, 0, 0);">{:(x)</span><span style="font-size: 10pt; font-family: 宋体; color: black;">很好Q我会(x)用案例说明以上我所描述的两?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">有别于其他标准的优点。问题是Z么分布式架构中的</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">CORBA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">和其他方法无法表现出q些优点呢?</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><br /></span><span style="font-size: 10pt; font-family: 宋体; color: black;">高度概括性的回答是Q?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">CORBA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">h更大的技术难度,在其执行q程中需要强大的技能和知识支持。那些技能十分乏,如果没有真正?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">CORBA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">标准会(x)无济于事。而比较而言Q?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">单,Z真正通用的标准。这q保了(jin)构造它们的q些技能是q泛可用的?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><br /><br /></span><span style="font-size: 10pt; font-family: 宋体; color: black;">更ؓ(f)详细的回{请(zhn)查看他们的架构Ҏ(gu)和原理的基本差别?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><br /><br /></span><span style="font-size: 10pt; font-family: 宋体; color: black;">在一?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">中,分布式资产就?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">"</span><span style="font-size: 10pt; font-family: 宋体; color: black;">_粒?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">"</span><span style="font-size: 10pt; font-family: 宋体; color: black;">服务Q它可以完成一些非常有用的功能Q如</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">"</span><span style="font-size: 10pt; font-family: 宋体; color: black;">更新客户订单状?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">"</span><span style="font-size: 10pt; font-family: 宋体; color: black;">。?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">CORBA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">Q分布式资񔞮是一些对象,每个对象都拥有自q属性和Ҏ(gu)。例如,订单对象h</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">"</span><span style="font-size: 10pt; font-family: 宋体; color: black;">状?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">"</span><span style="font-size: 10pt; font-family: 宋体; color: black;">属性和</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">"</span><span style="font-size: 10pt; font-family: 宋体; color: black;">更新</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">"</span><span style="font-size: 10pt; font-family: 宋体; color: black;">Ҏ(gu)。这样对架构设计师而言是相当繁琐的Q它需要具有很高水q的知识和技能。在q种l粒度别之下很难保证一致性。而?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">Q会(x)控制和动力,却易于管理。这U方法在技术上q不是非常强大,但在</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">IT</span><span style="font-size: 10pt; font-family: 宋体; color: black;">成功斚w的组l和人员角色上却体现Z(jin)相当的敏捷度?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><br /><br /></span><span style="font-size: 10pt; font-family: 宋体; color: rgb(204, 0, 0);">问:(x)</span><span style="font-size: 10pt; font-family: 宋体; color: black;">Z?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">?x)成功?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">CORBA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">?x)导致失败呢Q?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><br /><br /></span><span style="font-size: 10pt; font-family: 宋体; color: rgb(204, 0, 0);">{:(x)</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">?x)成功主要取决于合作伙伴的帮助。就重用效率或企业广泛一致性而言Q由中心(j)</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">IT</span><span style="font-size: 10pt; font-family: 宋体; color: black;">l织独立推动的架构都无法在长旉的运行中获得成功。我认ؓ(f)使用</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">Q我们将?x)拥有第一个业务合作伙伴帮助推动企业架构的实例。这不是因ؓ(f)他们喜欢架构本nQ而是因ؓ(f)他们的支持是Z</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">的业务相x的Q很快就可以从结果上看出Q开发生命周期改变了(jin)它的重点Q由原来较长的交付周期应用程序的交付转变成小单元代码</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">--</span><span style="font-size: 10pt; font-family: 宋体; color: black;">服务的交付和集成。持l的l果业务合作伙伴效忠于这U方法?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><br /><br /></span><span style="font-size: 10pt; font-family: 宋体; color: rgb(204, 0, 0);">问:(x)</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">Java</span><span style="font-size: 10pt; font-family: 宋体; color: black;">?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">的潜在成功中起到?jin)什么作用?</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US"><br /><br /></span><span style="font-size: 10pt; font-family: 宋体; color: rgb(204, 0, 0);">{:(x)</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">Java</span><span style="font-size: 10pt; font-family: 宋体; color: black;">作ؓ(f)实现服务的最行的编E标准,是非帔R要的?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">Java</span><span style="font-size: 10pt; font-family: 宋体; color: black;">C֌的规模和技能保证大量高质量的技能可以用于构?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">。这是</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">Java</span><span style="font-size: 10pt; font-family: 宋体; color: black;">实现帮助</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">成功的方式。也是_(d)</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">Java</span><span style="font-size: 10pt; font-family: 宋体; color: black;">只是实现服务的一U方式。没有一个大?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">IT</span><span style="font-size: 10pt; font-family: 宋体; color: black;">l织?x)只q作一个单一的编E标准。有利的斚w是使用</span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">SOA</span><span style="font-size: 10pt; font-family: 宋体; color: black;">(zhn)不需要一个单一的编E标准。服务范例的定义只能?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">Web</span><span style="font-size: 10pt; font-family: 宋体; color: black;">服务?/span><span style="font-size: 10pt; font-family: ˎ̥; color: black;" lang="EN-US">XML</span><span style="font-size: 10pt; font-family: 宋体; color: black;">的接口标准识别出q种内在的多相性ƈ讄需求?/span></p><br /><img src ="http://www.tkk7.com/alex/aggbug/60522.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/alex/" target="_blank">Alex</a> 2006-07-28 11:29 <a href="http://www.tkk7.com/alex/archive/2006/07/28/60522.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Z不让SOA变得单?http://www.tkk7.com/alex/archive/2006/07/28/60511.htmlAlexAlexFri, 28 Jul 2006 03:03:00 GMThttp://www.tkk7.com/alex/archive/2006/07/28/60511.htmlhttp://www.tkk7.com/alex/comments/60511.htmlhttp://www.tkk7.com/alex/archive/2006/07/28/60511.html#Feedback0http://www.tkk7.com/alex/comments/commentRss/60511.htmlhttp://www.tkk7.com/alex/services/trackbacks/60511.html转自q里

最q,SOA成ؓ(f)跨技术^収ͼ特别是J2EE?NetQY件开发中的热门话题。然而,如果我们比较一下围l着SOA的宣传和90q代后期EJB和服务g 的宣传,你会(x)发现q没有什么区别?998q_(d)EJB带领互联|的潮流q推M(jin)以CORBA的统d由PB/Oracle Forms和其他主导的CS架构标准。SOAQ作ZU新技术的术语Q还不具有那么大的破坏性。SOA只是一U想?概念和一l构建应用功能的最?jng)_c(din)? 相反圎ͼJ2EE是一套完整地开发技术,可以用来设计所有的东西?br />
  我对SOA的主要关注在于企业Java应用通用的问题:(x)复杂性? ơ要x的是SOA通常作ؓ(f)一U解x案被用来跨越J2EE应用各层Q虽然这好像没有什么意义。本文提取出SOA的基本元素ƈ介绍他们。一旦我们理解这 些,可以理解SOApȝ中的更复杂的lg?jin)。最后,我们可以?jin)解一下SOAlJ2EE应用带来的实际h(hun)|同时q不增加无用的复杂性?br />本文分ؓ(f)个部分:(x)首先Q提Z(jin)我对SOA作ؓ(f)一U标准参考点的定义。其ơ,(g)查那些主要的软g工种问题通过SOA可以解决而不是用SOA来检查。再ơ,?x)给出基于复杂需求的SOA的徏议分cR最后,l出三种主要SOA分类的徏议实现?br />
  SOA是什么?

  SOA有很多定义。下面是我的定义Q?br />  SOA是宏U别的应用到应用架构U的设计模式Q?br />  1、可选地暴露应用的功能作Zl离散的lg?br />  2、ɘq些lg能被用来构徏更复杂的lg和应用?br />  3、仅包含Z消息的组件内部通讯?br />
  我还遗漏?jin)什么呢Q还有一些方面,包括Q?br />  1、安全?br />  2、事?br />  3、状态或无状态会(x)?br />  4、消息无数据
  5、 消息特?br />  6、 消息协?br />  7、 消息内?br />  8、  具体技术实?br />
  q些斚w也是重要的,但不是主要的。我的定义提取了(jin)SOA的核?j)规则,但没有抛弃概忉|w?br />注意我在定义中引用了(jin)设计模式。我认ؓ(f)q是关键。SOA不是什么新技术,事实上,其最吸引人的一个地Ҏ(gu)可以利用现有的技术ƈ使其泛出新的光芒。对我来_(d)SOA更像是一q蓝图,一l最?jng)_践,或者说是一个定义下一代的软g应用应该如何设计和实现的规范?br />
  基础SOAҎ(gu)

  从上面的定义Q我们应该可以标识出l成SOA应用的必L供的软g服务的最集合。简z地_(d)q些服务是:(x)

  1、消息层Q允许消息通过特定的协议传输和接收。用SOA的说法,q一层称Z业服务母U或写ؓ(f)ESB?br />  2、一个组件模型,如应用必遵循的发送和接收来消息母U的消息的最约定?br />
  取决于你自己的业务需求,q两U服务可以极度的扩大Q但在核?j)来_(d)消息层和通用lg模型׃表了(jin)SOA?br />
   注意Q我没有在SOA的定义中包含自动定位和发现服务(在大部分JEE场景中,q是很有杀伤力的)(j)。在UDDIQ通用描述/发现/集成协议Q后的原始想 法是认ؓ(f)企业最l会(x)使用软g服务Q通过一个大的基于元数据搜烦(ch)服务仓库Q来购买和销售。这个美梦至也得十q后Q也许永q不?x)实玎ͼ因?f)Z是需要做的实 际的业务而不是Y件?br />
  JEE应用不需要自动发现服务,例如d或支付服务,q些服务应该在初始化时设|。不要误导我Q如果这些服务的实现不应该硬~码到应用中Q那么你也不需要SOA来解册些问题了(jin)?br />
  下一节,我们?x)来考虑一下究竟需要SOA来解决什么,或者他能替代什么?br />
  Z么要SOAQ?/span>

   最q的两拨企业UY件开发的L潮是C/S架构和多层架构。虽然多层架构提供了(jin)C/S架构中布|?q_支持/性能/伸羃性上更好的效果,但两者都没有? 决一个关键的企业U计机领域的Y件工E问题:(x)如何重用软g功能。作Y件开发h员和架构师,我们始终没有完全解决软g重用的问题。再往下看Q你?x)看到? 也不认ؓ(f)SOA能解册个问题。然而,我认Y仉用是SOA出现的最重要原因Q至在JEE应用中是q样Q?br />
  其他SOA使用现有的Jini和风D。基于Jini环境的特点如下:(x)
  1、自动发现组?服务
  2、自愈的

   然而,q些Ҏ(gu)ƈ没有与JEE应用{同的重要性。用JDBC配置数据库的位置只需要一ơ。我期望数据库来提供定w和除错功能,而且我不需要JEE应用 来尝试当产品实例当机时自动发现其他的数据库实例。另一斚wQ对一个有2000个工作站的办公室来说自动发现一个彩色打印机是一件好事,q也是符? Jinig的一个关键好处?br />
  q等CQ在一个真实的全球|格计算环境中,自动发现和枚举计资源来解决问题是基框架的关键部分,但这不是一个JEE环境Q那儿硬仉先计的以便在定义用h据和服务性能之间q?br />
  我的观点是,SOA对不同的需求需要不同对待。在本文中,我只兛_(j)JEE架构斚w的SOAQ而我认ؓ(f)q意味着功能重用。其他从JEE观点来看SOA的优点还有:(x)
  1、松耦合的组Ӟq是软g设计中重要的部分
  2、引入ESB作ؓ(f)消息层意味着强制“面向接口编E,而不是实现?br />  3、异步消息增加了(jin)应用的׾~?br />
  让我们通过问三个特定的问题来看一下Y仉用中更细节的问题Q?br />  1、ؓ(f)什么重用Y件是重要的?
  2、SOA是如何提?gu)册Y仉用问题的Q?br />  3、是否SOA的允够软g重用应用到现实中Q?br />
  首先QY仉用是重要的原因如下:(x)
  1、时间和p上的效率—能够重用已l的lg来满陈q的业务需求将节省大量的时间和金钱?br />  2、重要的Ҏ(gu)包括但不限于如E_?性能/可管理?文档/可配|性。因Z个组件被重用的次数越多,对这个组件的投资也越多,他的优势也越多?br />  3、 良好设计的可重用框架无论在哪里被用都拥有正面的效果,而且你愿意的话可以封装更好的x来解决通用问题?br />
   因此我们需要重用性。那么最单的Ҏ(gu)是什么呢Q就是打包Y件作Zl良好定义的lg来满离散的功能需求。然后,如果其他应用需要相同的lgQ他可 以重用了(jin)。还有些l节需要考虑Q如如何配置Q但q些l节已经偏离?jin)主题?x)重用M语言~写的代码,那些代码必须被设计成一l离散的lg或重构ؓ(f)集合?br />
  可以参考我在JavaWorld上的W一文章,“节省时间的框架”(2000.9Q,有更多细节善于JEE目的Y仉用?br />
   其次QSOA是如何解册Y仉用的问题呢?是通过Zlg模型来构建和引入一个重要的强制U定Q组仉的通讯要通过下发到ESB的消息来q行Q而这q 保了(jin)松耦合。实际上Q最q泛布v的SOA实现—Web services可以通过使消息层技术中性来~合用不同语a开发的lg?br />
  最 后,SOA对Y仉用的允诺真有实际意义吗?不,我想念如果SOA?945Q大概是和ENIAC同时代吧Q被发明的话实可以解决软g重用的问题。但? 有,现存的大量代码是用不同的开发语a~写的,有COBOL/C/C++http://java.chinaitlab.com/C#和其他语a。这些代 码没有作为离散的lg来编写,因此也没有SOA法来解冟뀂事实上Q我认ؓ(f)有大量的SOA目的工作是p在重构相同的代码库?br />
  现在Q让我们来看一下对于JEE应用SOA可以解决的一些问题?br />
  SOA~点

  SOA~点包括下面三方面:(x)
  1、 SOA自n的缺点,主要当前q没有成熟的实现
  2、 SOA的复杂?br />  3、  厂商对SOA在更q泛的JEE产品和方案中的位|?br />
  那么我们心(j)批判的眼光来看一下:(x)

  ·q没有像JEE规范那样有自q正式规范。虽然有一个发布的规范Q但那个太复杂了(jin)q且没有遵@80:20法则Q?0%的应用需要简单的SOAQ只?0%的应用需要更强大而复杂的功能Q?br />  ·有状态会(x)话依然存在广泛争议而且现在q没有被SOA的缺省实玎ͼWeb servicesQ所解决。而无状态会(x)话已l是完全支持?jin)?br />  ·׃~省正式或推荐的规范QW(xu)eb services已经成ؓ(f)许多人眼里SOA的代名词?jin),但Web services通常是过于强大了(jin)?br />  ·SOA增加?jin)复杂性。可能你更喜Ƣ硬~码和紧耦合Q而不需要XML配置文g来运行简单的应用?br />   ·SOA兼容的应用对本n来说没有什么意义。其商业价值来自于能够提供L的功能块通过SOA被用于其他的应用和模块。例如,如果你对订单的较验规则是 通过JSP面中的Java代码来实现的Q那么你q需要重构代码将其放到服务端对象中以便于SOA调用—但很多厂商q没有提?qing)这一炏V?br />  ·在某些情况下Q厂商将SOA作ؓ(f)|页应用框架的替代者!我认为,W(xu)AF是SOA定义功能中的消费者,只是作ؓ(f)一U补充,而不存在竟争关系?br />  · 与厂商提供的相反Q一些应用根本不需要SOA而只需要简单用MVC框架可以了(jin)。这很短视吗Q我不这么认为,即SOA的特性是需要的Q在上面的情况下Q最重要的部分是用来服务于企业服务ȝ的良好定义的业务逻辑层,而不是ESB自n?br />
  虽然我不认ؓ(f)SOA是一颗解决现有和新徏应用中问题的银弹Q便我相信SOA在他相应的位|上q是有其内在的h(hun)值的。现在让我们来看一下在应用中增加有效的SOA解决Ҏ(gu)是如何提供体现其商业价值的?br />
  的SOA分类

   现在Q你应该Ҏ(gu)保持事物的简单性的热忱表示感激吧。但我本质上q不是简单论者,我是一个实用主义者。对软g目来说Q我认ؓ(f)实用M是一斚w要^衡项 目的商业和实际h(hun)|另一斚w是用Y件设计上的最?jng)_c(din)简单的_(d)是在我们现有条件下构徏我们所能创建的最好的pȝ?br />
  一个实用主义的好例子来自于民间的工E历双Ӏ在修铁路时怿木桥Q而我们知道用铁桥?x)更好。当铁\公司的股东想使用铁\快开工而且初始投资要有限制Ӟ他就是这是最好的工程Ҏ(gu)?jin)。是否听h耳熟Q同L(fng)原则可以应用于Y件工E?br />
  Ҏ(gu)实用M的精,我徏议将SOA分ؓ(f)三个U别Q简?中等/复杂Q衡量标准是需要满的业务需求。如果你需要简单的SOAQ那么不要浪Ҏ(gu)间和金钱在复杂的SOA上?br />
  U别1Q简单的SOA

  样例实现Q?br />  1、用自qPOJO队列实现来发送和接收消息?br />  2、带有MDBQ消息驱动BeanQ的JMS队列/主题作ؓ(f)消息的消费者?br />
  q里늛的关键SOA概念有:(x)
  1、企业服务ȝ
  2、生产?消费者的lg模型?br />

resized image


  Figure 1. Schematic illustrating the core components of the simple SOA. Click on thumbnail to view full-sized image.

  U别2Q中{的SOA

  样例实现Q?br />  1、带有MDB的JMS队列/主题作ؓ(f)消息的消费者,q加其他特性如安全?事务/JMS元数据属性等
  2、 Web servicesQ例如Apache Axis

  q里늛的关键SOA概念在包含简单SOA外还有:(x)
  1、用来增加健壮性和可靠性的错误/重试队列?br />  2、引入XML作ؓ(f)消息的有效负载内Ҏ(gu)代替序列化Java对象Q从而支持其他技术如.Net

resized image


   Figure 2. Schematic illustrating the core components of the medium-complexity SOA. Click on thumbnail to view full-sized image.

  U别3Q复杂的SOA

  样例实现Q?br />  1、带有MDB的JMS队列/主题作ؓ(f)消息的消费者,q加其他特性如安全?事务/JMS元数据属性等
  2、Web services
  3、厂?标准相关的SOA兼容工具包(如专门的金融服务Q?br />
  q里늛的关键SOA概念在包含中{SOA外还有:(x)
  1、良好定义而且严格的组件模型(例如Java业务集成/服务lg架构?qing)其他?j)
  2、增强的厂商支持Q如可插拔的新生产?消费者组件创?br />  3、 详l枚丄定SOA实现上可用服务的lg注册表?br />

resized image


  Figure 3. Schematic illustrating the core components of the complex SOA. Click on thumbnail to view full-sized image.

  结

   目前SOA是作ZU架构体玎ͼ也将?x)成ZC/S或多层架构一样存在。但是,他目前还是不够成熟而且只是作ؓ(f)厂商利用的工兗我对SOA的徏议是Q从 单的做vq保持SOA可能的单。不要将SOA与Web services{同hQ也不要强制使用SOA的设计模式在JEE应用的各层上Q告别是|页层?br />
  那么我会(x)为大多数JEE应用推荐? 一个SOA实现呢?U别2上的SOA实现如带有MDB的JMS队列作ؓ(f)消费者,而POJO或无状态的?x)话Bean作ؓ(f)消息生者。当?dng)如果你确信你需? 集成非Java应用,那么考虑一下Web services实现。还要考虑你现在采用的解决Ҏ(gu)在以后要有够的扩展I间。虽焉多久通常都有争议的,但我q是最q不过36个月。如果你? 见到那个旉D内有额外的SOA需求,那么现在来构徏吧?br />
  关于作?/b>

  Humphrey Sheil是英国服务业企业U应用供应商CedaropenAccounts的首席技术架构师。特别擅长于集成领域。拥有爱?dng)兰都柏林大学的计算机科学硕士学位。点击这里进入他的博客?br />
  资源

  ·Jini技术,最早的SOA实现之一:http://www.jini.org
  ·JEE规范:http://java.sun.com/j2ee/download.html#platformspec
  ·学习(fn).Net的的入门点:(x)http://msdn2.microsoft.com/en-us/library/ms310245(en-us,MSDN.10).aspx
  ·http://www.uddi.org UDDI协议
  ·创徏SOA的准备:(x)http://weblog.infoworld.com/techwatch/archives/004644.html
   ·Java业务集成Q用来ؓ(f)Java应用Q特别指ZSOA的应用)(j)定义lg模型的规范。这更正规些Q因此允许厂商根据标准提供工具和框架以实现最l的 交互性。目前许多失败就是因为缺这些支持:(x)http://www.jcp.org/en/jsr/detail?id=208
  ·http://ws.apache.org/axis/ 开源的JEE|页服务实现- Apache Axis

  版权声明QQ何获得Matrix授权的网站,转蝲时请务必保留以下作者信息和链接
  原文:http://www.javaworld.com/
  译文:http://www.matrix.org.cn/



Alex 2006-07-28 11:03 发表评论
]]>
վ֩ģ壺 պvĻ| ҹƷ| ޹ŷۺһ| ޹߹ۿ | þaaëƬѲŰ| ĻȫѰƵ| ձ2019߹ۿ| ߹ۿȤƵ| þþƷһ| ݺۺɫ| ޹һҳwww| ŷպƷһ| һձƵѹۿ| 999|| ձƬѹۿ| ޾Ʒɫҹרպ| 91͵߹ۿ| ۺʮ| 91԰Ƶ| Ƶվѹۿ| պavþþƷ| ߹ۿİ| Ļþи| ׾ƷͼƬ| һ߹ۿ| ŮƵ| ޹Ʒר߹ۿ | ˳վþ99ȹ| ѹۿ| ɫվѹۿ| ѹۿ| ҹƷһ߲ŷ | Ļ޾Ʒ| ŷۺһ | ƷƷþһʽ| һav| ¶ۺ| aٰƵ| ߹ۿƵվ| þ޾ƷƷ| jizzѲ|