整个流程引擎应该分为三个部分,config, context组成构成process的基本部分,template作为整个process串联的基础,生成weavable,然后通过weavable,并辅助相关的scm的状态,最后拼接成一串的process节点,即完成整个流程的渲染过程。
首先config方面,基本存储静态的变量,如key, name, description等,
这里面有一个小技巧,由于config可以有多种的实现方式,于是其接口config只是定义基本的get方法,由各种实现去具体实现get方法,这样其他类来调用的时候,只需调用get方法就有取到相应的静态变量,而不需要特意在接口处定义变量。
如下面所示1
2
3
4
5
6public interface Config extends Serializable {
public Integer getId();
public String getKey();
public String getName();
…
}
关于config的实现,现有2个基本的实现,一是commonConfig,即普通的节点的config,如申请四位版本,模块编译等,主要是scm的操作的一些process;另一种是actionConfig,即由baseinfo定义的一些action转化的process。这里有一个感想,针对我们后面的统一化管理,可以将这两种都归结于actionConfig,申请四位版本和模块编译等,都可以作为action来存储在icafe中,icafe在开发任务task中加入相关的action即可。
然后是template部分。这里的template以baseinfo的模板作为基础,根据不同的任务,进行相关的操作,并生成weavable。这里的weavable,作为一个list,其实已经是简版的流程节点的串联,其包含相应的process的key以及process后需的节点的key和相应的type。
以开发任务的action为例,首先是判断该action是否被裁剪掉了,来判断是否要加入到weavable中去;然后设置相应的weavable的key和weaveType;最后转化相应的action的信息,放入到configMap中去,方便后面调用。
这里重点讲一下addOnline方面。
- 首先对于上线部分,其作为一个大的task存在,这里有个小技巧,将task转化为action,从而可以同上面的addAction相同的处理
1
ActionConfigAdapter config = new ActionConfigAdapter(convert(task));
其次,针对上线方式部分,采用获取从icafe中相关的上线方式,然后将相关action转化为sqaActionTemplate后,作为process的child节点加入到weavable中去.
1
2
3
4
5
6
7
8
9
10
11
12for(ActionInfo act : actionInfos){
String key = ConfigDataUtil.getKeyActionByProcssDefineId(act.getActionDefineid());
w.setWeaveKey(key);
w.setWeaveType(WeaveType.CHILD.name());
weavables.add(w);
ActionConfigAdapter actConfig = new ActionConfigAdapter(convert(act));
configMap.put(key, actConfig);
w = new Weavable();
w.setKey(pk);
}
这里有部分不能理解的是上线方式居然是从icafe中获取,而不是从baseinfo中获取。这里影射出icafe同baseinfo之间的关系若即若离,icafe既想同baseinfo切除关系,但是又很多的内容依赖于baseinfo,这层关系还需慢慢梳理,慢慢切除。
完成了template部分的解析,就会得到两个比较重要的变量,即
List<Weavable> weavables
和Map<String, Config> configMap
,前者即为流程串联的list,后者为相关的config信息,后面就是weaver部分,这部分就是将这两者加入scm的一些辅助状态,一起串联成为我们所谓的process串。同样,这个串联过程大致分为三个部分:- context的相关信息的初始化。前面讲到了context里存放着process的上下文环境,这里主要是一些scm的状态。这里拿到的是scmProcessContext,实际上映射着DefaultScmContext(吐槽一句:这个东西能不能相同命名,不然还需要去xml去寻找相应的对应关系,命令的规范遵循的是什么。。。),这里拿到
codePath
和codeVersion
,以及最重要的Map<String, ScmOperateBean> scmOperates
但是,在这个串联的后续步骤中,个人感觉这个东西没有用到。。 - 随后便是遍历
List<Weavable> weavables
结构,首先从相关的configMap
依据相应的weavable
的key值取得相应的config,然后通过
1
process = (Process) applicationContext.getBean(beanName, Process.class);
- context的相关信息的初始化。前面讲到了context里存放着process的上下文环境,这里主要是一些scm的状态。这里拿到的是scmProcessContext,实际上映射着DefaultScmContext(吐槽一句:这个东西能不能相同命名,不然还需要去xml去寻找相应的对应关系,命令的规范遵循的是什么。。。),这里拿到
来初始化相应的process,同时将process加入到Map<String, Process> processMap
中。
随后,从processMap中选取第一个节点作为headProcess返回即可。
感想:
context这个变量的设计感觉毫无头绪。首先对于
scmOperates
的初始化,可以放在template的解析中,同样也是属于状态的解析;其次,对于processMap
,依然可以放在template的解析中;这样导致就是process中的context变量还有没有意义?对于processMap的设计初衷是什么?既然是遍历weavables,然后按顺序将生成的process加入到processMap中去,为什么不继续复用weavables,而要另开一个map?
对于
SqaTaskTemplateAdapter
这个结构的extends关系,感觉不是很理解,为后面的扩展性的需要有什么帮助?直接作为引擎的一个实现,这才是他的核心吧得到headProcess之后,然后就是processRender的工作。这方面没什么好说的。
至此,整个流程模板的渲染过程大致介绍完毕。下图是流程的介绍说明。