我们正在探索旧的J2EE项目的迁移,该项目具有用JBpm重写的工作流类型。我已经提到了几个主要使用Java类进行活动或任务的例子。 Spring与JBPM的集成更多是JBPM的初始化。注入bean代替java pojo类在技术上是否可行?
答案 0 :(得分:0)
可以使用domainSpecific工作项处理程序在JBPM中使用spring bean。可以使用一些必需的参数定义自定义任务,例如bean名称,方法名称,调用参数等。这些自定义工作项处理程序将实现Spring的ContextAware接口并获取对容器的访问权限。 这项工作类似于使用JAVA pojo类的JBPM ServiceTask。
<bean id="workflowLauncherProcessor" class="workflow.WorkflowLauncherProcessor">
<property name="manager" ref="runtimeManager"></property>
<property name="workItemHandlerMap">
<map>
<entry key="SpringAsyncTask" value-ref="asyncWorkItemHandler"></entry>
<entry key="SpringSyncTask" value-ref="syncWorkItemHandler"></entry>
<entry key="SpringDirectTask" value-ref="directWorkItemHandler"></entry>
</map>
</property>
</bean>
<bean id="directWorkItemHandler" class="workflow.handler.SpringDirectBeanInvokeWorkItemHandler">
</bean>
实现类将如下所示
package workflow.handler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.management.InstanceNotFoundException;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jbpm.bpmn2.handler.WorkItemHandlerRuntimeException;
import org.kie.api.runtime.process.WorkItem;
import org.kie.api.runtime.process.WorkItemHandler;
import org.kie.api.runtime.process.WorkItemManager;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import com.scb.cashport.common.util.CommonConstants;
/**
* The Class SpringDirectBeanInvokeWorkItemHandler.
*
*/
public class SpringDirectBeanInvokeWorkItemHandler implements WorkItemHandler, ApplicationContextAware {
/** The Constant LOGGER. */
private static final Logger LOGGER = LogManager.getLogger(SpringDirectBeanInvokeWorkItemHandler.class);
/** The application context. */
private ApplicationContext applicationContext;
/*
* (non-Javadoc)
*
* @see
* org.kie.api.runtime.process.WorkItemHandler#executeWorkItem(org.kie.api
* .runtime.process.WorkItem, org.kie.api.runtime.process.WorkItemManager)
*/
@Override
public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {
Map<String, Object> results = new HashMap<String, Object>();
try {
String bean = (String) workItem.getParameter(CommonConstants.BEAN);
Object inputParam = (Object) workItem.getParameter(CommonConstants.INPUT_PARAM);
boolean cascasdeInput = Boolean.valueOf(String.valueOf(workItem.getParameter(CommonConstants.CASCADE_INPUT)));
String operation = (String) workItem.getParameter(CommonConstants.OPERATION);
String parameterDefinition = (String) workItem.getParameter(CommonConstants.PARAMETER_TYPE);
String parameter = (String) workItem.getParameter(CommonConstants.PARAMETER);
LOGGER.info("Spring Direct Bean Work Item begin for bean: {} and input: {}", bean, inputParam);
Object outParam = null;
Object instance = applicationContext.getBean(bean);
if (instance != null) {
try {
Class<?>[] classes = null;
Object[] params = null;
if (parameterDefinition != null) {
if (parameterDefinition.contains(CommonConstants.COMMA)) {
String[] parameterDefinitionArray = parameterDefinition.split(CommonConstants.COMMA);
String[] parameternArray = parameter.split(CommonConstants.COMMA);
if (parameterDefinitionArray.length != parameternArray.length) {
throw new IllegalArgumentException("Paramter types and parameters are not matching");
}
classes = new Class<?>[parameterDefinitionArray.length];
params = new Object[parameterDefinitionArray.length];
for (int i = 0; i < parameterDefinitionArray.length; i++) {
classes[i] = Class.forName(parameterDefinitionArray[i]);
String paramKey = parameternArray[i];
if (paramKey.startsWith("'")) {
params[i] = paramKey.substring(1, (paramKey.length() - 1));
} else {
params[i] = BeanUtils.getProperty(inputParam, parameternArray[i]);
}
}
} else {
classes = new Class<?>[]{Class.forName(parameterDefinition)};
params = new Object[]{BeanUtils.getProperty(inputParam, parameter)};
}
}
Method method = instance.getClass().getMethod(operation, classes);
outParam = method.invoke(instance, params);
if (cascasdeInput) {
String resultParameter = (String) workItem.getParameter(CommonConstants.RESULT_PARAMETER);
BeanUtils.setProperty(inputParam, resultParameter, outParam);
results.put(CommonConstants.INPUT_PARAM, inputParam);
results.put(CommonConstants.OUT_PARAM, inputParam);
} else {
results.put(CommonConstants.OUT_PARAM, outParam);
}
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException cnfe) {
handleException(cnfe, instance.getClass().getName(), operation, parameterDefinition);
}
} else {
throw new InstanceNotFoundException(bean + " bean instance not found");
}
LOGGER.info("Spring Direct Bean Work Item completed for bean: {} and input: {}", bean, inputParam);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e.getCause());
throw new WorkItemHandlerRuntimeException(e);
} finally {
manager.completeWorkItem(workItem.getId(), results);
}
}
/*
* (non-Javadoc)
*
* @see
* org.kie.api.runtime.process.WorkItemHandler#abortWorkItem(org.kie.api
* .runtime.process.WorkItem, org.kie.api.runtime.process.WorkItemManager)
*/
@Override
public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see
* org.springframework.context.ApplicationContextAware#setApplicationContext
* (org.springframework.context.ApplicationContext)
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
工作流程启动器将如下所示
RuntimeEngine engine = manager.getRuntimeEngine(EmptyContext.get());
KieSession ksession = engine.getKieSession();
for (Entry<String, WorkItemHandler> entry : workItemHandlerMap.entrySet()) {
ksession.getWorkItemManager().registerWorkItemHandler(entry.getKey(), entry.getValue());
}
Map<String, Object> parameter = new HashMap<String, Object>();
...
ProcessInstance processInstance = ksession.startProcess(processId, parameter);
Object variable = ((WorkflowProcessInstance) processInstance).getVariable("resultr");