JBpm可以使用Spring bean而不是类吗?

时间:2016-03-08 09:05:20

标签: spring jbpm

我们正在探索旧的J2EE项目的迁移,该项目具有用JBpm重写的工作流类型。我已经提到了几个主要使用Java类进行活动或任务的例子。 Spring与JBPM的集成更多是JBPM的初始化。注入bean代替java pojo类在技术上是否可行?

1 个答案:

答案 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");