Yesky首页| 产品报价| 行情| 手机 | 数码 | 笔记本 | 台式机 | DIY硬件 | 外设 | 网络 | 数字家庭 | 评测 | 软件 | e时代 | 游戏 | 图片 | 壁纸 | 群乐 | 社区 | 博客 | 下载
软件频道>程序开发>JavaVBVCDelphiC/C++Web开发微软专栏移动数据库程序人生软件工程|产品中心下载什么是软件架构
您现在的位置: 天极网 > 开发频道 > SCA V1.0中扩展机制的扩展点之一
全文
群乐:SOA

SCA V1.0中扩展机制的扩展点之一

2007-10-09 09:48 作者: 王洪伟 出处: 论坛整理 责任编辑:方舟

  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扩展类型,这个扩展类型不在上面的表中。

网友关注
最新上市
编辑推荐
欢迎订阅天极网RSS聚合资讯:http://www.yesky.com/index.xml