概述
jbpm human task 源代码分析 - I中为执行jbpm human task服务器端的代码,本文集中与执行human task时客户端如何连接到服务器,进行与服务器交互,jBPM 5执行human task是与服务器通信可以使用三种方式:
- hornetq
- mina
- jms
jbpm human task 源代码分析 - I中是使用jms,本文客户端代码分析也使用jms,所设计到的类注意包括JMSTaskClientConnector,JMSTaskClientHandler等。
org.jbpm.task.service.jms.JMSTaskClientConnector
org.jbpm.task.service.TaskClientConnector接口定义了客户端连接到human task服务器端的方法,接口中定义了如下方法:
public boolean connect();
public boolean connect(String address, int port);
public void disconnect() throws Exception;
public void write(Object message);
public BaseHandler getHandler();
public String getName();
public AtomicInteger getCounter();
connect方法供客户端连接到服务器,disconnect()方法供客户端断开到服务器的连接,write(Object message)想服务器端发送消息,如果使用JMS则发送JMS消息到服务器端消息队列,getHandler()方法获取连接处理器,getName()方法获取连接的名字。org.jbpm.task.service.jms.JMSTaskClientConnector实现了org.jbpm.task.service.TaskClientConnector接口,用来提供jms做为传输方式时的实现,相关类图如下:
connect()初始化JMS发送消息相关的Session,Producer等,顺序大致如下:
通过JNDI查询获取QueueConnectionFactory,通过QueueConnectionFactory创建QueueConnection,通过QueueConnection创建QueueSession,通过QueueSession创建MessageProducer,如果以上过程成功返回true。相关代码段如下:
QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup(connFactoryName);
this.connection = factory.createQueueConnection();
this.producerSession = this.connection.createQueueSession(transactedQueue, acknowledgeMode);
this.consumerSession = this.connection.createQueueSession(transactedQueue, acknowledgeMode);
this.taskServerQueue = this.producerSession.createQueue(taskServerQueueName);
this.responseQueue = this.consumerSession.createQueue(responseQueueName);
this.producer = this.producerSession.createProducer(this.taskServerQueue);
this.connection.start();
return true;
org.jbpm.task.service.jms.JMSTaskClientConnector提供了一个构造方法如下:
public JMSTaskClientConnector(String name, BaseClientHandler handler, Properties connectionProperties, Context context) {
if (name == null) {
throw new IllegalArgumentException("Name can not be null");
}
this.name = name;
this.handler = handler;
this.connectionProperties = connectionProperties;
this.context = context;
this.counter = new AtomicInteger();
if(System.getProperty("enableLog") != null)
this.enableLog = Boolean.parseBoolean(System.getProperty("enableLog"));
}
构造方法中:
- name - 定义了TaskClientConnector的名字
- handler - 定义客户端连接处理器
- connectionProperties - 定义初始化JMS发送消息相关的Session,Producer等参数,如队列名字等
- context - 定义JNDI的上下文
org.jbpm.task.service.jms.JMSTaskClientHandler
JMSTaskClientConnector构造方法中需要传入客户端连接处理器JMSTaskClientHandler,这里我们分析该类,首先给出类图,如下:
org.jbpm.task.service.BaseHandler定义了一个方法:
public void addResponseHandler(int id, ResponseHandler responseHandler);
org.jbpm.task.service.BaseClientHandler实现了BaseHandler,BaseClientHandler中定义了Map<Integer, ResponseHandler> responseHandlers,并在构造方法中初始化,addResponseHandler()方法的实现是将ResponseHandler添加到Map中,BaseClientHandler代码如下:
protected Map<Integer, ResponseHandler> responseHandlers;
public BaseClientHandler() {
responseHandlers = new HashMap<Integer, ResponseHandler>();
}
public void addResponseHandler(int id, ResponseHandler responseHandler) {
responseHandlers.put( id, responseHandler );
}
JMSTaskClientHandler的messageReceived方法如下:
public void messageReceived(Session session, Object message, Destination destination, String selector) throws Exception {
String name = "";
if (destination instanceof Queue) {
name = ((Queue) destination).getQueueName();
} else if (destination instanceof Topic) {
name = ((Topic) destination).getTopicName();
}
MessageProducer producer = (MessageProducer) this.producers.get(name);
if (producer == null) {
producer = session.createProducer(destination);
this.producers.put(name, producer);
}
this.handler.messageReceived(new JMSSessionWriter(session, producer, selector), message);
}