1. Component, service, reference and property naming conventions
SCA规范名没有定义它们的命名规范,下面只是推荐的命名格式:
(1) Component,Service以大写字母开头,驼峰式命名;
(2) Reference,property默认以小写字母开头。
2. 组合定义文件
组合是被用来定义服务、组件和引用的容器。 它被用来将SCA制品装配成逻辑分组的组件。SCA 组合可粗略的认
为是和Spring中通常被称作应用程序上下文(application context)的XMl文件类似的东西,而component元
素,则和Spring配置文件中定义的bean元素在功能上类似。
SCA组合装配XML示例,problemMgmt.composite.xml:
<?xml version="1.0" encoding="ISO-8859-15"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:hw="http://opensoa.book.chapter3" name="ProblemManagementComposite"
targetNamespace="http://opensoa.book.chapter3">
<service name="ProblemTicketComponent" promote="ProblemTicketComponent">
<binding.ws uri="http://localhost:8085/ProblemTicketService"/>
</service>
<component name="ProblemTicketComponent">
<implementation.java class="opensoa.book.chapter3.impl.ProblemTicketComponentImpl"/>
<reference name="createTicket" target="CreateTicketComponent"/>
</component>
<component name="CreateTicketComponent">
<implementation.java class="opensoa.book.chapter3.impl.CreateTicketComponentImpl"/>
</component>
</composite>
启动该装配集的方式:
SCADomain scaDomain = SCADomain.newInstance("problemMgmt.composite");
3. 配置组件
组件指的是通过代码表达的业务功能,是应用程序构建的单元;组件既可以提供服务,也可以使用服务。
ProblemTicketComponentImpl的Java实现:
@Service(ProblemTicketComponent.class)
public class ProblemTicketComponentImpl implements ProblemTicketComponent {
private CreateTicketComponent createTicket;
public int createTicket(TicketDO ticket) {
System.out.println(ticket.toString());
return createTicket.create(ticket);
}
@Reference
public void setCreateTicket( CreateTicketComponent createTicket) {
this.createTicket = createTicket;
}
}
@Remotable
public interface ProblemTicketComponent {
public int createTicket(TicketDO ticket);
}
public class CreateTicketComponentImpl implements CreateTicketComponent {
public int create(TicketDO ticket) {
Random r = new Random();
return r.nextInt(300000);
}
}
4. 定义服务
通过接口类定义的方法签名或interface.wsdl来规定哪些操作被允许,这种做法在容器级别会得到强制保障,是
安全的;而简单的创建 一个自定义的、只包含哪些你想暴露的操作的WSDL的做法,是不安全的,因为知道源码
的人还是可以调用哪些没有被显示暴露出来的操作。
<service name="ProblemTicketComponent" promote="ProblemTicketComponent">
<interface.java
interface="opensoa.book.chapter3_23.ProblemTicketComponent" />
<binding.ws uri="http://localhost:8085/ProblemTicketService" />
</service>
5. 使用属性
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
targetNamespace="http://opensoa.book.chapter3"
xmlns:hw="http://opensoa.book.chapter3"
name="ProblemManagementComposite">
<!-- VARIANT 1
<property name="username">[email protected]</property>
<property name="password">mypassword1</property>
-->
<!-- VARIANT 2 -->
<property name="credentials" type="hw:CredentialsType">
<Credentials>
<username>[email protected]</username>
<password>mypassword1</password>
</Credentials>
</property>
<service name="ProblemTicketComponent" promote="ProblemTicketComponent">
<binding.ws uri="http://localhost:8085/ProblemTicketService" />
</service>
<component name="ProblemTicketComponent">
<implementation.java
class="opensoa.book.chapter3_24.impl.ProblemTicketComponentImpl" />
<!-- use w/VARIANT 1
<property name="username" source="$username" />
<property name="password" source="$password" />
-->
<!-- use w/VARIANT 2 -->
<property name="username" source="$credentials/*[local-name()='Credentials']/
*[local-name()='username']" />
<property name="password" source="$credentials/*[local-name()='Credentials']/
*[local-name()='password']" />
<reference name="createTicket" target="CreateTicketComponent" />
</component>
<component name="CreateTicketComponent">
<implementation.java
class="opensoa.book.chapter3_24.impl.CreateTicketComponentImpl" />
</component>
</composite>
@Service(ProblemTicketComponent.class)
public class ProblemTicketComponentImpl implements ProblemTicketComponent {
/*第一种使用方式*/
@Property
protected String username;
@Property
protected String password;
/* 另一种使用方式 */
protected String username;
@Property(name="username")
public void setMyUserName(String username){
this.username = username
}
private CreateTicketComponent createTicket;
public int createTicket(TicketDO ticket) {
System.out.println(ticket.toString());
/* username variable passed as injected property value */
System.out.println("username is: " + username);
return createTicket.create(ticket);
}
/* Note, instead of using a setter, you could inject the reference
* directly at the variable reference level, similar to what
* is done for the propery injections shown above.
*/
@Reference
public void setCreateTicket(CreateTicketComponent createTicket) {
this.createTicket = createTicket;
}
}
6. 实现选项
Apache Tuscany 的SCA实现类型:
Java组件,Spring程序集,脚本:JS,Groovy,Ruby,Pythin,XSLT,BPEL,XQuery,OSGi
实现组示例:
<?xml version="1.0" encoding="ISO-8859-15"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:hw="http://opensoa.book.chapter325"
name="IssueManagementComposite"
targetNamespace="http://opensoa.book.chapter325">
<service name="SystemErrorService" promote="SystemErrorComponent">
<binding.ws uri="http://localhost:8085/SystemErrorService"/>
</service>
<component name="SystemErrorComponent">
<implementation.java
class="opensoa.book.chapter3_25.impl.SystemErrorComponentImpl"/>
<reference name="problemTicket" target="ProblemTicket"/>
</component>
<component name="ProblemTicket">
<implementation.composite name="hw:ProblemManagementComposite"/>
</component>
</composite>
实现类:
@Service(SystemErrorComponent.class)
public class SystemErrorComponentImpl implements SystemErrorComponent {
@Reference
public ProblemTicketComponent problemTicket;
public int systemProblem(String system, String title,String problem) {
System.out.println("*** SystemErrorComponentImpl ***");
int rval = 0;
TicketDO ticket = new TicketDO();
ticket.setSubject(title);
ticket.setSubject(problem);
ticket.setSource(system);
rval = problemTicket.createTicket(ticket);
System.out.println("problemTicket:" + rval);
return rval;
}
}
7. 使用引用进行依赖注入
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
targetNamespace="http://opensoa.book.chapter3"
xmlns:hw="http://opensoa.book.chapter3"
name="IssueManagementComposite">
<service name="SystemErrorService" promote="SystemErrorComponent">
<binding.ws uri="http://localhost:8085/SystemErrorService" />
</service>
<component name="SystemErrorComponent">
<implementation.java
class="opensoa.book.chapter3_26.impl.SystemErrorComponentImpl" />
</component>
<reference name="ProblemTicket" promote="SystemErrorComponent/problemTicket">
<binding.ws uri="http://localhost:8086/ProblemTicketService" />
</reference>
</composite>
@Reference
public void setProblemTicket(ProblemTicketComponent problemTicket) {
this.problemTicket = problemTicket;
}
8. 定义可用的绑定
Apache Tuscany的绑定类型:
WebService, JMs, JSON-RPC,EJB, Feed
将多个Web服务合并到单个WSDL文件中:
<composite
xmlns="http://www.osoa.org/xmlns/sca/1.0"
targetNamespace="http://opensoa.book.chapter327"
xmlns:hw="http://opensoa.book.chapter327"
name="IssueManagementComposite">
<service name="SystemErrorService" promote="SystemErrorComponent">
<binding.ws wsdlElement="http://chapter327.book.opensoa#wsdl.binding(
SystemErrorServiceJMSBinding)"
uri="jms:/SystemErrorInQueue?transport.jms
.ConnectionFactoryJNDIName=QueueConnectionFactory
&java.naming.factory.initial=org.apache.activemq
.jndi.ActiveMQInitialContextFactory&java.naming.provider.url
=tcp://localhost:61616?wireFormat.maxInactivityDuration=0" />
<binding.ws
wsdlElement="http://chapter327.book.opensoa#wsdl.port(SystemErrorService/SOAP)" />
<!--
<binding.ws uri="http://localhost:8085/SystemErrorService" />
-->
</service>
<component name="SystemErrorComponent">
<implementation.java
class="opensoa.book.chapter3_27.impl.SystemErrorComponentImpl" />
<reference name="problemTicket" target="ProblemTicket" /></component>
<component name="ProblemTicket">
<implementation.composite name="hw:ProblemManagementComposite" />
</component>
</composite>
SCA与远程协议(如:Web Service)之间的不同:
SCa定义可入如何将网络服务装配成可用的应用程序,并且提供了一种语言用于描述这种装配;而Web Service
描述了怎样使用协议去调用单个的服务。