`
wocsok
  • 浏览: 10788 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

JBPM3源代码剖析

阅读更多
 
JBPM3源代码剖析

作者:wocsok

    常用JBPM3的朋友们,也许已经对下面几行代码很熟悉了。这篇文章主要是对JBPM里的源代码进行一些简要的说明,让我们来看看这些方法里到底做了些什么。

JbpmConfiguration configuration =  JbpmConfiguration.getInstance();
JbpmContext jbpmContext = configuration.createJbpmContext();
InputStream is = new FileInputStream("test.par/processdefinition.xml");
ProcessDefinition processDefinition = ProcessDefinition.parseXmlInputStream(is);
jbpmContext.deployProcessDefinition(processDefinition);


引用

在剖析之前,大家先明确几个概念。
1. JbpmConfiguration顾名思义,JBPM的配置,也就是说这个类会包含JBPM的配置信息。
2. ObjectInfo。 JBPM会把配置文件中的对象都封装成ObjectInfo以便进行统一的操作。
3. ObjectFactory。创建ObjectInfo的工厂接口,它只有一个实现类ObjectFactoryImpl。
4. ObjectFactoryParser。解析器,负责解析XML配置文件,校验(判断配置文件标签中的命名,是否所支持的。),以及在创建ObjectInfo实现类的时候,会保存ObjectInfo的名字和对应的对象到一个map里,以后用的时候可以通过名字,直接取出对应的对象。



言归正传,我们先来看看JbpmConfiguration configuration =  JbpmConfiguration.getInstance();
里面的秘密。

	public static JbpmConfiguration getInstance() {
		return getInstance(null);
	}

	public static synchronized JbpmConfiguration getInstance(String resource) {
		// 默认去寻找jbpm.cfg.xml
		if (resource == null) {
			resource = "jbpm.cfg.xml";
		}
		// 从map里去取
		JbpmConfiguration instance = (JbpmConfiguration) instances
				.get(resource);
		// 如果是空的,进行构造,然后缓存到instances这个map里
		if (instance == null) {
			// 判断objectFactory是否存在
			if (defaultObjectFactory != null) {
				instance = new JbpmConfiguration(defaultObjectFactory);
			} else {
				try {
					InputStream jbpmCfgXmlStream = ClassLoaderUtil
							.getStream(resource);
					// 构造一个对象工厂
					ObjectFactory objectFactory = parseObjectFactory(jbpmCfgXmlStream);
					// 构造一个JbpmConfiguration实例
					instance = new JbpmConfiguration(objectFactory);
				} catch (RuntimeException e) {
					throw new JbpmException(
							"couldn't parse jbpm configuration from resource '"
									+ resource + "'", e);
				}
			}
			// 把构建成功的实例,缓存到map里。
			instances.put(resource, instance);
		}
		return instance;
	}

来看一下构建对象工厂的过程。
	protected static ObjectFactory parseObjectFactory(InputStream inputStream) {
		// 构造一个工厂解析器
		ObjectFactoryParser objectFactoryParser = new ObjectFactoryParser();
		// ObjectFactoryImpl对象工厂接口的实现类
		ObjectFactoryImpl objectFactoryImpl = new ObjectFactoryImpl();
		// 解析器对默认的配置文件进行解析,解析成对象,放入ObjectFactoryImpl。
		objectFactoryParser.parseElementsFromResource(
				"org/jbpm/default.jbpm.cfg.xml", objectFactoryImpl);
		// 解析传入的需要解析的资源
		if (inputStream != null) {

			objectFactoryParser.parseElementsStream(inputStream,
					objectFactoryImpl);
		}
		return objectFactoryImpl;
	}
 

看下objectFactoryParser.parseElementsFromResource()做了什么。
  public void parseElementsFromResource(String resource, ObjectFactoryImpl objectFactoryImpl) {
	  //取得XML的根元素
    Element rootElement = XmlUtil.parseXmlResource(resource).getDocumentElement();
    parseElements(rootElement, objectFactoryImpl);
  }
 
把XML里的配置信息,解析成ObjectInfo放入objectFactoryImpl里
	public void parseElements(Element element,
			ObjectFactoryImpl objectFactoryImpl) {
		List objectInfoElements = XmlUtil.elements(element);
		for (int i = 0; i < objectInfoElements.size(); i++) {
			Element objectInfoElement = (Element) objectInfoElements.get(i);
			ObjectInfo objectInfo = parse(objectInfoElement);
			objectFactoryImpl.addObjectInfo(objectInfo);
		}
	}

	// 具体如何解析的
	// 通过反射 生成objectInfo对象
	public ObjectInfo parse(Element element) {
		ObjectInfo objectInfo = null;
		String elementTagName = element.getTagName().toLowerCase();
		// 注: 在构造ObjectFactoryParser对象时,构造函数里进行了
		// 把对应的XML里的标签名 和 所对应应该封装成的类型的构造器(java.lang.reflect.Constructor),
		// 以key-value的形式,存放到mappings里,所以在此处取出Constructor进行实例化。
		Constructor constructor = (Constructor) mappings.get(elementTagName);
		if (constructor == null) {
			throw new JbpmException(
					"no ObjectInfo class specified for element '"
							+ elementTagName + "'");
		}
		try {
			// 注意 之所以在这里采用了回调的方式,把解析器的引用又传给了objectInfo是因为,在objectInfo构造器中,
			// 会把创建成功的 ObjectInfo的实现类的 名字 和 构造完的对象 以KEY-VALUE的形式
			// 存放到解析器的一个MAP里,以便日后直接可以取出
			// 名字对应的对象(没构造之前,只是有一个MAP保存 名字 和 对应的Construct)。
			objectInfo = (ObjectInfo) constructor.newInstance(new Object[] {
					element, this });
		} catch (Exception e) {
			throw new JbpmException("couldn't parse '" + elementTagName
					+ "' into a '" + constructor.getDeclaringClass().getName()
					+ "': " + XmlUtil.toString(element), e);
		}
		return objectInfo;
	}

至此,JbpmConfiguration的创建过程完毕。JbpmConfiguration的创建过程,其实就是把jbpm.cfg.xml配置文件,和default.jbpm.cfg.xml配置文件
进行了解析,然后封装成了对应的ObjectInfo的实现类,放进objectFactoryImpl里,然后所创建的JbpmConfiguration对象里埋了下对objectFactoryImpl的引用
以后我无论再需要创建什么ObjectInfo的实现类,只需要用这个对象工程进行创建就OK了(工厂对象的create()方法,实际上是调用了对应ObjectInfo的create方法)。

现在我们来看看 default.jbpm.cfg.xml都有些什么。
<jbpm-configuration>

  <!--
    This configuration is used when there is no jbpm.cfg.xml file found in the
    root of the classpath.  It is a very basic configuration without persistence
    and message services.  Only the authorization service installed.
    You can parse and create processes, but when you try to use one of the
    unavailable services, you'll get an exception.
  -->
 
  <jbpm-context>
    <service name="persistence" factory="org.jbpm.persistence.db.DbPersistenceServiceFactory" />
    <service name="message" factory="org.jbpm.msg.db.DbMessageServiceFactory" />
    <service name="scheduler" factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" />
    <service name="logging" factory="org.jbpm.logging.db.DbLoggingServiceFactory" />
    <service name="authentication" factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" />
  </jbpm-context>

  <!-- configuration resource files pointing to default configuration files in jbpm-{version}.jar -->
  <string name="resource.hibernate.cfg.xml" value="hibernate.cfg.xml" />
  //还有好多,省略。

  <long   name="jbpm.msg.wait.timout" value="5000" singleton="true" />
  <int    name="jbpm.byte.block.size" value="1024" singleton="true" />
  <string name="mail.smtp.host" value="localhost" />
  <bean   name="jbpm.task.instance.factory" class="org.jbpm.taskmgmt.impl.DefaultTaskInstanceFactoryImpl" singleton="true" />
//还有好多,省略。
</jbpm-configuration>

 //咱们先以简单的 StringInfo 为例,看构造的时候干了些什么。
  public StringInfo(Element stringElement, ObjectFactoryParser configParser) {
  //父类中 这个构造器是 在解析器里map里注册一下,然后判断下是否是单例的(例如:<long name="a" value="5000" singleton="true" />
  就是判断这个标签解析出来的 singleton存在不,如果存在是否是true )
    super(stringElement, configParser);
    s = getValueString(stringElement);
  }
  protected String getValueString(Element element) {
    String value = null;
    if (element.hasAttribute("value")) {
      value = element.getAttribute("value");
    } else {
      value = XmlUtil.getContentText(element);
    }
    return value;
  }
  //StringInfo里 构造函数主要就是解析出对应value的值,看看StringInfo的create();
  public Object createObject(ObjectFactoryImpl objectFactory) {
  //简单吧 就是把解析的value对应的字符串,返回
    return s;
  }


 
下篇文章我们会看一下 复杂点的JbpmContext的创建过程。
JbpmContext jbpmContext = configuration.createJbpmContext();


0
0
分享到:
评论

相关推荐

    jbpm5源代码

    jbpm5是一款非常著名的工作流管理...通过对这些源代码的分析和学习,开发者不仅可以掌握工作流管理的基本原理,还能深入了解如何利用jbpm5构建实际的业务流程管理系统,同时提升在Java、Maven、GWT和BPMN2领域的技能。

    jbpm4.4源代码阅读视频

    1.1构建jbpm4.4源代码于都工程 1.2配置文件解析过程 1.3对象创建过程与binding解析过程 同时由于本人能力有限,时间有限. 这些东西仅仅为抛砖引玉,我是转而已。可能会有一些不到位的地方。 如有不同意见可以...

    基于jbpm框架开发的demo程序源代码

    通过分析和运行这些源代码,开发者可以深入理解jbPM的工作原理和最佳实践。 首先,jbPM的核心概念包括: 1. **流程定义**:jbPM使用Business Process Modeling Notation (BPMN) 2.0标准来描述业务流程,这是一种...

    jbpm4.4源代码阅读第一季发布(共3个视频)

    通过视频教程,你可以逐步剖析jBPM4.4的源代码,学习如何阅读和理解复杂的业务流程管理代码,进一步提升你在企业级应用开发中的技能。同时,结合实际的示例和练习,有助于巩固理论知识,提高解决问题的能力。

    JBPM4 java源代码分包详解JBPM4

    【JBPM4 Java源代码分包详解】 JBPM4是一个流行的开源工作流管理系统,它提供了一整套用于设计、执行和管理业务流程的工具。在深入研究JBPM4的源代码时,我们可以从其包结构中了解到框架的核心功能和设计理念。 1....

    传智播客 jbpm 21讲 第4天 (共4天) 及源代码

    10. **源代码分析**:通过提供的源代码,分析jbpm的实例应用,帮助学员更好地理解和应用所学知识。 课程结束后,你应能掌握jbpm的基本操作,具备设计和实施简单到复杂业务流程的能力。同时,通过源代码的学习,可以...

    JBPM4_PVM源代码分析.doc

    ### JBPM4_PVM源代码分析 #### 一、概览 JBPM4_PVM(Process Virtual Machine)是JBPM框架中的一个核心组件,用于处理流程执行的核心逻辑。本文档将详细解析JBPM4_PVM的源代码结构,重点介绍其中的关键类及其功能...

    Jbpm源代码分包详解

    通过以上分析,我们可以看出Jbpm的源代码分包设计是高度模块化的,每个包都有明确的职责,使得系统易于扩展和维护。开发者可以根据自己的需求,深入研究和定制这些包中的类和接口,以适应特定的业务场景。

    jbpm请假例子完整源代码

    **jbpm请假例子完整源代码**是一套基于jbpm流程引擎的示例应用,它用于演示如何在实际项目中利用jbpm实现一个简单的请假流程。jbpm是一个开源的工作流管理系统,它提供了强大的业务流程建模、执行和管理能力。本示例...

    jbpm的扩展源代码

    jbpm(JBoss Business Process ...通过分析这些源代码,我们可以了解开发者如何根据实际需求对jbpm进行了定制,从而更好地理解和应用jbpm框架。对于想要深入了解jbpm和业务流程管理的人来说,这是一个宝贵的资源。

    一个Jbpm实例代码

    学习这个Jbpm实例代码,你需要理解上述概念,并通过阅读源代码来了解如何将这些概念应用到实际项目中。这包括流程的启动、任务的处理、流程状态的查询和控制,以及与外部系统的交互等。此外,你还可以深入研究Drools...

    一个Jbpm员工请假流程的实例(源代码)

    总的来说,这个Jbpm员工请假流程实例通过源代码展示了如何使用Jbpm设计、实现和管理一个实际的业务流程。它涉及了流程建模、服务接口设计、数据库交互和自动化构建等方面,为学习和理解Jbpm提供了一个完整的参考案例...

    JBPM4.0源码以及分析

    在提供的"src"目录下,我们可以深入研究JBPM4.0的源代码,了解其内部实现。源码分析通常从以下几个关键模块入手: - **org.jbpm.process.core**: 这个包包含了流程核心组件,如流程定义、节点、连接件等的实现。 - ...

    【转载 见附件】纵观jBPM:从jBPM3到jBPM5以及Activiti5

    1. **源码** - 标签提示文章可能涉及jBPM和Activiti5的源代码分析,可能包括它们的架构设计、内部实现机制或者开发者如何通过源码进行扩展和定制。 2. **工具** - 暗示jBPM和Activiti5是作为开发工具或平台被讨论,...

    JBPM采购申请系统整套源代码和整套流程第二部分

    总的来说,JBPM采购申请系统整套源代码和流程为开发者提供了一个全面的实践平台,不仅可以用于构建实际的采购管理系统,也能作为学习和研究业务流程管理技术的宝贵资源。通过深入研究和实践,开发者将能更好地理解和...

    JBPM使用实例,sql spring

    2. **项目源代码(全,不含jar包).rar**:这可能是一个完整的JBPM项目源代码,包含了流程定义、服务实现、配置文件等,用于展示如何在实际项目中使用JBPM和Spring进行流程管理。 3. **sql.rar**:这个压缩包可能...

    JBPM采购申请系统整套源代码和整套流程第一部分

    在这个“JBPM采购申请系统整套源代码和整套流程第一部分”中,我们将深入探讨JBPM如何被应用于构建一个完整的采购申请系统,以及其核心功能和流程的实现。 首先,我们要理解JBPM的核心概念。JBPM支持BPMN2.0标准,...

    JBPM案例详解(全)

    提供的“JBPM案例详解”包含了一系列示例的源代码,读者可以通过阅读和实践这些代码,更深入地理解JBPM的工作原理和用法。每个案例都有清晰的注释和说明,有助于读者快速上手和解决问题。 总结,JBPM作为一款强大的...

    jbpm-3.1.2.zip_jbpm_jbpm 3.1.2_jbpm-3.1.2.rar_jbpm3.1.2_工作流

    - `jbpm-3.1.2`:这可能是一个解压后的目录,其中可能包括了jBpm 3.1.2的源代码、库文件、文档、示例和其他资源。 对于初学者来说,了解jBpm的架构和API,学习如何使用BPMN进行流程建模,以及掌握如何部署和运行...

    jbpm-4.3-src.rar_bdf-jbpm4 src _jboss 4.3_jboss jbpm4.3_jbpm-4.3

    jbpm-4.3-src.rar_bdf-jbpm4 src _jboss 4.3_jboss jbpm4.3_jbpm-4.3 这个压缩包文件包含的是JBOSS jBPM4.3的源代码,这是一个用于业务流程管理(BPM)的开源框架。jBPM是一个强大的工具,它提供了流程定义、执行和...

Global site tag (gtag.js) - Google Analytics