Activiti源码分析(框架、核心类。。。)

LD is tigger forever,CG are not brothers forever, throw the pot and shine forever.
Modesty is not false, solid is not naive, treacherous but not deceitful, stay with good people, and stay away from poor people.
talk is cheap, show others the code,Keep progress,make a better result.
Survive during the day and develop at night。

目录

概 述

Activiti是业界很流行的java工作流引擎,

在这里插入图片描述

Activiti基于Spring,ibatis等开源中间件作为软件平台,在此之上构建了非常清晰的开发框架。上图列出了Activiti的核心组件。

1.ProcessEngine:流程引擎的抽象,对于开发者来说,它是我们使用Activiti的facade,通过它可以获得我们需要的一切服务。

2.XXService(TaskService,RuntimeService,RepositoryService…):Activiti按照流程的生命周期(定义,部署,运行)把不同阶段的服务封装在不同的Service中,用户可以非常清晰地使用特定阶段的接口。通过ProcessEngine能够获得这些Service实例。TaskService,RuntimeService,RepositoryService是非常重要的三个Service:

TaskService:流程运行过程中,与每个任务节点相关的接口,比如complete,delete,delegate等等

RepositoryService:流程定义和部署相关的存储服务。

RuntimeService:流程运行时相关服务,如startProcessInstanceByKey.

关于ProcessEngine和XXService的关系,可以看下面这张图:

在这里插入代码片

在这里插入图片描述
3.CommandContextIntercepter(CommandExecutor):Activiti使用命令模式作为基础开发模式,上面Service中定义的各个方法都对应相应的命令对象(xxCmd), Service把各种请求委托给xxCmd,xxCmd来决定命令的接收者,接收者执行后返回结果。而CommandContextIntercepter顾名思义,它是一个拦截器,拦截所有命令,在命令执行前后执行一些公共性操作
CommandContextIntercepter的核心方法:

 public <T> T execute(Command<T> command) {  
    CommandContext context = commandContextFactory.createCommandContext(command);  
  
    try {  
//执行前保存上下文  
      Context.setCommandContext(context);  
      Context.setProcessEngineConfiguration(processEngineConfiguration);  
      return next.execute(command);//执行命令  
        
    } catch (Exception e) {  
      context.exception(e);  
        
    } finally {  
      try {  
//关闭上下文,内部会flush session,把数据持久化到db等  
        context.close();  
      } finally {  
//释放上下文  
        Context.removeCommandContext();  
        Context.removeProcessEngineConfiguration();  
      }  
    }  
      
    return null;  
  }  

2)使用命令模式的好处,我这里体会最深的就是 职责分离,解耦。有了Command,各个Service从角色上说只是一些协调者或者控制者,他不需要知道具体怎么做,他只是把任务交给了各个命令。直接的好处是臃肿的、万能的大类没有了。而这往往是我们平时开发中最深恶痛绝的地方。
在这里插入图片描述

askEntity实现了3个接口:Task,DelegateTask和PersistentObject。其中PersistentObject是一个声明接口,表明TaskEntity需要持久化。接口是一种角色的声明,是一份职责的描述而TaskEntity就是这个角色的具体扮演者,因此TaskEntity必须承担如complete,delegate等职责。

5.Activiti的上下文组件(Context)
上下文(Context)用来保存生命周期很长的、全局性的信息。Activiti的Context类(在org.activiti.engine.impl.context包下)保持如下三类信息:
在这里插入图片描述
CommandContext:命令上下文,保持每个命令需要的必要资源,如持久化需要的session。
mailServerHost,DataSource等。单例。该实例在流程引擎创建时被实例化,其调用stack如下图:
在这里插入图片描述

在这里插入图片描述
顶层接口是Session和SessionFactory,这都非常好理解了。
Session有两个实现类:
DbSqlSession:简单点说,DbSqlSession负责sql表达式的执行。
AbstractManager:简单点说,AbstractManager及其子类负责面向对象的持久化操作
同理DbSqlSessionFactory与GenericManagerFactory的区别就很好理解了。
在这里插入图片描述
用户可以介入的代码类型包括:TaskListener,JavaDelegate,Expression,ExecutionListener。

ProcessEngineConfigurationImpl持有DelegateInterceptor的某个实例,这样就可以随时非常方便地调用handleInvocation

8.Cache 组件
对Activiti的cache实现很感兴趣,但现在我了解到的情况(也许还没有了解清楚)其cache的实现还是很简单的,在DbSqlSession中有cache实现:

protected List<PersistentObject> insertedObjects = new ArrayList<PersistentObject>();  
protected Map<Class<?>, Map<String, CachedObject>> cachedObjects = new HashMap<Class<?>, Map<String,CachedObject>>();  
protected List<DeleteOperation> deletedObjects = new ArrayList<DeleteOperation>();  
protected List<DeserializedObject> deserializedObjects = new ArrayList<DeserializedObject>(); 

也就是说Activiti就是基于内存的List和Map来做缓存的。具体怎么用的呢?以DbSqlSession.selectOne方法为例:

public Object selectOne(String statement, Object parameter) {  
  statement = dbSqlSessionFactory.mapStatement(statement);  
  Object result = sqlSession.selectOne(statement, parameter);  
  if (result instanceof PersistentObject) {  
    PersistentObject loadedObject = (PersistentObject) result;  
缓存处理  
    result = cacheFilter(loadedObject);  
  }  
  return result;  
}  
 protected PersistentObject cacheFilter(PersistentObject persistentObject) {  
    PersistentObject cachedPersistentObject = cacheGet(persistentObject.getClass(), persistentObject.getId());  
    if (cachedPersistentObject!=null) {  
//如果缓存中有就直接返回  
      return cachedPersistentObject;  
    }  
//否则,就先放入缓存  
    cachePut(persistentObject, true);  
    return persistentObject;  
  }  

9.异步执行组件
在这里插入图片描述

Job组件

JobExecutor是异步执行组件的核心类,其包含三个主要属性:
1)JobAcquisitionThread jobAccquisitionThread:执行任务的线程 extends java.lang.Thread
2)BlockingQueue threadPoolQueue
3)ThreadPoolExecutor threadPoolExecutor:线程池

方法ProcessEngines在引擎启动时调用JobExecutor.start,JobAcquisitionThread 线程即开始工作,其run方法不断循环执行AcquiredJobs中的job,执行一次后线程等待一定时间直到超时或者JobExecutor.jobWasAdded方法因为有新任务而被调用

在这里插入代码片

PVM:Process Virtal Machine,流程虚拟机API暴露了流程虚拟机的POJO核心,流程虚拟机API描述了一个工作流流程必备的组件,这些组件包括:

PvmProcessDefinition:流程的定义,形象点说就是用户画的那个图。静态含义。

PvmProcessInstance:流程实例,用户发起的某个PvmProcessDefinition的一个实例,动态含义。

PvmActivity:流程中的一个节点

PvmTransition:衔接各个节点之间的路径,形象点说就是图中各个节点之间的连接线。

PvmEvent:流程执行过程中触发的事件
以上这些组件很好地对一个流程进行了建模和抽象。每个组件都有很清晰的角色和职责划分。另外,有了这些API,我们可以通过编程的方式,用代码来“画”一个流程图并让他run起来,例如:

PvmProcessDefinition processDefinition = new ProcessDefinitionBuilder()  
        .createActivity("a").initial().<strong style="background-color: #ff0000;">behavior</strong>(new WaitState())  
        .transition("b").endActivity().createActivity("b")  
        .behavior(new WaitState()).transition("c").endActivity()  
        .createActivity("c").behavior(new WaitState()).endActivity()  
        .buildProcessDefinition();  
PvmProcessInstance processInstance = processDefinition  
        .createProcessInstance();  
processInstance.start();  
PvmExecution activityInstance = processInstance.findExecution("a");  
assertNotNull(activityInstance);  
activityInstance.signal(null, null);  
activityInstance = processInstance.findExecution("b");  
assertNotNull(activityInstance);  
activityInstance.signal(null, null);  
activityInstance = processInstance.findExecution("c");  
assertNotNull(activityInstance);  

粗体红色背景的behavior方法,为一个PvmActivity增加ActivityBehavior,这是干什么呢?ActivityBehavior是一个interface,其接口声明很简单:

/** 
 * @author Tom Baeyens 
 */  
public interface ActivityBehavior {  
  
  void execute(ActivityExecution execution) throws Exception;  
}  

ExecutionEntity.signal方法核心工作就是把发信号的工作委托给PvmActivity的activityBehavior. 这里的设计存在问题,很显然其触犯了一个代码的坏味道:消息链。它让ExceutionEntity没有必要地与SignallableActivityBehavior 产生了耦合,更好的做法应该是PvmActivity提供signal方法,其内部调用ActivityBehavior完成发信号工作。

总结:

相关工具如下:

分析:

小结:

主要讲述了接下来Activiti源码分析(框架、核心类。。。),请大家指正~

参考资料和推荐阅读

1.链接: 参考资料.

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

执于代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值