实习期间mentor让看看Tuscany——apache的一个顶级项目。之前一直没有接触过,听mentor说了下用途过后,感觉其像是alibaba的分布式服务框架Dubbo,简要看了看,似乎和RMI也有相关性。总之它也是面向服务的分布式框架。经过一下午的尝试,发现Tuscany 2和Tuscany 1还是有比较大的不同(API方面、设计思想没有深入研究不知道),网上关于Tuscany的资料也不多,所以在此写文章mark一下。
Tuscany 1的API参考这位博主http://blog.csdn.net/ajun_studio/article/details/7770023
1. 准备
首先是在工程中引入Tuscany 2.0.1的jar包,从一个Apache的China镜像上不难找到(PS:Tuscany 1在官网上已经不维护了)。
工程需要实现客户端调用远程服务器端的服务的功能。该项目中调用远程完成“加”的功能。
2. 入门
首先添加IAdd接口
package com.ajun.tuscany.server;
public interface IAdd {
double add(double n1,double n2);
}
然后是实现类Addpackage com.ajun.tuscany.server;
public class Add implements IAdd {
@Override
public double add(double n1, double n2) {
// TODO Auto-generated method stub
return n1 + n2;
}
}
加减乘除都属于“计算”类,此处为了简便,只实现“加”方法。然后是“计算”的接口。package com.ajun.tuscany.server;
public interface ICalculator {
double add(double n1, double n2);
}
然后是“计算”的实现,注意一定要在setter中加入@Reference,否则会报错,这里类似于Spring的注入。package com.ajun.tuscany.server;
import org.oasisopen.sca.annotation.Reference;
public class Calculator implements ICalculator {
private IAdd add;
public IAdd getAdd() {
return add;
}
@Reference
public void setAdd(IAdd add) {
this.add = add;
}
@Override
public double add(double n1, double n2) {
// TODO Auto-generated method stub
return this.add.add(n1, n2);
}
}
到此,基本的业务逻辑类就编写好了,接下来,是Tuscany中重要的配置文件,即XXX.composite,其本质也是一个xml。如果不是面向分布式服务,该xml文件结构类似Spring的application.xml。下面是Calculator.composite,注意配置文件中reference,name标记为add,应该也是同Spring的大写首字母规则,通过settrt注入。<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1"
targetNamespace="http://sample"
xmlns:sample="http://sample"
xmlns:scallop="http://scallop/xmlns/sca/1.1"
name="Calculator" >
<component name="CalculatorServiceComponent">
<implementation.java class="com.ajun.tuscany.server.Calculator" />
<reference name="add" target="AddComponent"/>
</component>
<component name="AddComponent">
<implementation.java class="com.ajun.tuscany.server.Add" />
</component>
</composite>
最后是运行main的类package com.ajun.tuscany.server;
import org.apache.tuscany.sca.node.Node;
import org.apache.tuscany.sca.node.NodeFactory;
public class StartService {
public static void main(String[] args) {
Node node = NodeFactory.newInstance().createNode(
"Calculator.composite");
node.start();
System.out.println("service启动");
ICalculator c = node.getService(Calculator.class,
"CalculatorServiceComponent");
System.out.println(c.add(2, 2));
}
}
运行输出如下2014-11-10 17:39:24 org.apache.tuscany.sca.node.impl.NodeFactoryImpl loadContributions
信息: Loading contribution: file:/E:/HuRanjie/EclipseWorkspace/Calculatoer_01/bin/
2014-11-10 17:39:24 org.apache.tuscany.sca.host.rmi.DefaultRMIHost registerService
信息: RMI service registered: rmi://127.0.0.1:8099/CalculatorRMIService
2014-11-10 17:39:24 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl addEndpoint
信息: Add endpoint - binding.rmi - rmi://127.0.0.1:8099/CalculatorRMIService
2014-11-10 17:39:24 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl addEndpoint
信息: Add endpoint - binding.sca - AddComponent/Add
service启动
4.0
3. 远程调用rmi
上面并没有将“计算”类作为一个服务,暴露给远程调用,只是实现了本地的装配。下面将其作为服务给远程调用,后面可以看到,只需要暴露一个包括host、port、serviceName
首先,修改配置文件,修改为如下样子——在本地(127.0.0.1)的8099端口暴露出名字为CalculatorRMIService的服务
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1"
targetNamespace="http://sample"
xmlns:sample="http://sample"
xmlns:scallop="http://scallop/xmlns/sca/1.1"
name="Calculator" >
<component name="CalculatorServiceComponent">
<implementation.java class="com.ajun.tuscany.server.Calculator" />
<service name="Calculator">
<interface.java interface="com.ajun.tuscany.server.ICalculator"/>
<tuscany:binding.rmi uri="rmi://127.0.0.1:8099/CalculatorRMIService"/>
</service>
<reference name="add" target="AddComponent"/>
</component>
<component name="AddComponent">
<implementation.java class="com.ajun.tuscany.server.Add" />
</component>
</composite>
服务器端的main主要功能是启动该服务,如下
package com.ajun.tuscany.server;
import org.apache.tuscany.sca.node.Node;
import org.apache.tuscany.sca.node.NodeFactory;
public class StartService {
public static void main(String[] args) {
Node node = NodeFactory.newInstance().createNode(
"Calculator.composite");
node.start();
System.out.println("service启动");
}
}
客户端通过rmi调用服务器端的服务,来实现功能,如下
package com.ajun.tuscany.client;
import java.rmi.Naming;
import com.ajun.tuscany.server.ICalculator;
public class CalculatorClient {
public static void main(String[] args) throws Exception {
ICalculator c= (ICalculator) Naming.lookup("//127.0.0.1:8099/CalculatorRMIService");
System.out.println(c.add(1, 2));
}
}
启动服务端输出
2014-11-10 18:00:30 org.apache.tuscany.sca.node.impl.NodeImpl start
信息: Starting node: http://tuscany.apache.org/sca/1.1/nodes/default0 domain: default
2014-11-10 18:00:30 org.apache.tuscany.sca.node.impl.NodeFactoryImpl loadContributions
信息: Loading contribution: file:/E:/HuRanjie/EclipseWorkspace/Calculatoer_01/bin/
2014-11-10 18:00:31 org.apache.tuscany.sca.host.rmi.DefaultRMIHost registerService
信息: RMI service registered: rmi://127.0.0.1:8099/CalculatorRMIService
2014-11-10 18:00:31 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl addEndpoint
信息: Add endpoint - binding.rmi - rmi://127.0.0.1:8099/CalculatorRMIService
2014-11-10 18:00:31 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl addEndpoint
信息: Add endpoint - binding.sca - AddComponent/Add
service启动
客户端输出
3.0