3.使用Tuscany构建SCA服务端与客户端---计算器实例
3.1 新建项目并设置Tuscany环境
右键SCAJava---》Properties---》java build path---》add External jars---》
3.2 开发SCA服务器端组件
定义一个接受并路由请求到相应模块的主入口模块
1.加法模块AddService
1 package calculator; 2 3 public interface AddService { 4 double add(double n1,double n2); 5 }
2.加法模块的实现AddServiceImpl
1 package calculator; 2 3 import java.util.logging.Level; 4 import java.util.logging.Logger; 5 6 import org.oasisopen.sca.annotation.Service; 7 8 @Service(AddService.class) 9 public class AddServiceImpl implements AddService{ 10 11 @Override 12 public double add(double n1, double n2) { 13 Logger logger = Logger.getLogger("calculator"); 14 logger.log(Level.FINEST,"Adding "+n1+" and "+n2); 15 return n1+n2; 16 } 17 18 }
3.减法模块SubtractService
1 package calculator; 2 3 public interface SubtractService { 4 double subtract(double n1,double n2); 5 }
4.减法模块的实现类SubtractServiceImpl
1 package calculator; 2 3 import java.util.logging.Level; 4 import java.util.logging.Logger; 5 6 import org.oasisopen.sca.annotation.Service; 7 8 @Service(SubtractService.class) 9 public class SubtractServiceImpl implements SubtractService{ 10 11 @Override 12 public double subtract(double n1, double n2) { 13 Logger logger = Logger.getLogger("calculator"); 14 logger.log(Level.FINEST,"Subtract "+n1+" from "+n2); 15 return n1-n2; 16 } 17 18 }
5.乘法模块MultiplyService
1 package calculator; 2 3 public interface MultiplyService { 4 double multiply(double n1,double n2); 5 }
6.乘法模块的实现类MultiplyServiceImpl
1 package calculator; 2 3 import java.util.logging.Level; 4 import java.util.logging.Logger; 5 6 import org.oasisopen.sca.annotation.Service; 7 8 @Service(MultiplyService.class) 9 public class MultiplyServiceImpl implements MultiplyService{ 10 11 @Override 12 public double multiply(double n1, double n2) { 13 Logger logger = Logger.getLogger("calculator"); 14 logger.log(Level.FINEST,"Multiply "+n1+" with "+n2); 15 return n1*n2; 16 } 17 18 }
7.除法模块DivideService
1 package calculator; 2 3 public interface DivideService { 4 double divide(double n1,double n2); 5 }
8.除法模块的实现类DivideServiceImpl
1 package calculator; 2 3 import java.util.logging.Level; 4 import java.util.logging.Logger; 5 6 import org.oasisopen.sca.annotation.Service; 7 8 @Service(DivideService.class) 9 public class DivideServiceImpl implements DivideService{ 10 11 @Override 12 public double divide(double n1, double n2) { 13 Logger logger = Logger.getLogger("calculator"); 14 logger.log(Level.FINEST,"Drividing "+n1+" with "+n2); 15 return n1/n2; 16 } 17 18 }
9.主模块CalculatorService
1 package calculator; 2 3 public interface CalculatorService { 4 double add(double n1,double n2); 5 double subtract(double n1,double n2); 6 double multiply(double n1,double n2); 7 double divide(double n1,double n2); 8 }
10.主模块的实现CalculatorServiceImpl
1 package calculator; 2 3 import org.oasisopen.sca.annotation.Reference; 4 import org.oasisopen.sca.annotation.Service; 5 6 @Service(CalculatorService.class) 7 public class CalculatorServiceImpl implements CalculatorService{ 8 9 private AddService addService; 10 private SubtractService subtractService; 11 private MultiplyService multiplyService; 12 private DivideService divideService; 13 14 @Reference 15 public void setAddService(AddService addService) { 16 this.addService = addService; 17 } 18 @Reference 19 public void setSubtractService(SubtractService subtractService) { 20 this.subtractService = subtractService; 21 } 22 @Reference 23 public void setMultiplyService(MultiplyService multiplyService) { 24 this.multiplyService = multiplyService; 25 } 26 @Reference 27 public void setDivideService(DivideService divideService) { 28 this.divideService = divideService; 29 } 30 31 @Override 32 public double add(double n1, double n2) { 33 return addService.add(n1, n2); 34 } 35 36 @Override 37 public double subtract(double n1, double n2) { 38 return subtractService.subtract(n1, n2); 39 } 40 41 @Override 42 public double multiply(double n1, double n2) { 43 return multiplyService.multiply(n1, n2); 44 } 45 46 @Override 47 public double divide(double n1, double n2) { 48 return divideService.divide(n1, n2); 49 } 50 51 }
3.3 传统的调用方式:但是这样没有用于Tuscany运行环境,也没有使用Web Service接口的方式
1 package calculator; 2 3 public class Test { 4 5 public static void main(String[] args) { 6 7 CalculatorServiceImpl calculatorServiceImpl = new CalculatorServiceImpl(); 8 AddService addService = new AddServiceImpl(); 9 calculatorServiceImpl.setAddService(addService); 10 System.out.println("10+5="+calculatorServiceImpl.add(10, 5)); 11 } 12 }
3.4 配置SCA服务器端Calculator.composite
1 <?xml version="1.0" encoding="UTF-8"?> 2 <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" 3 xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1" 4 targetNamespace="http://sample" 5 xmlns:sample="http://sample" 6 xmlns:scallop="http://scallop/xmlns/sca/1.1" 7 name="Calculator" > 8 9 10 <component name="AddServiceComponent"> 11 <implementation.java class="calculator.AddServiceImpl" /> 12 </component> 13 <component name="SubtractServiceComponent"> 14 <implementation.java class="calculator.SubtractServiceImpl" /> 15 </component> 16 <component name="MultiplyServiceComponent"> 17 <implementation.java class="calculator.MultiplyServiceImpl" /> 18 </component> 19 <component name="DivideServiceComponent"> 20 <implementation.java class="calculator.DivideServiceImpl" /> 21 </component> 22 23 <component name="CalculatorServiceComponent"> 24 <implementation.java class="calculator.CalculatorServiceImpl" /> 25 <reference name="addService" target="AddServiceComponent" /> 26 <reference name="subtractService" target="SubtractServiceComponent" /> 27 <reference name="multiplyService" target="MultiplyServiceComponent" /> 28 <reference name="divideService" target="DivideServiceComponent" /> 29 </component> 30 31 </composite>
Tuscany SCA运行时解析XML Composite文件中的信息,然后用这些信息创建Service对象,
并填充到CalculatorServiceImpl.java中
@Reference注解,这个注解告诉我们Tuscany SCA这个属性需要自动注入。等价于下面的代码
1 package calculator; 2 3 public class Test { 4 5 public static void main(String[] args) { 6 7 CalculatorServiceImpl calculatorServiceImpl = new CalculatorServiceImpl(); 8 AddService addService = new AddServiceImpl(); 9 calculatorServiceImpl.setAddService(addService); 10 System.out.println("10+5="+calculatorServiceImpl.add(10, 5)); 11 } 12 }
为了让Tuscany知道Cauculator.composite配置,需要配置
META-INF/sca-contribution.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <contribution xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" 3 xmlns:sample="http://sample"> 4 <deployable composite="sample:Calculator"/> 5 </contribution>
至此,完成了服务器端的开发与配置
3.5 开发SCA客户端
开发完服务端,就可以使用SCADomain来加载配置文件Calculator.composite
1 package calculator; 2 3 import org.apache.tuscany.sca.node.Node; 4 import org.apache.tuscany.sca.node.NodeFactory; 5 6 public class CalculatorClient { 7 public static void main(String[] args) { 8 9 //创建节点 10 Node node = NodeFactory.newInstance().createNode(); 11 //启动 12 node.start(); 13 //取得对象 14 CalculatorService calculatorService=node.getService(CalculatorService.class, "CalculatorServiceComponent"); 15 16 //计算 17 System.out.println("10+5="+calculatorService.add(10, 5)); 18 System.out.println("10-5="+calculatorService.subtract(10, 5)); 19 System.out.println("10*5="+calculatorService.multiply(10, 5)); 20 System.out.println("10/5="+calculatorService.divide(10, 5)); 21 22 //停止 23 node.stop(); 24 } 25 }
控制台信息:
1 三月 09, 2016 8:55:52 下午 org.apache.tuscany.sca.node.impl.NodeImpl start 2 信息: Starting node: http://tuscany.apache.org/sca/1.1/nodes/default0 domain: default 3 三月 09, 2016 8:55:52 下午 org.apache.tuscany.sca.node.impl.NodeFactoryImpl loadContributions 4 信息: Loading contribution: file:/F:/daydaystudy/SCAJava/bin/ 5 三月 09, 2016 8:55:56 下午 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl addEndpoint 6 信息: Add endpoint - binding.sca - AddServiceComponent/AddService 7 三月 09, 2016 8:55:56 下午 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl addEndpoint 8 信息: Add endpoint - binding.sca - SubtractServiceComponent/SubtractService 9 三月 09, 2016 8:55:56 下午 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl addEndpoint 10 信息: Add endpoint - binding.sca - MultiplyServiceComponent/MultiplyService 11 三月 09, 2016 8:55:56 下午 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl addEndpoint 12 信息: Add endpoint - binding.sca - DivideServiceComponent/DivideService 13 三月 09, 2016 8:55:56 下午 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl addEndpoint 14 信息: Add endpoint - binding.sca - CalculatorServiceComponent/CalculatorService 15 10+5=15.0 16 10-5=5.0 17 10*5=50.0 18 10/5=2.0 19 三月 09, 2016 8:55:56 下午 org.apache.tuscany.sca.node.impl.NodeImpl stop 20 信息: Stopping node: http://tuscany.apache.org/sca/1.1/nodes/default0 21 三月 09, 2016 8:55:56 下午 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl removeEndpoint 22 信息: Remove endpoint - binding.sca - AddServiceComponent/AddService 23 三月 09, 2016 8:55:56 下午 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl removeEndpoint 24 信息: Remove endpoint - binding.sca - SubtractServiceComponent/SubtractService 25 三月 09, 2016 8:55:56 下午 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl removeEndpoint 26 信息: Remove endpoint - binding.sca - MultiplyServiceComponent/MultiplyService 27 三月 09, 2016 8:55:56 下午 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl removeEndpoint 28 信息: Remove endpoint - binding.sca - DivideServiceComponent/DivideService 29 三月 09, 2016 8:55:56 下午 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl removeEndpoint 30 信息: Remove endpoint - binding.sca - CalculatorServiceComponent/CalculatorService
工程目录:
3.7 打包SCAJava.zip
4.使用Tuscany构建分布式Web服务---HelloWorld实例
以上的Calculator.composite负责将服务器端的POJO类发布为服务SCA服务,然后通过java类调用SCA服务的方式
来获得服务端的组件
4.1 创建SCA服务器端发布Web服务
1.创建SCA服务器端
服务接口HelloWorld.java
1 package helloworld; 2 3 import org.oasisopen.sca.annotation.Remotable; 4 5 @Remotable 6 public interface HelloWorld { 7 String sayHello(String name); 8 }
@Remotable:让我们把服务接口发布为远程服务
接口的实现HelloWorldImpl.java
1 package helloworld; 2 3 public class HelloWorldImpl implements HelloWorld{ 4 5 @Override 6 public String sayHello(String name) { 7 System.out.println("客户端调用:"+name); 8 return "Hello "+name+" !"; 9 } 10 11 }
2.配置SCA服务
配置文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" 3 xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1" 4 targetNamespace="http://sample" 5 xmlns:sample="http://sample" 6 xmlns:scallop="http://scallop/xmlns/sca/1.1" 7 name="HelloWorld" > 8 9 10 <component name="HelloWorldComponent"> 11 <implementation.java class="helloworld.HelloWorldImpl" /> 12 <service name="HelloWorld"> 13 <binding.ws uri="http://localhost:8080/HelloWorld"/> 14 </service> 15 </component> 16 17 18 </composite>
<bingding.ws>将HelloWorld组件发布为Web服务,地址为http://localhost:8080/HelloWorld
添加SCA配置文件:META-INF/sca-contribution.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <contribution xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" 3 xmlns:sample="http://sample"> 4 <deployable composite="sample:HelloWorld/> 5 </contribution>
3.启动SCA服务器端
1 package helloworld; 2 3 import org.apache.tuscany.sca.node.Node; 4 import org.apache.tuscany.sca.node.NodeFactory; 5 6 public class HelloWorldServer { 7 8 public static void main(String[] args) { 9 HelloWorldServer server = new HelloWorldServer(); 10 server.start(); 11 try{ 12 while(true){ 13 Thread.sleep(Long.MAX_VALUE); 14 } 15 }catch(InterruptedException e){ 16 System.out.println(e); 17 } 18 } 19 20 private void start() { 21 //创建节点 22 Node node = (Node) NodeFactory.newInstance().createNode(); 23 //启动 24 node.start(); 25 } 26 }
控制台:
1 三月 09, 2016 9:56:12 下午 org.apache.tuscany.sca.node.impl.NodeImpl start 2 信息: Starting node: http://tuscany.apache.org/sca/1.1/nodes/default0 domain: default 3 三月 09, 2016 9:56:12 下午 org.apache.tuscany.sca.node.impl.NodeFactoryImpl loadContributions 4 信息: Loading contribution: file:/F:/daydaystudy/SCAWSServer/bin/ 5 三月 09, 2016 9:56:17 下午 org.mortbay.log.Slf4jLog info 6 信息: Logging to org.slf4j.impl.JDK14LoggerAdapter(org.mortbay.log) via org.mortbay.log.Slf4jLog 7 三月 09, 2016 9:56:18 下午 org.apache.tuscany.sca.http.jetty.JettyLogger info 8 信息: jetty-6.1.26 9 三月 09, 2016 9:56:19 下午 org.apache.tuscany.sca.http.jetty.JettyLogger info 10 信息: Started SelectChannelConnector@localhost:8080 11 三月 09, 2016 9:56:19 下午 org.apache.tuscany.sca.http.jetty.JettyServer addServletMapping 12 信息: Added Servlet mapping: http://localhost:8080/HelloWorld 13 三月 09, 2016 9:56:19 下午 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl addEndpoint 14 信息: Add endpoint - binding.ws - http://localhost:8080/HelloWorld
4.测试Web服务
1 http://localhost:8080/HelloWorld?wsdl
这样就已经通过Tuscany创建了Web Service
4.2 通过SCA客户端访问远程Web服务
实现分布式应用的访问,为了通过分布式程序来访问刚才的Web服务
安装服务端的方式把代码赋值过来
1.配置客户端组件HelloWorld.composite
1 <?xml version="1.0" encoding="UTF-8"?> 2 <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" 3 xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1" 4 targetNamespace="http://sample" 5 xmlns:sample="http://sample" 6 xmlns:scallop="http://scallop/xmlns/sca/1.1" 7 name="HelloWorld" > 8 9 10 <component name="HelloWorldComponent"> 11 <implementation.java class="helloworld.HelloWorldImpl" /> 12 <reference name="HelloWorld"> 13 <binding.ws uri="http://localhost:8080/HelloWorld"/> 14 </reference> 15 </component> 16 17 18 </composite>
2.添加组件引用HelloWorldImpl.java
1 package helloworld; 2 3 import org.oasisopen.sca.annotation.Reference; 4 5 public class HelloWorldImpl implements HelloWorld{ 6 7 private HelloWorld helloWorld; 8 9 @Reference 10 public void setHelloWorld(HelloWorld helloWorld){ 11 this.helloWorld = helloWorld; 12 } 13 public String sayHello(String name) { 14 return helloWorld.sayHello(name); 15 } 16 17 }
3.开发客户端HelloWorldClient.java
1 package helloworld; 2 3 import org.apache.tuscany.sca.node.Node; 4 import org.apache.tuscany.sca.node.NodeFactory; 5 6 public class HelloWorldClient { 7 8 public static void main(String[] args) { 9 //创建节点 10 Node node = (Node) NodeFactory.newInstance().createNode(); 11 //启动 12 node.start(); 13 //取得对象 14 HelloWorld helloWorld = node.getService(HelloWorld.class,"HelloWorldComponent"); 15 System.out.println(helloWorld.sayHello("world")); 16 //停止 17 node.stop(); 18 } 19 }
4.运行客户端
1 三月 09, 2016 10:15:16 下午 org.apache.tuscany.sca.node.impl.NodeImpl start 2 信息: Starting node: http://tuscany.apache.org/sca/1.1/nodes/default0 domain: default 3 三月 09, 2016 10:15:17 下午 org.apache.tuscany.sca.node.impl.NodeFactoryImpl loadContributions 4 信息: Loading contribution: file:/F:/daydaystudy/SCAWSClient/bin/ 5 三月 09, 2016 10:15:20 下午 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl addEndpoint 6 信息: Add endpoint - binding.sca - HelloWorldComponent/HelloWorld 7 三月 09, 2016 10:15:22 下午 org.apache.tuscany.sca.node.impl.NodeImpl stop 8 信息: Stopping node: http://tuscany.apache.org/sca/1.1/nodes/default0 9 三月 09, 2016 10:15:22 下午 org.apache.tuscany.sca.core.assembly.impl.DomainRegistryImpl removeEndpoint 10 信息: Remove endpoint - binding.sca - HelloWorldComponent/HelloWorld 11 Hello world !
服务端:
1 客户端调用:world
通过SCAWSServer发布了Web服务,SCAWSClient通过组件配置了引用了该Web服务
4.3 打包SCAWSServer.zip和SCAWSClient.zip