1.使用对话
(1) 对话范围的不同级别
Composite: 所有请求在组合的整个生命周期都被分发到同一个类实例。一个经典的场景是计数器,每当特定服务被调
用就增加一次计数。
Conversation: 利用相关性创建进行中的客户端与目标服务之间的对话。第一个服务被调用时 对话开始,结束操作被
调用时回话终止。客户端需要比较智能以支持这项功能。
Request: 与Servlet的请求范围类似,对远程接口的请求进入到SCA运行时,处理该请求,指导线程完成处理。只有
SCA客户端支持该级别。
Stateless: 默认不维持任何回话。
(2)下面用Composite范围来作示例:
带有会话注解的SessionManager接口类:
@Remotable
@Conversational //将服务标记为会话式的服务操作
public interface SessionManager {
public void initialize();
public int getSessionId();
}
带有会话注解的SessionManagerImpl实现类:
@Service (SessionManager.class)
@Scope ("COMPOSITE") //标明服务的范围
@EagerInit //SCA domain 启动时初始化
public class SessionManagerImpl implements SessionManager {
private int sessionId = 0;
public int getSessionId() {
return sessionId;
}
@Init //类初始化时调用的方法 ,使用@EagerInit注解时必须使用的
public void initialize() {
Random r = new Random();
sessionId = r.nextInt(300000);
}
}
配置文件:problemMgmt421.composite
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
targetNamespace="http://opensoa.book.chapter4"
xmlns:hw="http://opensoa.book.chapter4"
name="ProblemManagementComposite">
<service name="ProblemTicketComponent" promote="ProblemTicketComponent">
<binding.ws uri="http://localhost:8085/ProblemTicketService" />
</service>
<component name="ProblemTicketComponent">
<implementation.java
class="opensoa.book.chapter4_21.impl.ProblemTicketComponentImpl" />
<property name="username">[email protected]</property>
<property name="password">mypassword1</property>
<reference name="createTicket" target="CreateTicketComponent" />
</component>
<component name="CreateTicketComponent">
<implementation.java
class="opensoa.book.chapter4_21.impl.CreateTicketComponentImpl" />
<reference name="sessionManager" target="SessionManagerComponent" />
</component>
<component name="SessionManagerComponent">
<implementation.java
class="opensoa.book.chapter4_21.impl.SessionManagerImpl" />
</component>
</composite>
2. 理解回调
会调是一种双向通信,客户端请求服务,服务提供者或服务器通过给定的接口或操作“回调”客户端。它被认为是一种
异步的通信,因为服务器不像通常的Web服务或RPC风格的通信那样通过同步的回复返回结果。创建回调服务有以下
几个步骤:
(1)创建回调接口:定义之行回调时调用的操作
@Remotable
public interface EventNotificationCallback {
void success(boolean status);
}
(2)创建服务接口和实现:增加回调注解
@Remotable
@Callback(EventNotificationCallback.class) //指定回调
public interface EventNotificationComponent {
@OneWay //给出回调方法类型
public void notify(TicketDO ticket);
}
@Service(EventNotificationComponent.class)
public class EventNotificationComponentImpl implements EventNotificationComponent {
@Callback //注入回调类
protected EventNotificationCallback callback;
public void notify(TicketDO ticket) {
try {
Thread.sleep(4000); //休眠40秒
} catch (InterruptedException e) {
e.printStackTrace();
}
callback.success(true); //执行回调操作
}
}
(3) 创建或修改客户端类,实现第一步中定义的回调接口,增加到第二步中创建的服务的引用,修改业务逻辑以使用服
务端组件的功能。
@Service(CreateTicketComponent.class)
public class CreateTicketComponentImpl implements CreateTicketComponent,
EventNotificationCallback { //实现回调接口
@Reference
protected SessionManager sessionManager;
@Reference
protected EventNotificationComponent eventNotifier;
int ticketId = 0;
public CreateTicketComponentImpl() {
super();
System.out.println("CreateTicketComponentImpl instantiated...");
}
public int create(TicketDO ticket) {
System.out.println("createTicket sessionManager: " + sessionManager.getSessionId());
Random r = new Random();
ticketId = r.nextInt(300000);
eventNotifier.notify(ticket);
return ticketId;
}
public void success(boolean status) { //调用方法
System.out.println("Notify results: " + status);
}
}
(4) 修改composite文件以支持装配集
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
targetNamespace="http://opensoa.book.chapter4"
xmlns:hw="http://opensoa.book.chapter4"
name="ProblemManagementComposite">
<property name="credentials" type="hw:CredentialsType">
<hw:Credentials>
<hw:username>[email protected]</hw:username>
<hw:password>mypassword1</hw:password>
</hw:Credentials>
</property>
<service name="ProblemTicketComponent" promote="ProblemTicketComponent">
<binding.ws uri="http://localhost:8085/ProblemTicketService" />
</service>
<component name="ProblemTicketComponent">
<implementation.java
class="opensoa.book.chapter4_22.impl.ProblemTicketComponentImpl" />
<property name="username" source="$credentials//*[local-name()='username']" />
<property name="password" source="$credentials//*[local-name()='password']" />
<reference name="createTicket" target="CreateTicketComponent" />
</component>
<component name="CreateTicketComponent">
<implementation.java
class="opensoa.book.chapter4_22.impl.CreateTicketComponentImpl" />
<reference name="sessionManager" target="SessionManagerComponent" />
<!--定义要注入的引用-->
<reference name="eventNotifier" target="EventNotificationComponent">
<!--指明回调接口-->
<interface.java
interface="opensoa.book.chapter4_22.EventNotificationComponent"
callbackInterface="opensoa.book.chapter4_22.EventNotificationCallback" />
</reference>
</component>
<component name="SessionManagerComponent">
<implementation.java
class="opensoa.book.chapter4_22.impl.SessionManagerImpl" />
</component>
<component name="EventNotificationComponent">
<implementation.java
class="opensoa.book.chapter4_22.impl.EventNotificationComponentImpl" />
</component>
</composite>