Tuscany SCA V1.0中的扩展机制和启动过程中的扩展点[11月29日更新]

5700人阅读 评论(9) 收藏 举报

 

 

2007年9月24日Tuscany SCA 发布了V1.0版本的实现 。本文讲述的内容使用的就是基于这个版本的,代码下载地址 http://incubator.apache.org/tuscany/sca-java-10-incubating.html

 

一、Tuscany SCA 运行时的组成

        Tuscany SCA V1.0 与前面的几个版本相比,在结构上发生了很大的变化。这种变化是意料之中的,但变化之快却是始料不及的。前面几个版本结构比较僵化、组织复杂,对变化的适应性差。如果SCA规范稍有变动,在结构上很难快速的适应,代码的变化就更不用说了。

        Tuscany SCA V1.0版本将Tucany SCA 运行时(Runtime)分成两部分,核心部分和扩展部分。核心部分的实质是利用IoC (Inversion of Control)或者DI (Dependency Injection)原理将分开的逻辑和实现,通过扩展机制实现联系和匹配;在扩展部分的结构上使用多级扩展。这种机制带来更加灵活的扩展能力和动态特性。关于Ioc或者DI可以参看相关的文章。

      通过扩展点将功能结构分解分散,减少了核心部分的对象和操作,使核心部分结构更加清晰,紧凑。这让我想起了章鱼:一个小小的头和长长的八只爪。我想不久,Tuscany SCA在结构上还会做进一步的改进。

 

二、"芝麻开门"——Tuscany SCA V1.0 的启动点

Tuscany SCA V1.0的启动是从SCADomain开始的,从上向下,由外到内逐步细化。SCADomain是一个抽象类,对应规范中的Domain组件。SCADomain通过其实现类获得Domain组件的实例。SCADomain 有几个实现类,关系如下图:

当执行 SCADomain.createInstance("someComposite") 时,SCA 的启动开始!

 

三、启动环境的准备

DefaultSCADomain是SCADomain的一个实现类。SCADomain.createInstance()通过DefaultSCADomain构造一个SCADomain类型的实例。这个DefaultSCADomain实例,包含了一个运行时(Runtime)对象——ReallySmallRuntime。

ReallySmallRuntime 主要作用就是实现扩展机制,做了大量的扩展点匹配的工作。

 

四、扩展机制

        扩展机制包含两个部分:扩展类型和扩展点。扩展类型和扩展点的关系是接口和实现类的关系。
扩展类型声明的方法在扩展点中被实现;扩展点是一个接口,而扩展点是实现了这个接口的类。

在程序中,通过什么方法调用即避免在代码中不出现扩展点(实现类),还可以通过扩展类型(接口)使用这些扩展点(实现类)呢?来看看下面的代码:

ExtensionPointRegistry registry = new DefaultExtensionPointRegistry();
WorkScheduler workScheduler 
= registry.getExtensionPoint(WorkScheduler.class);

解释一下上面两行代码:

1、ExtensionPointRegistry是一个扩展点注册接口。在ExtensionPointRegistry 中声明的方法通过DefaultExtensionPointRegistry实现,通过ExtensionPointRegistry 接口来使用。

2、通过DefaultExtensionPointRegistry的实例registry来获取扩展类型为WorkScheduler.class 的扩展点,并返回一个扩展类型的实例。

ExtensionPointRegistry在这里起到了匹配、实例化、类型转换、存储的作用。

首先,通过ServiceConfigurationUtil.getServiceClassNames()方法匹配扩展点,方法如下。

public static List<String> getServiceClassNames(ClassLoader classLoader, String name) throws IOException {
        List
<String> classNames = new ArrayList<String>();
        
for (URL url: Collections.list(classLoader.getResources("META-INF/services/" + name))) {
            InputStream is 
= url.openStream();
            BufferedReader reader 
= null;
            
try {
                reader 
= new BufferedReader(new InputStreamReader(is));
                
while (true) {
                    String line 
= reader.readLine();
                    
if (line == null)
                        
break;
                    line 
= line.trim();
                    
if (!line.startsWith("#"&& !"".equals(line)) {
                        classNames.add(line.trim());
                    }
                }
            } 
finally {
                
if (reader != null)
                    reader.close();
                
if (is != null) {
                    
try {
                        is.close();
                    } 
catch (IOException ioe) {}
                }
            }
        }
        
return classNames;
    }

其中,String name参数是 WorkScheduler.class.getName()的值,即包含全部包在内的全路径名。
WorkScheduler.class.getName() = "org.apache.tuscany.sca.work.WorkScheduler";

在("META-INF/services/"路径下,会有一个以"org.apache.tuscany.sca.work.WorkScheduler"为名称的文件,文件内容为:

# 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.core.work.Jsr237WorkScheduler

所以,ServiceConfigurationUtil.getServiceClassNames()返回的List类型的classNames里面有一个值,为:org.apache.tuscany.sca.core.work.Jsr237WorkScheduler

然后,实例化、存储、类型转换:

public <T> T getExtensionPoint(Class<T> extensionPointType) {
           List<String> classNames = ServiceConfigurationUtil.getServiceClassNames(classLoader, extensionPointType.getName());
                
if (!classNames.isEmpty()) {
                    Class
<?> extensionPointClass = Class.forName(classNames.iterator().next(), true, classLoader);
                    Constructor constructor 
= extensionPointClass.getConstructor();
                    Object extensionPoint 
= constructor.newInstance();
}
       addExtensionPoint(extensionPoint);
       return extensionPointType.cast(extensionPoint);
}

这样,通过ServiceConfigurationUtil.getServiceClassNames()查找与扩展类型匹配的扩展点,利用ExtensionPointRegistry.getExtensionPoint()方法实现实例化、类型转换、存储,实现了扩展机制。

 

五、启动过程中的扩展类型分级一览

除了上面列举的一些扩展类型之外,还有两个扩展类型需要特别说明。一个是XMLInputFactory扩展类型;另一个是ModuleActivator扩展类型,这个扩展类型不在上面的表中。

[2007年11月29日新增以下内容]

上面所列举的扩展类型,在其"META-INF/services"目录中都有对应的匹配文件,这个文件就是扩展类型类的全路径名称, 即包括完整的(package)包名的类名,但是不包括扩展名(不包括.Class).


但是XMLInputFactory这个扩展类型,你却无法在Tuscany的代码中找到任何的匹配文件。
这是因为在Tuscany引用的一个jar中包含了一个XMLInputFactory的匹配文件;
这个jar位于D:/tuscany-sca-1.0-incubating/lib的wstx-asl-3.2.1.jar/META-INF/services中.
这是XMLInputFactory扩展类型与其它扩展类型不同的地方,还有一个扩展类型也与众不同,就是ModuleActivator.

上述扩展类型都几乎只有一个匹配文件,在匹配文件中可能有几个继承了这个扩展类型的扩展点,但是数量还是相对较少.ModuleActivator拥有众多的扩展匹配文件,目前找到的有11个匹配文件.这意味着ModuleActivator提供了非常丰富和灵活的应用,这些扩展点是
org.apache.tuscany.sca.binding.ejb.EJBBindingsActivator
org.apache.tuscany.sca.binding.notification.NotificationBindingModuleActivator
org.apache.tuscany.sca.core.databinding.module.DataBindingModuleActivator
org.apache.tuscany.sca.extension.helper.impl.ImplementationsActivator
org.apache.tuscany.sca.extension.helper.impl.BindingsActivator
test.crud.module.CRUDModuleActivator
org.apache.tuscany.sca.http.jetty.module.JettyRuntimeModuleActivator
org.apache.tuscany.sca.http.tomcat.module.TomcatRuntimeModuleActivator
org.apache.tuscany.sca.host.webapp.WebAppModuleActivator
org.apache.tuscany.sca.implementation.java.module.JavaRuntimeModuleActivator
org.apache.tuscany.sca.implementation.notification.NotificationModuleActivator
org.apache.tuscany.sca.osgi.runtime.OSGiRuntimeModuleActivator

 

<待续>

0
1

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1982686次
    • 积分:24065
    • 等级:
    • 排名:第288名
    • 原创:383篇
    • 转载:143篇
    • 译文:9篇
    • 评论:495条
    博客专栏
    最新评论