JBPM引擎设计(1)
来源:互联网 发布:远程的端口号 编辑:程序博客网 时间:2024/05/18 02:24
1、命令模式在Jbpm的使用,有助于管理各命令的执行,也方便方便接口处理,如下:
protected int getJobCount() { return processEngine.execute(new Command<Integer>() { private static final long serialVersionUID = 1L; public Integer execute(Environment environment) { org.hibernate.Session session = environment.get(org.hibernate.Session.class); return (Integer) session.createCriteria("org.jbpm.pvm.internal.job.JobImpl") .add(Restrictions.gt("retries", 0)) .setProjection(Projections.rowCount()) .uniqueResult(); } }); }
以上类图只在Task处理做解释,实际上包含业务处理的所有操作(DAO)都为一个Command,如上面的getTaskCmd,其实现如下:
package org.jbpm.pvm.internal.cmd;import org.jbpm.api.JbpmException;import org.jbpm.api.cmd.Environment;import org.jbpm.api.task.Task;import org.jbpm.pvm.internal.session.DbSession;import org.jbpm.pvm.internal.task.TaskImpl;/** * @author Alejandro Guizar */public class GetTaskCmd extends AbstractCommand<Task> { private static final long serialVersionUID = 1L; protected String taskId; public GetTaskCmd(String taskId) { if (taskId==null) { throw new JbpmException("taskId is null"); } this.taskId = taskId; } public Task execute(Environment environment) throws Exception { DbSession dbSession = environment.get(DbSession.class); return dbSession.get(TaskImpl.class, Long.parseLong(taskId)); }}
而以上处理中的DbSession就是hibernate的Session接口,这是在enviroment中注入的:
package org.jbpm.pvm.internal.hibernate;import java.io.Serializable;import java.util.Collection;import java.util.List;import org.hibernate.LockMode;import org.hibernate.Session;import org.hibernate.criterion.Order;import org.hibernate.criterion.Restrictions;import org.hibernate.metadata.ClassMetadata;import org.jbpm.api.Execution;import org.jbpm.api.JbpmException;import org.jbpm.api.history.HistoryComment;import org.jbpm.api.task.Task;import org.jbpm.internal.log.Log;import org.jbpm.pvm.internal.client.ClientExecution;import org.jbpm.pvm.internal.env.EnvironmentImpl;import org.jbpm.pvm.internal.history.model.HistoryCommentImpl;import org.jbpm.pvm.internal.history.model.HistoryProcessInstanceImpl;import org.jbpm.pvm.internal.id.DbidGenerator;import org.jbpm.pvm.internal.job.JobImpl;import org.jbpm.pvm.internal.job.StartProcessTimer;import org.jbpm.pvm.internal.model.ExecutionImpl;import org.jbpm.pvm.internal.query.DeploymentQueryImpl;import org.jbpm.pvm.internal.query.HistoryActivityInstanceQueryImpl;import org.jbpm.pvm.internal.query.HistoryDetailQueryImpl;import org.jbpm.pvm.internal.query.HistoryProcessInstanceQueryImpl;import org.jbpm.pvm.internal.query.JobQueryImpl;import org.jbpm.pvm.internal.query.ProcessInstanceQueryImpl;import org.jbpm.pvm.internal.query.TaskQueryImpl;import org.jbpm.pvm.internal.session.DbSession;import org.jbpm.pvm.internal.task.TaskImpl;import org.jbpm.pvm.internal.util.Clock;import org.jbpm.pvm.internal.util.CollectionUtil;/** * @author Tom Baeyens */public class DbSessionImpl implements DbSession { private static Log log = Log.getLog(DbSessionImpl.class.getName()); protected Session session; public void close() { session.close(); } public <T> T get(Class<T> entityClass, Object primaryKey) { return entityClass.cast(session.get(entityClass, (Serializable) primaryKey)); } public void flush() { session.flush(); } public void forceVersionUpdate(Object entity) { session.lock(entity, LockMode.FORCE); } public void lockPessimistically(Object entity) { session.lock(entity, LockMode.UPGRADE); } public void save(Object entity) { session.save(entity); } public void update(Object entity) { session.update(entity); } public void merge(Object entity) { session.merge(entity); } public void delete(Object entity) { session.delete(entity); } public Session getSession() { return session; } public void setSession(Session session) { this.session = session; } public void deleteProcessDefinitionHistory(String processDefinitionId) { List<?> historyProcessInstances = session.createCriteria(HistoryProcessInstanceImpl.class) .add(Restrictions.eq("processDefinitionId", processDefinitionId)) .list(); for (Object hpi : historyProcessInstances) { session.delete(hpi); } } public boolean isHistoryEnabled() { ClassMetadata historyHibernateMetadata = session.getSessionFactory() .getClassMetadata(HistoryProcessInstanceImpl.class); return historyHibernateMetadata != null; } // process execution queries //////////////////////////////////////////////// public ClientExecution findExecutionById(String executionId) { // query definition can be found at the bottom of resource jbpm.execution.hbm.xml return (ClientExecution) session.getNamedQuery("findExecutionById") .setString("id", executionId) .setMaxResults(1) .uniqueResult(); } public ClientExecution findProcessInstanceById(String processInstanceId) { // query definition can be found at the bottom of resource jbpm.execution.hbm.xml return (ClientExecution) session.getNamedQuery("findProcessInstanceById") .setString("processInstanceId", processInstanceId) .setMaxResults(1) .uniqueResult(); } public ClientExecution findProcessInstanceByIdIgnoreSuspended(String processInstanceId) { // query definition can be found at the bottom of resource jbpm.execution.hbm.xml return (ClientExecution) session.getNamedQuery("findProcessInstanceByIdIgnoreSuspended") .setString("processInstanceId", processInstanceId) .setMaxResults(1) .uniqueResult(); } public List<String> findProcessInstanceIds(String processDefinitionId) { // query definition can be found at the bottom of resource jbpm.execution.hbm.xml List<?> processInstanceIds = session.getNamedQuery("findProcessInstanceIds") .setString("processDefinitionId", processDefinitionId) .list(); return CollectionUtil.checkList(processInstanceIds, String.class); } public void deleteProcessInstance(String processInstanceId) { deleteProcessInstance(processInstanceId, true); } public void deleteProcessInstance(String processInstanceId, boolean deleteHistory) { if (processInstanceId == null) { throw new JbpmException("processInstanceId is null"); } // if history should be deleted if (deleteHistory && (isHistoryEnabled())) { // try to get the history HistoryProcessInstanceImpl historyProcessInstance = findHistoryProcessInstanceById(processInstanceId); // if there is a history process instance in the db if (historyProcessInstance != null) { if (log.isDebugEnabled()) { log.debug("deleting history process instance " + processInstanceId); } session.delete(historyProcessInstance); } } ExecutionImpl processInstance = (ExecutionImpl) findProcessInstanceByIdIgnoreSuspended(processInstanceId); if (processInstance != null) { deleteSubProcesses(processInstance, deleteHistory); // delete remaining tasks for this process instance List<TaskImpl> tasks = findTasks(processInstanceId); for (TaskImpl task : tasks) { session.delete(task); } // delete remaining jobs for this process instance JobImpl currentJob = EnvironmentImpl.getFromCurrent(JobImpl.class, false); List<JobImpl> jobs = findJobs(processInstanceId); for (JobImpl job : jobs) { if (job != currentJob) { session.delete(job); } } if (log.isDebugEnabled()) { log.debug("Deleting process instance " + processInstanceId); } session.delete(processInstance); } else { throw new JbpmException("Can't delete processInstance " + processInstanceId + ": no processInstance found for the given id"); } } private void deleteSubProcesses(ExecutionImpl execution, boolean deleteHistory) { ExecutionImpl subProcessInstance = execution.getSubProcessInstance(); if (subProcessInstance != null) { subProcessInstance.setSuperProcessExecution(null); execution.setSubProcessInstance(null); deleteProcessInstance(subProcessInstance.getId(), deleteHistory); } Collection<ExecutionImpl> childExecutions = execution.getExecutions(); if (childExecutions != null) { for (ExecutionImpl childExecution : childExecutions) { deleteSubProcesses(childExecution, deleteHistory); } } } public HistoryProcessInstanceImpl findHistoryProcessInstanceById(String processInstanceId) { return (HistoryProcessInstanceImpl) session.createCriteria(HistoryProcessInstanceImpl.class) .add(Restrictions.eq("processInstanceId", processInstanceId)) .uniqueResult(); } List<TaskImpl> findTasks(String processInstanceId) { List<?> tasks = session.createCriteria(TaskImpl.class) .createAlias("processInstance", "pi") .add(Restrictions.eq("pi.id", processInstanceId)) .list(); return CollectionUtil.checkList(tasks, TaskImpl.class); } List<JobImpl> findJobs(String processInstanceId) { List<?> jobs = session.createCriteria(JobImpl.class) .createAlias("processInstance", "pi") .add(Restrictions.eq("pi.id", processInstanceId)) .list(); return CollectionUtil.checkList(jobs, JobImpl.class); } public void cascadeExecutionSuspend(ExecutionImpl execution) { // cascade suspend to jobs List<?> jobs = session.createCriteria(JobImpl.class) .add(Restrictions.eq("execution", execution)) .add(Restrictions.ne("state", JobImpl.STATE_SUSPENDED)) .list(); for (JobImpl job : CollectionUtil.checkList(jobs, JobImpl.class)) { job.suspend(); } // cascade suspend to tasks List<?> tasks = session.createCriteria(TaskImpl.class) .add(Restrictions.eq("execution", execution)) .add(Restrictions.ne("state", Task.STATE_SUSPENDED)) .list(); for (TaskImpl task : CollectionUtil.checkList(tasks, TaskImpl.class)) { task.suspend(); } } public void cascadeExecutionResume(ExecutionImpl execution) { // cascade resume to jobs List<?> jobs = session.createCriteria(JobImpl.class) .add(Restrictions.eq("execution", execution)) .add(Restrictions.eq("state", JobImpl.STATE_SUSPENDED)) .list(); for (JobImpl job : CollectionUtil.checkList(jobs, JobImpl.class)) { job.resume(); } // cascade resume to tasks List<?> tasks = session.createCriteria(TaskImpl.class) .add(Restrictions.eq("execution", execution)) .add(Restrictions.eq("state", Task.STATE_SUSPENDED)) .list(); for (TaskImpl task : CollectionUtil.checkList(tasks, TaskImpl.class)) { task.resume(); } } public TaskImpl createTask() { TaskImpl task = newTask(); task.setCreateTime(Clock.getTime()); return task; } protected TaskImpl newTask() { TaskImpl task = new TaskImpl(); long dbid = EnvironmentImpl.getFromCurrent(DbidGenerator.class).getNextId(); task.setDbid(dbid); task.setNew(true); return task; } public TaskImpl findTaskByDbid(long taskDbid) { return (TaskImpl) session.get(TaskImpl.class, taskDbid); } public TaskImpl findTaskByExecution(Execution execution) { return (TaskImpl) session.createCriteria(TaskImpl.class) .add(Restrictions.eq("execution", execution)) .uniqueResult(); } public JobImpl findFirstAcquirableJob() { return (JobImpl) session.getNamedQuery("findFirstAcquirableJob") .setTimestamp("now", Clock.getTime()) .setMaxResults(1) .uniqueResult(); } public List<JobImpl> findExclusiveJobs(Execution processInstance) { List<?> exclusiveJobs = session.getNamedQuery("findExclusiveJobs") .setTimestamp("now", Clock.getTime()) .setEntity("processInstance", processInstance) .list(); return CollectionUtil.checkList(exclusiveJobs, JobImpl.class); } public JobImpl findFirstDueJob() { return (JobImpl) session.getNamedQuery("findFirstDueJob") .setMaxResults(1) .uniqueResult(); } public List<StartProcessTimer> findStartProcessTimers(String processDefinitionName) { List<?> timers = session.createCriteria(StartProcessTimer.class) .add(Restrictions.eq("signalName", processDefinitionName)) .list(); return CollectionUtil.checkList(timers, StartProcessTimer.class); } public ProcessInstanceQueryImpl createProcessInstanceQuery() { return new ProcessInstanceQueryImpl(); } public TaskQueryImpl createTaskQuery() { return new TaskQueryImpl(); } public HistoryProcessInstanceQueryImpl createHistoryProcessInstanceQuery() { return new HistoryProcessInstanceQueryImpl(); } public HistoryActivityInstanceQueryImpl createHistoryActivityInstanceQuery() { return new HistoryActivityInstanceQueryImpl(); } public HistoryDetailQueryImpl createHistoryDetailQuery() { return new HistoryDetailQueryImpl(); } public JobQueryImpl createJobQuery() { return new JobQueryImpl(); } public DeploymentQueryImpl createDeploymentQuery() { return new DeploymentQueryImpl(); } public List<HistoryComment> findCommentsByTaskId(String taskId) { List<?> comments = session.createCriteria(HistoryCommentImpl.class) .createAlias("historyTask", "task") .add(Restrictions.eq("task.dbid", Long.parseLong(taskId))) .addOrder(Order.asc("historyTaskIndex")) .list(); return CollectionUtil.checkList(comments, HistoryComment.class); }}
也就是说,底层还是通过session操作数据库的。3、关于上图中的CommandService是一个接口:
public interface CommandService { String NAME_TX_REQUIRED_COMMAND_SERVICE = "txRequiredCommandService"; String NAME_NEW_TX_REQUIRED_COMMAND_SERVICE = "newTxRequiredCommandService"; /** * @throws JbpmException if command throws an exception. */ <T> T execute(Command<T> command);}
实际调用的类是AbstractServiceImpl依赖这个CommandService,如下:
public class AbstractServiceImpl { protected CommandService commandService; public CommandService getCommandService() { return commandService; } public void setCommandService(CommandService commandService) { this.commandService = commandService; }}
AbstractServiceImpl几个子类对于实际操作的几个接口:
4、我们在使用JBPM流程引擎时,先获取单例的ProcessEnginee对象,用这个可以
RepositoryService getRepositoryService(); /** the {@link ExecutionService execution service} that provides access * to the runtime executions repository. */ ExecutionService getExecutionService(); /** the {@link HistoryService history service} that provides access * to the history executions repository. */ HistoryService getHistoryService(); /** the {@link TaskService task service} that exposes the * runtime human task lists. */ TaskService getTaskService(); /** the {@link IdentityService identity service} that exposes the * user and group operations management operations. */ IdentityService getIdentityService(); /** the {@link ManagementService management service} that exposes the * management operations to operators that have to keep the jBPM system * up and running. */ ManagementService getManagementService();
也就是几个服务接口,我们应用层就是操作者几个接口进行流程控制。
6、以上关键部分就是CommandService是具体对象:
比如TaskServiceImp中依赖的CommandService就是:
processEngineWireContext.get()在上层获取
比如ProcessEniginee中还有一个execute(Command<T>)接口中的Command就是这里获取
userCommandService = (CommandService) processEngineWireContext.get(CommandService.NAME_TX_REQUIRED_COMMAND_SERVICE);
0 0
- JBPM引擎设计(1)
- jbpm工作流引擎(1)----概述
- 揭秘jbpm流程引擎内核设计思想及构架(经典之作,收藏之)
- 揭秘jbpm流程引擎内核设计思想及构架(经典之作,收藏之)
- 揭秘jbpm流程引擎内核设计思想及构架
- 揭秘jbpm流程引擎内核设计思想及构架
- 揭秘jbpm流程引擎内核设计思想及构架
- 揭秘jbpm流程引擎内核设计思想及构架
- 揭秘jbpm流程引擎内核设计思想及构架
- 揭秘jbpm流程引擎内核设计思想及构架
- 揭秘jbpm流程引擎内核设计思想及构架
- 揭秘jbpm流程引擎内核设计思想及构架[收藏]
- 揭秘jbpm流程引擎内核设计思想及构架 [收藏]
- 揭秘jbpm流程引擎内核设计思想及构架(转贴)
- JBPM工作流引擎内核设计思想及构架
- 揭秘jbpm流程引擎内核设计思想及构架
- 揭秘jbpm流程引擎内核设计思想及构架
- 揭秘jbpm流程引擎内核设计思想及构架
- Python快捷键一览
- 轻量级HTTP服务器Nginx(常用配置实例)
- Junit4测试报错
- Linux增加swap分区大小
- 数据结构-链表创建,删除,插入,反转,连接
- JBPM引擎设计(1)
- 主键被删除,外键引用报的异常
- Bash Shell脚本字符串截断
- JAVA之抽象类与接口的区别
- Android数据库使用cursor的注意事项!
- 修改ubuntu下IP地址
- CentOS6.3配置SVN之subversion1.7.7
- 如何成为一名优秀的前端工程师
- extjs xtype僧如理解