Tucany SCA软件架构设计理念分析(一)

 

李俊杰

1.     概述

SCA (Service Component Architecture) 是一个开发SOA(Service-Oriented Architecture)面向服务应用的简单模型规范,它描述用于使用 SOA 构建应用程序和系统的模型。它可简化使用 SOA 进行的应用程序开发和实现工作。SCA仅仅是个规范(http://www.osoa.org),各个涉及SOA技术的公司的实现也各不相同。本文主要分析Apache Tuscany开源项目 (http://incubator.apache.org/tuscany/)中的SCA设计架构;因为我们不能满足于会用,而从这些大师们的作品中汲取营养,知其然,也要知其所以然,当我们面对需求(比如说SCA规范),都拥有同样的语言功底,如何设计一个开放性,可扩展性的架构,就是一个挑战。因为Tuscany设计理念博大精深,开放式的结构思想,性能方面的考虑,安全方面的考虑,不一而足,所以不可能在一篇短文中详细介绍,将在后续的文章中不断地深入剖析,提取设计架构和设计技巧的精华之处,供广大软件界同仁共享。

2.     SCA规范基础知识

SCA编程模型是高扩展性和语言中立的,它易于被扩展为多种实现语言技术JAVAC++BPELPHP Spring 等,多种远程访问 bindings 包括 Web ServiceJMS EJBJSON RPC等,多种主机环境例如 Tomcat, Jetty, Geronimo, OSGI等。SCA分隔式架构可以使开发者更注重业务逻辑,而不必要关注诸如可靠性,安全,事务等系统属性,这些属性都配置到配置文件中。SCA的组成部分如下图所示:(本文涉及的SCA术语不翻译)

1Component

深蓝色方框(Component AComponent B)表示是ComponentComponentSCA原子(最基层的组织单元),其封装了实际的业务逻辑。Component可以采用运行环境支持的任何编程技术实现。例如, Apache Tuscany 项目目前支持JavaJavaScriptRubyPythonC++组件类型,同时为创建新的组件类型提供了扩展API

2Property

Property (Component AComponent B上方的黄色方框和Composite A的黄色小方框)Property控制Component的行为,在部署其间可以被可改变。同时Composite也可以有Property,但其PropertyComponent Property升级(Promote)后的Property

3Service

Service是供其它Component调用时使用。在图中接口用Component方框左边的绿色箭头来表示,被称作SCA服务Service)。

4Reference

Component也描述了被该Component调用的其它组件的接口,在图中这样的接口用组件方框右边的粉红色箭头来表示,称为SCA引用Reference)。这些ServiceReference被连接在一起,组成一个可运行的系统。

5Composite

如果说ComponentSCA架构中的原子,那么Composite就是SCA架构中的分子;图中的两个ComponentAB,被组装在一个更大Composite范围内,被称作Composite ASCAComposite描述了一个由互相连接的Component所构成的集合。正如你所看到,Composite也声明了ServiceReference,它们被暴露到Composite外部。CompositeserviceReferenceComposite内部的ComponentServiceReference的升级。.一个Composite内部的Component彼此连接就如同创建一个运行在同一进程中的紧耦合的应用程序。将Composite通过ServiceReference连接在一起,则形成了一个更加松耦合的系统;系统中的每一个Composite都可能运行在一个单独的进程或处理器中,在网络中通过各种的协议和传输绑定连接起来。通过这个途径SCA为独立和分布式应用提供了统一的编程模型。

6Wire

Wire是连接ServiceReference的连线

7Promote

Promotewire的特殊表现形式,是把Component级别Service或者Reference升级为Composite级别的连线。

8Domain

为了更直观地介绍domain,如下图所示:

从上图可以清楚地看出,Domain是个逻辑的概念,管理跨机器,跨进程的Composite,同时Composite也可以跨机器跨进程部署,从而可以管理分布式部署的SCA,所以Domain是个相当重要的SCA概念。其实除了Domain是管理含义外,还有外部接口界面的含义。

 

3.     Tuscany SCA软件架构设计思想

通过SCA基础知识的介绍,我们了解了大致的需求,感谢Tuscany的架构师和工程师,是他们奉献了自己的聪明智慧,创作出如此赏心悦目的精品大作,深刻品味大型软件架构设计的精髓,分享软件设计的豪华盛筵,汲取设计的精华。

(1) 插件式软件设计思想

不论是Eclipse,还是炒得火热的ESB,都使用插件式的设计思想,所谓插件式,可插拔的软件架构,就是极大地体现了松耦合的设计理念,虽然是从原有的设计模式阵营中走来,但其出现给现有的设计模式已很大的冲击并提升了和补充现有的设计模式。在Tuscany中同样如此,可以说把插件式的设计思想用到了极致。下面类图非常简单,但它就是类似于注册中心功能的扩展点注册类,它是Tuscany的最基本和最基础的设计架构,后面有相对复杂的设计,也是建立这种基本架构的基础之上拓展出来的。

基本工作原理:

上面的静态类图表现了注册结构的静态分析,类org.apache.tuscany.sca.core. DefaultExtensionPointRegistrygetExtensionPoint流程图体现了在如何从注册中心获取需要的对象的过程。从本质上分析ExtensionPointRegistry就类似于Collection,其功能无外乎可添加,可删除,可获取,这儿用HashMap<Class<?>, Object>来实现,HashMap也就是putgetremove方法。可以把DefaultExtensionPointRegistry理解为HashMap的特殊封装,其中<Class<?>, Object>是非常重要的。

换句话说,META-INF/services下面的文件相当于插件板组,其中包含着若干个插件板,每个插件板的插件孔是可以预先调配的。另外,类似于树的概念,有些插件板的插孔也可以插入子插件板,下面显示一个简单插件板的例子,插件板的名称是“org.apache.tuscany.sca.contribution.resolver. ModelResolverExtensionPoint ,插件板的名称一般是Java接口的名称,而插孔的名称一般为实现类的名称,该例子仅仅声明了一个插孔,插孔名称为“org.apache.tuscany.sca.contribution.resolver.DefaultModelResolverExtensionPoint “,另外我告诉你一秘密,凡是以“ExtensionPoin”结尾的,一般是子插件板,呵呵!一般人我不告诉他。

# Licensed to the Apache Software Foundation (ASF) under one

# or more contributor license agreements.  See the NOTICE file

# distributed with this work for additional information

# regarding copyright ownership.  The ASF licenses this file

# to you under the Apache License, Version 2.0 (the

# "License"); you may not use this file except in compliance

# with the License.  You may obtain a copy of the License at

#

#   http://www.apache.org/licenses/LICENSE-2.0

#

# Unless required by applicable law or agreed to in writing,

# software distributed under the License is distributed on an

# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

# KIND, either express or implied.  See the License for the

# specific language governing permissions and limitations

# under the License.

 

org.apache.tuscany.sca.contribution.resolver.DefaultModelResolverExtensionPoint

从而我们就可以非常方便地对插件板进行修改,或增加插件板来满足系统不断新增需求,不断新增模块,修改模块的需求。并且DefaultExtensionPointRegistry是系统中的根插件板,是其他所有插件板或者插件的根(root)。

(2) Factory设计模式的深化和发展

与插件式软件设计模式类似,Factory设计模式方面也有很大地发展和提高,为此仅用例子如SpringImplementationProviderFactory来说明Facory模式方面的设计理念和技巧。

如图所示,左上角的部分也同样是插件式模式。在META-INF/services/目录下有文件名称为“org.apache.tuscany.sca.provider.ProviderFactoryExtensionPoint”,文件内容有用的仅一行是“org.apache.tuscany.sca.provider.DefaultProviderFactoryExtensionPoint”,就是这样把DefaultProviderFactoryExtensionPoint插入到DefaultExtensionPointRegistry插件板的,同样ProviderFactoryExtensionPoint为接口名称,DefaultProviderFactoryExtensionPoint为实现该接口的具体实现。

 

   ProvideFactory接口中定义了Class<M> getModelType()方法,在SpringImplementationProvideFactory中实现为

public Class<SpringImplementation> getModelType()

{

        return SpringImplementation.class;

 }

其中的ModelType就对应于的model的值  ,即META-INF/services/目录下的是“org.apache.tuscany.sca.provide.ImplementationProviderFactory”文件下每行数据中的model属性的值(org.apache.tuscany.sca.implementation.spring.SpringImplementation)。

ImplementationProviderFactory<M extends Implementation>中定义了factory方法createImplementationProvider),在SpringImplementationProvideFactory中实现为

public ImplementationProvider createImplementationProvider(RuntimeComponent component,                                                               SpringImplementation implementation)

{

        return new SpringImplementationProvider(component, implementation, proxyService, propertyFactory);

}

DefaultProvideFactoryExtensionPoint类中有获取ProvideFactory的方法

public ProviderFactory getProviderFactory(Class<?> modelType) {

       //

        loadProviderFactories();

       

        Class<?>[] classes = modelType.getInterfaces();

        for (Class<?> c : classes) {

            ProviderFactory factory = providerFactories.get(c);

            if (factory != null) {

                return factory;

            }

        }

        return providerFactories.get(modelType);

    }

和插件式设计模式类似,loadProviderFactories();也是调用ServiceConfigUtil 类的getServiceNames方法到META-INF/services/目录下的文件,本例子找的文件是“org.apache.tuscany.sca.provide.ImplementationProviderFactory”,文件的主要内容是:

org.apache.tuscany.sca.implementation.spring.SpringImplementationProviderFactory;model=org.apache.tuscany.sca.implementation.spring.SpringImplementation

org.apache.tuscany.sca.implementation.resource.provider.ResourceImplementationProviderFactory;model=org.apache.tuscany.sca.implementation.resource.ResourceImplementation

 

org.apache.tuscany.sca.implementation.osgi.invocation.OSGiImplementationProviderFactory;model=org.apache.tuscany.sca.implementation.osgi.OSGiImplementationInterface

 

最后保存到类DefaultProviderFactoryExtensionPointHashMap<Class<?>, ProviderFactory>中如下图所示:

ServiceConfigUtil是按行读文件,由于每行比较长,在本文书写时不方便,就折为两行,但还能够分清是否是一行的。读后把每行数据都保存在List<String>中,

ServiceConfigUtilparseServiceDeclaration方法是解析字符串,每行字符使用“;”隔开,前者为Factory名称,后者为属性名称及数值,多个属性用“,”分割,读完后分别存储Map<String, String> attributeskey分别为“class”,“model”。

在这儿并没有把相关的factory,直接用modelfactory对象直接放入到HashMap<Class<?>, ProviderFactory>中,而是在Factory外封装了延迟加载类(LazyBindingProviderFactory LazyImplementationProviderFactory都是DefaultProvideFactoryExtensionPoint的内部类)作为value值放入HashMap<Class<?>, ProviderFactory>中。这样只有使用时才去加载这些类。

Factory调用及代理模式实现的延迟加载功能

下面来看调用是多么简单,providerFactories就是我们图示的HashMap,下面的implementationProvider  是那个延迟加载的类LazyImplementationProviderFactor的对象:

ImplementationProviderFactory     providerFactory   =

            (ImplementationProviderFactory)providerFactories.getProviderFactory(implementation.getClass());

ImplementationProvider        implementationProvider  =

                providerFactory.createImplementationProvider(component, implementation);

LazyImplementationProviderFactor调用createImplementationProvider方法如下,其中getFactory()是要加载该延迟加载类封装的实际的的ProviderFactor

public ImplementationProvider createImplementationProvider(RuntimeComponent component, Implementation Implementation) {

            return getFactory().createImplementationProvider(component, Implementation);

        }

另外除了延迟加载的原理,还存在代理模式的应用,如下图所示,这儿调用的是LazyImplementationProvicerFactory,然后通过它来调用实际的ImplementationProvicerFactory的实现类来创建ImplementationProvider

 

且看它这时才加载( ImplementationProviderFactory getFactory() ),这正是延迟加载的含义。

if (factory == null) {

                try {

                   

ClassLoader classLoader = ImplementationProviderFactory.class.getClassLoader();

   Class<ImplementationProviderFactory> factoryClass = (Class<ImplementationProviderFactory>)Class.forName(className, true, classLoader);

   Constructor<ImplementationProviderFactory> constructor = factoryClass.getConstructor(ExtensionPointRegistry.class);

                    factory = constructor.newInstance(registry);

                } catch (Exception e) {

                    throw new IllegalStateException(e);

                }

            }

  return factory;

 

(3) 更复杂的工厂模式

Tuscany SCA软件中有Artifact Professor的创建是更为复杂的工厂模式,Artifact Professor是描述如何处理Artifact的接口(在SCA中,最基本的部件是Artifact,即包含外部的artifact,也包括内部的artifactArtifactContribute的原子,我们部署我们的应用到SCA上,那么每个应用就叫一个Contribute)。下面是类图:

这儿你可以看到美学在软件架构设计中的应用,呵呵!

 

代理模式的使用

如图所示,ExtensibleURLArtifactProcessor ExtensibleStAXArtifactProcessor分别是接口URLArtifactProcessor StAXArtifactProcessor的实现类,它们都包含相应的ArtifactProcessorExtensionProcessor接口,即包含相应的工厂,外部的调用是首先调用这个代理类,从而获取这个工厂并创建出相应的ArtifactProcessor。从而实现了代理模式。

public Object read(XMLStreamReader source) throws ContributionReadException {

       

        // Delegate to the processor associated with the element qname

        QName name = source.getName();

        StAXArtifactProcessor<?> processor = (StAXArtifactProcessor<?>)processors.getProcessor(name);

        if (processor == null) {

            return null;

        }

        try {

            return processor.read(source);

        } catch (XMLStreamException e) {

            throw new ContributionReadException(e);

        }

    }

 

复杂工厂的介绍

如图所示,ArtifactProcessorExtensionPoint接口表明这是是个插件板,它有两个子插件板,分别为URLArtifactProcessorExtensionPoint StAXArtifactExtensionPoint,另外还有两个缺省实现类DefaultURLArtifactProcessorExtensionPoint DefaultStAXArtifactExtensionPoint,从上面工厂类模式的扩展类似(为了简化,没有画文件包及处理文件的类ServiceConfigUtil),在META-INF/services/下面有两个文件:

org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint

org.apache.tuscany.sca.contribution.processor.DefaultURLArtifactProcessorExtensionPoint

org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint

org.apache.tuscany.sca.contribution.processor.DefaultStAXArtifactProcessorExtensionPoint

分别标明是两个子插件板的实现插件板。它们都继承了DefaultArtifactProcessorExtensionPoint,也就是说提供类型(ArtifactProcessor)相似的插孔。更具体地说是继承类型(ArtifactProcessor的两个子类型URLArtifactProcessorStAXArtifactProcessor),这儿可以很清楚地看出JDK1.5后的泛型的应用是多么大的威力。

 同样在在META-INF/services/下面有两个相对应的文件,分别表示两种类似的插件:

org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor

org.apache.tuscany.sca.interfacedef.wsdl.xml.WSDLDocumentProcessor;type=.wsdl,model=org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition

org.apache.tuscany.sca.interfacedef.wsdl.xml.XSDDocumentProcessor;type=.xsd,model=org.apache.tuscany.sca.interfacedef.wsdl.XSDefinition

org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor

org.apache.tuscany.sca.implementation.spring.SpringArtifactProcessor;qname=http://tuscany.apache.org/xmlns/sca/1.0#implementation.spring,model=org.apache.tuscany.sca.implementation.spring.SpringImplementation

 

org.apache.tuscany.sca.assembly.xml.DefaultBeanModelProcessor;qname=http://tuscany.apache.org/xmlns/sca/1.0#binding.http,model=org.apache.tuscany.sca.binding.http.HTTPResourceBinding,factory=org.apache.tuscany.sca.binding.http.HTTPResourceBindingFactory

 

org.apache.tuscany.sca.interfacedef.wsdl.xml.WSDLInterfaceProcessor;qname=http://www.osoa.org/xmlns/sca/1.0#interface.wsdl,model=org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterfaceContract

 

org.apache.tuscany.sca.databinding.sdo.ImportSDOProcessor;qname=http://tuscany.apache.org/xmlns/sca/databinding/sdo/1.0#import.sdo,model=org.apache.tuscany.sca.databinding.sdo.ImportSDO

 

org.apache.tuscany.sca.contribution.java.impl.JavaImportProcessor;qname=http://www.osoa.org/xmlns/sca/1.0#import.java,model=org.apache.tuscany.sca.contribution.java.JavaImport

org.apache.tuscany.sca.contribution.java.impl.JavaExportProcessor;qname=http://www.osoa.org/xmlns/sca/1.0#export.java,model=org.apache.tuscany.sca.contribution.java.JavaExport

 

org.apache.tuscany.sca.contribution.namespace.impl.NamespaceImportProcessor;qname=http://www.osoa.org/xmlns/sca/1.0#import,model=org.apache.tuscany.sca.contribution.namespace.NamespaceImport

org.apache.tuscany.sca.contribution.namespace.impl.NamespaceExportProcessor;qname=http://www.osoa.org/xmlns/sca/1.0#export,model=org.apache.tuscany.sca.contribution.namespace.NamespaceExport

 

org.apache.tuscany.sca.implementation.java.xml.JavaImplementationProcessor;qname=http://www.osoa.org/xmlns/sca/1.0#implementation.java,model=org.apache.tuscany.sca.implementation.java.JavaImplementation

 

org.apache.tuscany.sca.binding.sca.xml.SCABindingProcessor;qname=http://www.osoa.org/xmlns/sca/1.0#binding.sca,model=org.apache.tuscany.sca.binding.sca.impl.SCABindingImpl

 

org.apache.tuscany.sca.implementation.resource.impl.ResourceImplementationProcessor;qname=http://tuscany.apache.org/xmlns/sca/1.0#implementation.resource,model=org.apache.tuscany.sca.implementation.resource.ResourceImplementation,factory=org.apache.tuscany.sca.implementation.resource.ResourceImplementationFactory

 

org.apache.tuscany.sca.implementation.osgi.xml.OSGiImplementationProcessor;qname=http://tuscany.apache.org/xmlns/sca/1.0#implementation.osgi,model=org.apache.tuscany.sca.implementation.osgi.OSGiImplementationInterface

 

org.apache.tuscany.sca.assembly.xml.DefaultBeanModelProcessor;qname=http://tuscany.apache.org/xmlns/sca/1.0#binding.atom,model=org.apache.tuscany.sca.binding.feed.AtomBinding,factory=org.apache.tuscany.sca.binding.feed.AtomBindingFactory

org.apache.tuscany.sca.assembly.xml.DefaultBeanModelProcessor;qname=http://tuscany.apache.org/xmlns/sca/1.0#binding.rss,model=org.apache.tuscany.sca.binding.feed.RSSBinding,factory=org.apache.tuscany.sca.binding.feed.RSSBindingFactory

 

org.apache.tuscany.sca.binding.ws.xml.WebServiceBindingProcessor;qname=http://www.osoa.org/xmlns/sca/1.0#binding.ws,model=org.apache.tuscany.sca.binding.ws.WebServiceBinding

 

类似上面所说明的,在Hash Map中依然是保存着ArtifactProcessor的延迟加载封装类,同样是采用代理模式来实现延迟加载功能的,在这儿不再赘述。

精巧的设计

QName name = source.getName();

        StAXArtifactProcessor<?> processor = (StAXArtifactProcessor<?>)processors.getProcessor(name);

再看QName来自于何方神圣,在我们开发的例子程序中有Calculator.composite配置文件

<component name="CalculatorServiceComponent">

<implementation.java class="calculator.CalculatorServiceImpl"/>

上面的QNamelocalPart属性就是“component”,“implementation.java”,而这个QName是在读Calculator.composite文件时产生的,根据这个QName,我们就能找到要处理这个tag的类。如当读到“implementation.java”的QName,根据QName作为key值就在HashMap中找到JavaImplementationProcessor ,然后由JavaImplementationProcessor来处理。

implementation.java-JavaImplementationProcessor,多么令人拍案叫绝的设计啊!

 

(4) JDK 泛型在工厂模式中的应用

Tuscany是基于JDK1.5的开发出来的,其中大量使用了泛型等新特性,下面简单地介绍泛型在工厂模式中的应用。

泛型基础知识

泛型增加可读性和稳定性,如果说继承实现了子类型的多态的话,那么泛型则是实现了参数的多态,两者都是抽象机制的重要组成部分,两者能够在一定程度上相互替代,编译器会帮助你检查类型,保证类型安全。继承和泛型是两种方向上的重用技术,继承提供的是类型的纵向扩展,而泛型提供的是类型的横向抽象。两种技术都能够提供优秀的重用性。

JDK1.4时,只能用继承,可以覆写接口或父类的方法,但注意如果覆写这些方法,必须按照接口或者父类的方法写(不论是参数类型系列,还是返回类型都必须和接口或父类保持完全一致),这样就限制了我们的发挥,呵呵!还是举个例子吧:

public interface Employee {

       public String getName();

}

// Employee接口实现类1

public class EmployeeImpl implements Employee{

       public String getName()

       {

              return "employee";

       }

}

// Employee接口实现类2

public class DepartmentLeader implements Employee{

       public String getName()

       {

              return "leader";

       }

}

//Employee工厂接口

public interface EmployeeFactory {

       public Employee CreateEmployee(String employeeType);

}

//Employee工厂接口实现类

public class EmployeeFactoryImpl implements EmployeeFactory{

       public Employee CreateEmployee(String employeeType)

       {

              Employee employee = null;

              if(employeeType.equalsIgnoreCase("employee"))

              {

                     employee = new EmployeeImpl();

              }

              else if(employeeType.equalsIgnoreCase("employee"))

              {

                     employee = new DepartmentLeader();

              }

              return employee;

       }

}

我们再来看使用泛型的写法,父类或接口中定义了泛型约束,只要求这个“e”是Employee的子类即可,下面的两个实现类可以清楚地看到实现接口方法的返回类型不同了,但返回类型都是Employee的子类。

//使用泛型的Employee工厂接口

public interface EmployeeFactoryByGeneric<e extends Employee> {

       public e createEmployee();

      

}

//使用泛型的DepartmentLeader工厂实现

public class DepartmentLeaderFactory implements EmployeeFactoryByGeneric<DepartmentLeader>{

       public DepartmentLeader createEmployee()

       {

              return new DepartmentLeader();

       }

}

//使用泛型的Employee工厂实现

public class EmployeeFactoryImplByGeneric implements EmployeeFactoryByGeneric<EmployeeImpl> {

       public EmployeeImpl createEmployee()

       {

              return new EmployeeImpl();

       }

}

这样有什么好处呢?让我们来看看如何调用的。可以看出调用方面没有什么大的区别。

JDK1.4的做法

EmployeeFactory factory = new EmployeeFactoryImpl();

Employee leader =  factory.createEmployee("leader");

leader.getName();

使用泛型的做法:

EmployeeFactoryByGeneric factoryByGeneric = new DepartmentLeaderFactory();

Employee employee =  factoryByGeneric.createEmployee();

employee.getName();

Tuscany中工厂设计中涉及泛型的应用

根据我们上面介绍的泛型的基础知识,下面让我们来看看SpringImplementationProviderFactory如何定义的,其中使用了泛型约束SpringImplementation

public class SpringImplementationProviderFactory implements ImplementationProviderFactory<SpringImplementation>

 SpringImplementationProviderFactory另外其中有个方法非常值得注意,就是getModelType,在这儿是SpringImplementation.class

public Class<SpringImplementation> getModelType() {

        return SpringImplementation.class;

    }

类似的我们看ResourceImplementationProviderFactory的定义,其中使用了泛型约束ResourceImplementation

public class ResourceImplementationProviderFactory implements ImplementationProviderFactory<ResourceImplementation>

它同样有个方法getModelType,在这儿是ResourceImplementation.class

public Class<ResourceImplementation> getModelType() {

        return ResourceImplementation.class;

    }

那么这个ModeType有什么神秘的用途呢?来看DefaultProviderFactoryExtensionPoint的代码,从以下代码可以看出,在HashMap中的key值为providerFactory.getModelType(),到这儿明白了ModelType的用途了吧。

private final Map<Class<?>, ProviderFactory> providerFactories = new HashMap<Class<?>, ProviderFactory>();

public void addProviderFactory(ProviderFactory providerFactory) {

        providerFactories.put(providerFactory.getModelType(), providerFactory);

    }

下面是META-INF/services/ org.apache.tuscany.sca.provide.ImplementationProviderFactory的片断,从中也可以找到model的身影,从而可以看出model泛型约束是贯穿全剧的线索

org.apache.tuscany.sca.implementation.spring.SpringImplementationProviderFactory;model=org.apache.tuscany.sca.implementation.spring.SpringImplementation

 

Tuscany的工厂设计中都使用了类似的设计理念,使用要创建的类或者是类的接口作为其工厂HashMap中的Key,这样就能很方便地取出这个工厂,创建这个类了。从DefaultProviderFactoryExtensionPoint中的获取工厂可以看出这一点,接口或实现类都可以作为key保存到HashMap

public ProviderFactory getProviderFactory(Class<?> modelType) {

        loadProviderFactories();

       

        Class<?>[] classes = modelType.getInterfaces();

        for (Class<?> c : classes) {

            ProviderFactory factory = providerFactories.get(c);

            if (factory != null) {

                return factory;

            }

        }

        return providerFactories.get(modelType);

 }

 

4.     结束语

以上内容仅仅涉及插件式设计模式及工厂模式的深化和发展,随后将介绍有关Proxyinvocation方面的设计理念,还有Assemblycontributebinding的具体设计思想,最后介绍Tuscany整体架构设计思想,敬请关注。共享是我的准则,共同提高是我的目标。

 

努力,在于我热爱我的事业,与中国的软件一起走向成熟,走向世界。

   

联系作者:lijj_72@hotmail.com

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值