[color=red]注意:本文基于tuscany-sca-1.6.1进行讲解。(未完待整理)[/color]
关于SCA概念和tuscany请参考其他文章。
本文重要介绍三点:
01 SCA中各个Component是如何组织起来,对外提供服务。
02 SCA中暴露Component为Service的方式,及其简单性。
03 配置文件和java类中一些需要注意的地方。
为了演示需要建立一些基本数据结构和接口
下面介绍重要的配置文件:
上面的配置文件演示了两种依赖装配方式
1 使用component的方式,如logService属性。使用这种方式接口LogService不需要使用@Remotable注解。
2 使用component声明的service方式,如securityService属性。使用这种方式要在接口SecurityService上使用@Remotable注解。
SCA部署文件
WEB部署文件web.xml
启动Tomcat服务器后,可以通过http://localhost:8080/tuscany/BookService?wsdl访问到WSDL文件。
注意到
不仅暴露了WebService服务,还暴露了RMI服务。
下面测试一下RMI服务是否正常运行。
对RMI服务的测试使用Spring提供的方式:
Console输出:
关于SCA概念和tuscany请参考其他文章。
本文重要介绍三点:
01 SCA中各个Component是如何组织起来,对外提供服务。
02 SCA中暴露Component为Service的方式,及其简单性。
03 配置文件和java类中一些需要注意的地方。
为了演示需要建立一些基本数据结构和接口
public class Book implements Serializable{
private static final long serialVersionUID = 1L;
private Long id;
private String bookName;
public Book(){}
public Book(Long bookId, String bookName) {
this.id = bookId;
this.bookName = bookName;
}
}
package org.max.tuscany.demo.service;
import org.max.tuscany.demo.Book;
import org.osoa.sca.annotations.Remotable;
/**
* 使用注解这个服务要暴露为WebService
* @author administrator
*
*/
@Remotable
public interface BookService {
Book getBook(Long bookId,Long userId);
}
package org.max.tuscany.demo.service;
/**
* 注意这里没有任何注解
* @author administrator
*
*/
public interface LogService {
void log(String content);
}
package org.max.tuscany.demo.service;
import org.osoa.sca.annotations.Remotable;
/**
* 使用注解,这个组件声明了Service
* @author administrator
*
*/
@Remotable
public interface SecurityService {
boolean securityCheck(Long userId);
}
package org.max.tuscany.demo.service.impl;
import org.max.tuscany.demo.Book;
import org.max.tuscany.demo.service.BookService;
import org.max.tuscany.demo.service.LogService;
import org.max.tuscany.demo.service.SecurityService;
import org.osoa.sca.annotations.Reference;
public class BookServiceImpl implements BookService {
private SecurityService securityService;
private LogService logService;
@Reference
public void setLogService(LogService logService) {
this.logService = logService;
}
@Reference
public void setSecurityService(SecurityService securityService) {
this.securityService = securityService;
}
@Override
public Book getBook(Long bookId, Long userId) {
System.out.println("BookServiceImpl.getBook is invoked");
if(securityService.securityCheck(userId)){
logService.log("ok");
return new Book(bookId,"tuscany in action");
}else{
logService.log("go back");
}
return null;
}
}
package org.max.tuscany.demo.service.impl;
import org.max.tuscany.demo.service.LogService;
public class LogServiceImpl implements LogService {
@Override
public void log(String content) {
System.out.println("LogServiceImpl.log is invoked");
}
}
package org.max.tuscany.demo.service.impl;
import org.max.tuscany.demo.service.SecurityService;
public class SecurityServiceImpl implements SecurityService{
@Override
public boolean securityCheck(Long userId) {
System.out.println("SecurityServiceImpl.securityCheck is invoked");
return true;
}
}
下面介绍重要的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
targetNamespace="http://sample" xmlns:sample="http://sample" name="Book">
<service name="BookService" promote="BookServiceComponent">
<interface.java interface="org.max.tuscany.demo.service.BookService" />
<binding.ws />
<tuscany:binding.rmi host="localhost" port="8099"
serviceName="BookService" />
</service>
<component name="BookServiceComponent">
<implementation.java class="org.max.tuscany.demo.service.impl.BookServiceImpl" />
<reference name="securityService" target="SecurityServiceComponent/SecurityService">
<interface.java interface="org.max.tuscany.demo.service.SecurityService" />
</reference>
<reference name="logService" target="LogServiceComponent"/>
</component>
<component name="SecurityServiceComponent">
<implementation.java class="org.max.tuscany.demo.service.impl.SecurityServiceImpl"/>
<service name="SecurityService">
<interface.java interface="org.max.tuscany.demo.service.SecurityService" />
</service>
</component>
<component name="LogServiceComponent">
<implementation.java class="org.max.tuscany.demo.service.impl.LogServiceImpl"/>
</component>
</composite>
上面的配置文件演示了两种依赖装配方式
1 使用component的方式,如logService属性。使用这种方式接口LogService不需要使用@Remotable注解。
2 使用component声明的service方式,如securityService属性。使用这种方式要在接口SecurityService上使用@Remotable注解。
SCA部署文件
META-INF/sca-contribution.xml
<?xml version="1.0" encoding="UTF-8"?>
<contribution xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:sample="http://sample">
<deployable composite="sample:Book"/>
</contribution>
WEB部署文件web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web
Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Apache Tuscany Calculator Web Service Sample</display-name>
<filter>
<filter-name>tuscany</filter-name>
<filter-class>org.apache.tuscany.sca.host.webapp.TuscanyServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>tuscany</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
启动Tomcat服务器后,可以通过http://localhost:8080/tuscany/BookService?wsdl访问到WSDL文件。
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="BookServiceService" targetNamespace="http://service.demo.tuscany.max.org/" xmlns:tns="http://service.demo.tuscany.max.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:SOAP="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:SOAP11="http://schemas.xmlsoap.org/wsdl/soap/">
<wsdl:types>
<xs:schema attributeFormDefault="qualified" elementFormDefault="unqualified" targetNamespace="http://service.demo.tuscany.max.org/" xmlns:tns="http://service.demo.tuscany.max.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:element name="getBookResponse"><xs:complexType><xs:sequence><xs:element minOccurs="0" name="return" nillable="true" type="tns:book"/></xs:sequence></xs:complexType></xs:element><xs:element name="getBook"><xs:complexType><xs:sequence><xs:element minOccurs="0" name="arg0" nillable="true" type="xs:long"/><xs:element minOccurs="0" name="arg1" nillable="true" type="xs:long"/></xs:sequence></xs:complexType></xs:element>
<xs:complexType name="book"><xs:sequence><xs:element minOccurs="0" name="bookName" type="xs:string"/><xs:element minOccurs="0" name="id" type="xs:long"/></xs:sequence></xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="getBookResponse">
<wsdl:part name="getBookResponse" element="tns:getBookResponse">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getBook">
<wsdl:part name="getBook" element="tns:getBook">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="BookService">
<wsdl:operation name="getBook">
<wsdl:input message="tns:getBook">
</wsdl:input>
<wsdl:output message="tns:getBookResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="BookServiceBinding" type="tns:BookService">
<SOAP:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getBook">
<SOAP:operation/>
<wsdl:input>
<SOAP:body use="literal"/>
</wsdl:input>
<wsdl:output>
<SOAP:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="BookServiceService">
<wsdl:port name="BookServicePort" binding="tns:BookServiceBinding">
<SOAP:address location="http://localhost:8080/tuscany/BookService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
注意到
<service name="BookService" promote="BookServiceComponent">
<interface.java interface="org.max.tuscany.demo.service.BookService" />
<binding.ws />
<tuscany:binding.rmi host="localhost" port="8099"
serviceName="BookService" />
</service>
不仅暴露了WebService服务,还暴露了RMI服务。
下面测试一下RMI服务是否正常运行。
对RMI服务的测试使用Spring提供的方式:
<bean id="bookService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl" value="rmi://localhost:8099/BookService"/>
<property name="serviceInterface" value="org.max.tuscany.demo.service.BookService"/>
</bean>
public class Client {
public static void main(String[] args){
ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:org/max/rmi/spring-rmi-client.xml");
BookService service = (BookService)context.getBean("bookService");
service.getBook(1L, 1L);
}
}
Console输出:
BookServiceImpl.getBook is invoked
SecurityServiceImpl.securityCheck is invoked
LogServiceImpl.log is invoked