Tuscany SCA案例分析(转)

2024-03-19 23:08
文章标签 分析 案例 sca tuscany

本文主要是介绍Tuscany SCA案例分析(转),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Tuscany SCA案例分析(一)(连载中...)

给了好久的承诺 , 前些日子一直在学习一些 SOA 方面相关的资料 , 包括 Web Service 基础 --WSDL SOAP UDDI , 这些是经典的 Web service 规范 , 同时学习了些相关的 XML-RPC 以及 WS-BPEL 等相关的内容,其中发现要看明白这些东西必须要先学好 XML 以及 XML Schema 的基础知识 , 然后又开始学习了 , 发现可以看明白一些东西了 , 当然还看了些 SOA 设计方面的原则的资料了 , 这些会在学习以及后续的分析整理出来 . 现在有了高层的设计指导 , 当然需要具体的编码技术支持了 , 否则再好的设计也无法实现了 , 所以开始了对 Tuscany SCA 的编码学习 . 为了让读者更有思路跟上节奏 , 以后的连载文章都将按照如下顺序介绍 :1  解析设计图  2 具体编码  3 分析以及总结

       为了让编码更容易,Java编程怎么能缺少Javadoc,否则无法查看帮助文档是很郁闷的事情,于是我先安装了maven2.0.5,这个在本人翻译的 <如何进入Java SCA软件的开发>文章中提到了,高于Maven2.0.5版本可能会出现错误,下面就配置maven2.0.5,下载maven2.0.5,直接解压(我这里是解压到d盘了)

下面配置maven的可执行文件到Path

然后进入tuscany源代码的解压文件夹,

-apache-tuscany-sca-1.0.1-incubating-src

 |-- sca

     |-- demos         SCA 演示应用程序

     |-- distribution     SCA 发布程序

     |-- itest           SCA 集成测试

     |-- modules       SCA 实现的各个模块 (core, runtimes, contribution, extensions                                 等等)

     |-- samples       SCA 样例程序

     |-- tools          SCA 工具 (Eclipse插件, wsdl2java, java2wsdl等等)

这是我环境的结构,在dos窗口中进入sca目录,然后直接使用mvn命令

mvn javadoc:javadoc

来生成Javadoc,经过一段时间,就会在modules里面的每个相应目录下的target文件夹下生成site文件夹,里面就是javaAPIdoc了,我们需要的就是这些javadoc,因为我们后面的编程会用到,用得比较多的是modules/domain-api/target/site/apidocs里的帮助信息了。

里面有SCADomainFactorySCADomain类的相关信息。

好的,万事具备,只欠东风了。我们开始我们的编码旅程吧。顺便说下,为了方便编辑.composite文件,我根据网上的<Eclipse开发Apache Tuscany上的SCA应用>文章下载了个eclipse插件,这里就不多说了。

开始了,我们先从最简单的calculator开始,先解析下设计图,如下:

在这个案例中,运行环境是每个组件都在一个node上,前台的CalculatorServiceComponent组件分别引用到了AddServiceComponentSubstractServiceComponentMultiplyServiceComponent以及DivideServiceComponent四个组件。他们之间的引用关系由SCA运行时自动注入。可以认为后面的四个具体的服务是“原子服务”(它完全由自己实现),而前台的CalculatorServiceComponent组件则是组合出来的服务,虽然它只是简单的做了个功能代理而已,但它完全可以加入自己的附加功能。

       好了,设计图的分析到此为止,我们可以开始进行编码了,来学习学习如何用SCA javaAPI来实现。打开eclipse,新建一个普通的java project,在建工程的时候可以加入Junit3的库和MyTuscany用户库(该库的设置在我的< Tuscany初探>的附录中给出了设置方法)

我设置了target文件夹为默认的输出路径,这里无所谓的。下一步建立组件的逻辑功能代码。我这里为了保持一致,建立了calculator包,在该包下分别建立加、减、乘、除的服务接口文件AddService.javaSubtractService.javaMultiplyService.javaDivideService.java。这四个Java接口都是本地的。

AddService.java内容如下:

package calculator;

 

/**

 * The Add service interface

 */

public interface AddService {

 

    double add(double n1, double n2);

 

}

SubtractService.java内容如下:

package calculator;

/**

 * The interface for the multiply service

 */

public interface SubtractService {

    double subtract(double n1, double n2);

}

MultiplyService.java内容如下:

package calculator;

/**

 * The interface for the multiply service

 */

public interface MultiplyService {

    double multiply(double n1, double n2);

}

DivideService.java内容如下:

package calculator;

/**

 * The divide service interface

 */

public interface DivideService {

    double divide(double n1, double n2);

}

后面的实现很简单的,就是利用double类型的+ - * /号来进行运算,这里就不给出具体实现了,仅给出java文件名,我的命名规则是在相应的Service后面加上Impl就成了实现的java代码文件名。再给出前台服务组件的CalculatorService.java的接口代码如下:

package calculator;

/**

 * The Calculator service interface.

 */

public interface CalculatorService {

    double add(double n1, double n2);

    double subtract(double n1, double n2);

    double multiply(double n1, double n2);

    double divide(double n1, double n2);

}

CalculatorServiceImpl.java内容如下:

package calculator;

import org.osoa.sca.annotations.Reference;

/**

 * An implementation of the Calculator service.

 */

public class CalculatorServiceImpl implements CalculatorService {

    private AddService addService;

    private SubtractService subtractService;

    private MultiplyService multiplyService;

    private DivideService divideService;

    @Reference

    public void setAddService(AddService addService) {

        this.addService = addService;

    }

    @Reference

    public void setSubtractService(SubtractService subtractService) {

        this.subtractService = subtractService;

    }

    @Reference

    public void setDivideService(DivideService divideService) {

        this.divideService = divideService;

    }

    @Reference

    public void setMultiplyService(MultiplyService multiplyService) {

        this.multiplyService = multiplyService;

    }

    public double add(double n1, double n2) {

        return addService.add(n1, n2);

    }

    public double subtract(double n1, double n2) {

        return subtractService.subtract(n1, n2);

    }

    public double multiply(double n1, double n2) {

        return multiplyService.multiply(n1, n2);

    }

    public double divide(double n1, double n2) {

        return divideService.divide(n1, n2);

    }

}

该类中有相应引用的服务接口,并且在这些接口实例setter函数注入时,都有@Reference注解。不用担心,tuscany SCA运行时会自动注入的。

    到目前为止,所有的服务组件逻辑业务功能都用Java实现了。该是时候给出.composite文件了,该文件展示了各个服务组件之间的引用关系以及构件与组件的组合关系。直接在src下建立Calculator.composite文件,这个文件名可以自己取,不一定要和我的一致。

其内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"

    xmlns:t="http://tuscany.apache.org/xmlns/sca/1.0"

    xmlns:c="http://Calculator" name="Calculator">

<!-- 这里的name就是composite的名字,其中默认名称空间与"http://www.osoa.org/xmlns/sca/1.0"相关

       用插件生成的composite文件会在composite元素头标签给出一个c名称空间,其与"http://Calculator"关联

    -->

    <component name="CalculatorServiceComponent">

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

       <reference name="addService" target="AddServiceComponent" />

        <reference name="subtractService" target="SubtractServiceComponent" />

        <reference name="multiplyService" target="MultiplyServiceComponent" />

        <reference name="divideService" target="DivideServiceComponent" />

    </component>

    <component name="AddServiceComponent">

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

    </component>

    <component name="SubtractServiceComponent">

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

    </component>

    <component name="MultiplyServiceComponent">

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

    </component>

    <component name="DivideServiceComponent">

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

    </component>

</composite>

    名叫"Calculator"的构件中含有五个组件CalculatorServiceComponentAddServiceComponent SubtractServiceComponent、MultiplyServiceComponentDivideServiceComponent其中CalculatorServiceComponent引用到其他四个组件每个组件都是用java实现的<implementation.java具体的class类个不相同。这里要注意的是CalculatorServiceComponent的引用书写,例如<referencename="addService" target="AddServiceComponent" />referencename要是该实现类里需要注入的属性名,这里是CalculatorServiceImpl类代码体的private AddService addService;代码行的addServicetarget就是后面的component名字<component name="AddServiceComponent">

        好了现在服务的业务逻辑实现和装配都给出来了,那么如何才能让SCA运行时运行起来,装配出服务,并向外界提供服务呢?客户又如何实现调用服务呢?这里给出的代码只是给出了与服务方运行在同一个JVM里的客户程序。其代码实现如下: 

package calculator;

 import org.apache.tuscany.sca.host.embedded.SCADomain;

 /**

 * This client program shows how to create an SCA runtime, start it,

 * and locate and invoke a SCA component

 */

public class CalculatorClient {

    public static void main(String[] args) throws Exception {

        SCADomain scaDomain = SCADomain.newInstance("Calculator.composite");

        CalculatorService calculatorService =

            scaDomain.getService(CalculatorService.class,"CalculatorServiceComponent");

        // Calculate

        System.out.println("3 + 2=" + calculatorService.add(3, 2));

        System.out.println("3 - 2=" + calculatorService.subtract(3, 2));

        System.out.println("3 * 2=" + calculatorService.multiply(3, 2));

        System.out.println("3 / 2=" + calculatorService.divide(3, 2));

        scaDomain.close();

    }

}

现在要用到前面的javadoc了,这里的main函数中用了SCADomain类的newInstance,传入了composite文件的路径,这里 是相对路径。eclipse中会到src中找Calculator.composite文件。然后利用scaDomaingetService方法得到 CalculatorService接口的实例,这个其实有点象Spring 了,spring也是一开始先得到applicationContext,这里会传入applicationContext.xml配置文件路径地址,然 后通过applicationContext实例用getBean获得bean。如果说spring是类的装配和生产工厂,那么就可以说Tuscany 服务的装配和生产工厂。接着就可以使用calculatorService的加、减、乘、除功能了。最后关闭SCADomain对象就可以了。

这篇关于Tuscany SCA案例分析(转)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/827520

相关文章

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

使用Navicat工具比对两个数据库所有表结构的差异案例详解

《使用Navicat工具比对两个数据库所有表结构的差异案例详解》:本文主要介绍如何使用Navicat工具对比两个数据库test_old和test_new,并生成相应的DDLSQL语句,以便将te... 目录概要案例一、如图两个数据库test_old和test_new进行比较:二、开始比较总结概要公司存在多

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

SpringBoot实现动态插拔的AOP的完整案例

《SpringBoot实现动态插拔的AOP的完整案例》在现代软件开发中,面向切面编程(AOP)是一种非常重要的技术,能够有效实现日志记录、安全控制、性能监控等横切关注点的分离,在传统的AOP实现中,切... 目录引言一、AOP 概述1.1 什么是 AOP1.2 AOP 的典型应用场景1.3 为什么需要动态插

Golang操作DuckDB实战案例分享

《Golang操作DuckDB实战案例分享》DuckDB是一个嵌入式SQL数据库引擎,它与众所周知的SQLite非常相似,但它是为olap风格的工作负载设计的,DuckDB支持各种数据类型和SQL特性... 目录DuckDB的主要优点环境准备初始化表和数据查询单行或多行错误处理和事务完整代码最后总结Duck

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

MySQL不使用子查询的原因及优化案例

《MySQL不使用子查询的原因及优化案例》对于mysql,不推荐使用子查询,效率太差,执行子查询时,MYSQL需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响,本文给大家... 目录不推荐使用子查询和JOIN的原因解决方案优化案例案例1:查询所有有库存的商品信息案例2:使用EX

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re