Activiti7
简述:
Activiti是一款工作流引擎,是业务流程管理(BPM)框架,最常用的是用在各种审批工作中,比如请假审批,采购审批

引进背景:
我们引入工作流是为了灵活多变的实行客户在提交订单时,获得上级认证通过的流程方式,采用流程图可以在不修改代码,不发布的前提下,满足客户的需求,
在上线初, 存在业务场景为“三不固定”审批:
节点不定:客户上级审批存在多个节点审批,一级复一级,节点不定
人员不定:一个节点审批存在多个人审批的情况,可一可众,人员不定
路线不定:同一个人下单,存在依据下单条件多种,多条分支,不同审批人的情况,路线不定
在这种复杂的业务场景和业务需求下,传统的开发审批功能模块是无法满足的,故而引入了Activiti工作流,与之相比的还有Flowable 引擎,这两个都是比较热门的同种引擎,但是在接口文档完整性,版本稳定性,开源特性等多个方面考虑,最终选择了Activiti,需要注意的是,我们采用的act版本是7.0.0版本,这个版本强耦合了Security安全框架,我们项目采用的是轻量级框架Shiro,故而我们使用了UserDetailsServiceImpl类实现了Security中的UserDetailsService类,
伪装登录到了Security中,

/**
 * activiti7强绑定了security中的角色,shiro在此伪装登录一次
 * @param username
 * @return
 * @throws UsernameNotFoundException
 */
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{

    String userPasswordDb = new BCryptPasswordEncoder().encode("password");
    String permissions = "ROLE_ACTIVITI_USER,GROUP_activitiTeam";

    UserDetails userDetails =
            new User(username, userPasswordDb,
                    AuthorityUtils.commaSeparatedStringToAuthorityList(permissions));

    return userDetails;
}

与之相关的还有LoginToSecurityApplicationConfiguration中的方法,以及SecurityUtil#logInAs 有兴趣的可以看看:

@Autowired
    private UserDetailsServiceImpl userDetailsService;

    public void logInAs(String username) {
        //======================= start  ====================================

        UserDetails user = userDetailsService.loadUserByUsername(username);
        if (user == null) {
            throw new IllegalStateException("User " + username + " doesn't exist, please provide a valid user");
        }
        SecurityContextHolder.setContext(new SecurityContextImpl(new Authentication() {
            @Override
            public Collection<? extends GrantedAuthority> getAuthorities() {
                return user.getAuthorities();
            }

            @Override
            public Object getCredentials() {
                return user.getPassword();
            }

            @Override
            public Object getDetails() {
                return user;
            }

            @Override
            public Object getPrincipal() {
                return user;
            }

            @Override
            public boolean isAuthenticated() {
                return true;
            }

            @Override
            public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {

            }

            @Override
            public String getName() {
                return user.getUsername();
            }
        }));

        //======================= end  ====================================
        org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);
    }

正文
工作流的核心是 ProcessEngine 接口,ProcessEngine接口定义了获取各种服务类实例对象的方法,我们主要用到的是这四个RepositoryServiceRuntimeServiceTaskServiceHistoryService,具体用法在Activiti中都有阐述,
工作流作为一个工作引擎,有他自己的专属25张表
Activiti使用到的表都是ACT_开头的。
ACT_RE_:流程定义存储。
ACT_RU_
:流程执行记录,记录流程启动到结束的所有动作,流程结束后会清除相关记录。
ACT_ID_:用户记录,流程中使用到的用户和组。
ACT_HI_
:流程执行的历史记录。
ACT_GE_*:通用数据及设置。

表说明如下
act_evt_log --流程定义,详细信息
act_ge_property --属性数据表。存储这个流程引擎级别的数据。
act_procdef_info
act_re_model

–流程部署相关的三张表
act_re_procdef --业务流程定义数据表
act_re_deployment --用来存储部署时需要持久化保存下来的信息
act_ge_bytearray --用来保存部署文件的大文本数据

–流程历史数据,以hi标识,记录流程运行所有信息
act_hi_actinst --流程实例
act_hi_attachment
act_hi_comment --提交审核意见表
act_hi_detail --启动流程或者在任务complete之后,记录历史流程变量
act_hi_identitylink --任务参与者数据表。主要存储历史参与者的信息。
act_hi_procinst --流程实例
act_hi_taskinst --任务实例
act_hi_varinst --历史流程变量数据表

–流程运行时临时数据,以ru标识,流程运行完毕,对应数据消失,表说明参考历史信息
act_ru_deadletter_job
act_ru_event_subscr
act_ru_execution
act_ru_identitylink
act_ru_integration
act_ru_job
act_ru_suspended_job
act_ru_task
act_ru_timer_job
act_ru_variable

–系统业务表
shop_act_info --自定义流程业务表,流程业务和订单业务绑定表
shop_process_model --自定义流程模板表,流程模板表,记录系统新建了哪些流程图

包括部署流程、启动流程、扭转流程、完成流程、驳回流程、填写审批原因、查询流程列表、查询流程流水、反射获取节点上配置的参数等。如没有所需的方法可以从网上获取。

前端引入了Bpmn画图工具,能够绘制流程图,页面如下:

activiti6 有spring security嘛_web安全

排他网关配置如下:

activiti6 有spring security嘛_web安全_02

配置完成后,需要部署流程图,部署流程图之后,流程方才生效,流程图有版本之分,业务单据所绑定的历史流程不会更改,还会依照历史版本的流程图运行