请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

TaskService 使用表达式调用spring bean 方法

如题 部分流程文件如下

<serviceTask id="service" name="服务" activiti:expression="${testService.print(name)}"></serviceTask>

问题描述:
serviceTask 调用 testServiceprint方法; 其中testServicespring的一个bean

流程图如下
图片描述

过程

  • 创建bean 并加载流程文件
@Bean
public ProcessEngine processEngine(){
   ProcessEngineConfiguration cfg =ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration();
   ProcessEngine processEngine = cfg.buildProcessEngine();
   DeploymentBuilder deployment = processEngine.getRepositoryService().createDeployment();
   deployment.addClasspathResource("test1.bpmn20.xml");
   Deployment deploy = deployment.deploy();
   return processEngine;
}
  • 启动项目
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}
  • 测试代码
@RestController
public class TestController {
    @Autowired
    private ProcessEngine processEngine;
    @Autowired
    private TestService testService;
    @GetMapping("/test")
    public void test(){
        RuntimeService runtimeService = processEngine.getRuntimeService();
        Map<String,Object> context=new HashMap<>();
        context.put("name","Lucy");
        //context.put("testService",testService);
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("test", context);
        System.out.println(processInstance.getId());
    }
}

错误信息如下

org.activiti.engine.ActivitiException: Could not execute service task expression
Caused by: org.activiti.engine.ActivitiException: Unknown property used in expression: ${testService.print(name)}
Caused by: javax.el.PropertyNotFoundException: Cannot resolve identifier 'testService'

尝试方法:

  • testService放入流程的上下文
    若取消context.put("testService",testService); 的注释,报以下异常(不能序列化)
org.activiti.engine.ActivitiException: couldn't find a variable type that is able to serialize com.boco.mis.activiti.hello.TestService@216d848e

调整TestService的代码 实现Serializable,之后可以正常运行

@Service(value="testService")
public class TestService implements Serializable{
   public void print(String name){
       System.out.println("TestService1.print("+name+")");
   }
}

但是,正式环境中testService会依赖其他类,依赖类也必须实现Serializable,才可以,而依赖类又会依赖其他类,所以此方案不可行

后续又对activiti:classactiviti:delegateExpression 进行了测试 均没有达到预期效果

所有测试代码均在https://github.com/jiabiaoli/activiti-hello

正在回答 回答被采纳积分+3

1回答

Jimmy 2019-11-22 14:14:44

问题出在 这里 

ProcessEngineConfiguration cfg =ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration();
  ProcessEngine processEngine = cfg.buildProcessEngine(); 

在spring环境下通过这种方式创建的ProcessEngine并没有把spring 容器的bean放到流程引擎中

解决的方法

独立声明一下 SpringProcessEngineConfiguration 成为一个bean

参考

@Bean

public SpringProcessEngineConfiguration processEngineConfiguration(){

    //具体参数需要配置

    renturn new SpringProcessEngineConfiguration()

}

0 回复 有任何疑惑可以回复我~
  • 提问者 破地瓜 #1
    @Bean
        public DataSource dataSource() {
            return DataSourceBuilder.create()
                    .username("sa")
                    .password("")
               .url("jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false").build();
        }
        @Bean
        public PlatformTransactionManager transactionManager(){
            DataSourceTransactionManager transactionManager=new DataSourceTransactionManager();
            transactionManager.setDataSource(dataSource());
            return transactionManager;
        }
    
        @Bean
        public SpringProcessEngineConfiguration springProcessEngineConfiguration() {
            SpringProcessEngineConfiguration processEngineConfiguration = new SpringProcessEngineConfiguration();
            processEngineConfiguration.setDataSource(dataSource());
            processEngineConfiguration.setTransactionManager(transactionManager());
            processEngineConfiguration.setDatabaseSchemaUpdate("true");
            return processEngineConfiguration;
        }
    
    
    已经改造 仍然不好使,代码已提交github
    回复 有任何疑惑可以回复我~ 2019-11-22 14:32:17
  • 提问者 破地瓜 #2
    经过测试 以上代码不够
    public ProcessEngineFactoryBean springProcessEngineBean() {
            ProcessEngineFactoryBean processEngineFactoryBean = new ProcessEngineFactoryBean();
            processEngineFactoryBean.setProcessEngineConfiguration(springProcessEngineConfiguration());
            processEngineFactoryBean.setApplicationContext(applicationContext);
            return processEngineFactoryBean;
        }
    
    通过processEngineFactoryBean.getObject() 获取才可以
    回复 有任何疑惑可以回复我~ 2019-11-22 14:35:37
  • 提问者 破地瓜 #3
    写了篇文章 记录下
    https://www.jianshu.com/p/48e5f85a5568
    回复 有任何疑惑可以回复我~ 2019-11-22 17:42:46
问题已解决,确定采纳
还有疑问,暂不采纳
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号