1.實現服務任務的監聽事件,該實現類實現了JavaDelegate接口時,直接使用@Resource注入的bean是null
原因:flowable執行監聽事件時,是通過反射獲取bean的,此時該bean不在spring的管理中,需要使用ApplicationContext來獲取bean
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@Service
@Lazy(false)
public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
private static ApplicationContext applicationContext = null;
private static Logger logger = LoggerFactory.getLogger(SpringContextHolder.class);
/**
* 取得存儲在靜態變量中的ApplicationContext.
*/
public static ApplicationContext getApplicationContext() {
assertContextInjected();
return applicationContext;
}
/**
* 從靜態變量applicationContext中取得Bean, 自動轉型為所賦值對象的類型.
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) {
assertContextInjected();
return (T) applicationContext.getBean(name);
}
/**
* 從靜態變量applicationContext中取得Bean, 自動轉型為所賦值對象的類型.
*/
public static <T> T getBean(Class<T> requiredType) {
assertContextInjected();
return applicationContext.getBean(requiredType);
}
/**
* 清除SpringContextHolder中的ApplicationContext為Null.
*/
public static void clearHolder() {
if (logger.isDebugEnabled()){
logger.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
}
applicationContext = null;
}
/**
* 實現ApplicationContextAware接口, 注入Context到靜態變量中.
*/
public void setApplicationContext(ApplicationContext applicationContext) {
// logger.debug("注入ApplicationContext到SpringContextHolder:{}", applicationContext);
if (SpringContextHolder.applicationContext != null) {
logger.info("SpringContextHolder中的ApplicationContext被覆蓋, 原有ApplicationContext為:" + SpringContextHolder.applicationContext);
}
SpringContextHolder.applicationContext = applicationContext;
}
/**
* 實現DisposableBean接口, 在Context關閉時清理靜態變量.
*/
public void destroy() throws Exception {
SpringContextHolder.clearHolder();
}
/**
* 檢查ApplicationContext不為空.
*/
private static void assertContextInjected() {
Validate.validState(applicationContext != null, "applicaitonContext屬性未注入, 請在applicationContext.xml中定義SpringContextHolder.");
}
}
package com.insgeek.platform.flow.adapter.listener;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.JavaDelegate;
import org.springframework.util.CollectionUtils;
import com.insgeek.boot.web.context.IdentityContext;
import com.insgeek.platform.flow.adapter.config.FlowConstants;
import com.insgeek.platform.flow.enums.ElementTypeEnum;
import com.insgeek.platform.flow.enums.ResultCodeEnum;
import com.insgeek.platform.flow.pojo.dto.ExtensionServiceTaskDto;
import com.insgeek.platform.flow.pojo.dto.ProcessModelDto;
import com.insgeek.platform.flow.pojo.model.ExtensionElementModel;
import com.insgeek.platform.flow.rpc.EventClientService;
import com.insgeek.platform.flow.service.ExtensionService;
import com.insgeek.platform.flow.service.ProcessModelService;
import com.insgeek.platform.flow.util.BusinessKeyUtil;
import com.insgeek.platform.flow.util.SpringContextHolder;
import com.insgeek.protocol.flow.dto.InteractBusinessRequestDto;
/**
* @author jiangliangyou
* @date 2020-11-25
*/
public class ServiceTaskImpl implements JavaDelegate {
private EventClientService eventClientService = SpringContextHolder.getBean(EventClientService.class);
private ExtensionService extensionService = SpringContextHolder.getBean(ExtensionService.class);;
private ProcessModelService processModelService = SpringContextHolder.getBean(ProcessModelService.class);
@Override
public void execute(DelegateExecution execution) {
// System.out.println("JavaDelegate : " + getClass().getSimpleName());
// Map map = MapBuilder.of("getId", execution.getId())
// .put("getProcessInstanceId", execution.getProcessInstanceId())
// .put("getProcessDefinitionId", execution.getProcessDefinitionId())
// .put("getVariableNames", String.join(",", execution.getVariableNames()))
// .put("getCurrentActivityId", execution.getCurrentActivityId())
// .put("getEventName", execution.getEventName())
// .put("getParentId", execution.getParentId())
// .put("getProcessInstanceBusinessKey", execution.getProcessInstanceBusinessKey())
// .put("getRootProcessInstanceId", execution.getRootProcessInstanceId())
// .put("getSuperExecutionId", execution.getSuperExecutionId())
// .put("getSimpleName", execution.getClass().getSimpleName()).build();
// System.out.println(JacksonUtils.writeAsString(map));
ProcessModelDto processModelDto = processModelService.findEnableProcessModelByDefinition(execution.getProcessDefinitionId());
// 根據任務elementId和modelId查詢額外擴展表獲取事件列表,如果沒有事件,直接返回
ExtensionElementModel queryParams = new ExtensionElementModel();
queryParams.setModelId(processModelDto.getId());
queryParams.setElementId(execution.getCurrentActivityId());
queryParams.setElementType(ElementTypeEnum.SERVICE_TASK.getValue());
List<ExtensionElementModel> eventModelList = extensionService.getExtensionElementModelListByQuery(queryParams);
if (CollectionUtils.isEmpty(eventModelList)) return;
// 事件不為空,判斷事件的執行條件是否為空
List<Long> eventIds = eventModelList.stream()
.map(ExtensionServiceTaskDto::of)
.map(ExtensionServiceTaskDto::getTaskEventId)
.filter(Objects::nonNull)
.collect(Collectors.toList());
Map<String,Object> variablesMap = execution.getVariables();
InteractBusinessRequestDto interactBusinessRequestDto = new InteractBusinessRequestDto()
.setCurrentTaskId(execution.getId())
.setDataId(BusinessKeyUtil.dataId(execution.getProcessInstanceBusinessKey()))
.setEntityKey(processModelDto.getEntityKey())
.setApplicantId(Long.valueOf(String.valueOf(variablesMap.get(FlowConstants.APPLICANT_ID))))
.setDefinitionId(execution.getProcessDefinitionId())
.setVariables(variablesMap)
.setCurrentUserId(IdentityContext.getUserId());
eventClientService.executeEventByEventIds(eventIds, ResultCodeEnum.AFTER_EVENT_EXECUTION_ERROR,interactBusinessRequestDto);
}
}
