在默认情况下,jBPM包里有个jbpm.cfg.xml,这个就是他的配置文件,我们先看下它的内容.
	 
										
										
												
														
 <jbpm-configuration>
  <import resource="jbpm.default.cfg.xml" />
  <import resource="jbpm.tx.jta.cfg.xml" />
  <import resource="jbpm.jpdl.cfg.xml" />
  <import resource="jbpm.identity.cfg.xml" />	
  <import resource="jbpm.jobexecutor.cfg.xml" />	
</jbpm-configuration>
										
										
													 
	 这里,我们再继续看下jbpm.default.cfg.xml,看下配置文件到底是长啥样.
	 
										
										
												
														
  <process-engine-context> 
    <repository-service />
    <repository-cache />
    <execution-service />
    <history-service />
    <management-service />
    <identity-service />
    <task-service />
    <hibernate-configuration>
      <cfg resource="jbpm.hibernate.cfg.xml" />     
    </hibernate-configuration>
	...........
  </process-engine-context>
  <transaction-context>
    <repository-session />
    <db-session />   
    <message-session />
    <timer-session />
    <history-session />
    <mail-session>
      <mail-server>
        <session-properties resource="jbpm.mail.properties" />
      </mail-server>
    </mail-session>
  </transaction-context>
										
										
													 
  这个配置文件主要包含了"process-engine-context'和 'transaction-context'的配置.	 
	
										
										
												我们知道,现在都是讲究Dependency Inject (Inversion of Control),那么,我们这里到底是哪个类来实现repository-service呢?那配置mail-session又是怎么实例化的呢?
我们先来看下jBPM的IOC实现机制.  
	
										
										
												首先是Context接口,你可以从这里存储,获得对象.它的接口很简单. 
    
	 
										
										
												  Object get(String key);
  <T> T get(Class<T> type);
  Object set(String key, Object value);
										
										
												你看可以从Context中获取到组件,对于IOC容器来说,一般情况下都会提供一种加载的方式,比如从xml文件进行加载、从资源文件进行加载。
    
										
										
													
Jbpm4是通过WireParser来解析xml,然后创建并把对象存放在WireContext. WireContext这个类负责存放,提取对象,内部用一个Map来存储已经创建的对象实例,可以简单得把他看成是IOC的一个实现类.
从WireContext的javadoc,我们可以看出,他主要是跟WireDefinition, Descriptor打
交道. WireContext里面
包含了一个WireDefinition,而WireDefinition里面包含了一系列的Descriptor.每个Descriptor负责创建和
初始化该对象. 比如我们可以看到IntegerDescriptor, FloatDescriptor, ObjectDescriptor等等.
我们来看下Descriptor的接口: 
										
										
												
														
  /**
   * constructs the object.
   * @param wireContext {@link WireContext} in which the object is created. This is also the {@link WireContext} 
   * where the object will search for other object that may be needed during the initialization phase.
   * @return the constructed object.
   */
  Object construct(WireContext wireContext);
  /**
   *called by the WireContext to initialize the specified object.
   */
  void initialize(Object object, WireContext wireContext);
										
										
													 
Descriptor对象的创建可以直接通过Java对象的实例化,比如(new IntegerDescriptor(..)),也可以通过xml的配置文件来实现.可以说我们更经常用xml来配置,所以就有了Binding的概念.
Binding类最主要的任务就是把XML DOM 到Java对象的转换. Bindings是把Binding归类了一下而已.
以下是Binding的接口.
	 
										
										
												
														
public interface Binding { 
  String getCategory();
  /** does this binding apply to the given element? */
  boolean matches(Element element);
  /** translates the given element into a domain model java object.
   * Use the parse to report problems. 
   */
  Object parse(Element element, Parse parse, Parser parser);
}
										
										
												如果想看实现,我们可以看下IdentityServiceBinding, RepositoryServiceBinding等等.这里注意下,在jBPM的实现当中,WireDescriptorBinding是根据tagName来解析的.
所以,从jBPM的xml配置文件,到ProcessEngine对象的构建,是这样的一个流程.
										
										
												 jbpm.cfg.xml –>  jBPMConfigurationParser ->  Binding –>  Descriptor --> WireContext
										
										
												或者更清楚的,我们可以看下下面这张图[
												
														1].
 
										
我们不妨也看下ConfigurationTest测试.
	 
										
												
  public void testConfigurationServices() {
    ProcessEngine processEngine = new Configuration()
        .setXmlString(
            "<jbpm-configuration>" +
            "  <process-engine-context>" +
            "    <repository-service />" +
            "    <execution-service />" +
            "    <management-service />" +
            "  </process-engine-context>" +
            "</jbpm-configuration>"
        )
        .buildProcessEngine();
    assertNotNull(processEngine);
    assertNotNull(processEngine.getExecutionService());
    assertNotNull(processEngine.getManagementService());
  }
										
												
														Configuration
												类是jBPM的入口,你可以从
Configuration类中创建ProcessEngine,而从ProcessEngine中获取到RepositoryService,
ExecutionService, TaskService等等.
Configuration类里有两个实现类,一个是JbpmConfiguration,这是默认的jBPM自带的Configuration解析器,
另外一个是SpringConfiguration,这个是jBPM和Spring的集成.
在这里,我们就只看下JbpmConfiguration的实现,在JbpmConfiguration类里,我们可以看到他是这么去调用Parser来
解析xml的. 
										
												
 protected void parse(StreamInput streamSource) {
   isConfigured = true;
   JbpmConfigurationParser.getInstance()
     .createParse()
     .pushObject(this)
     .setStreamSource(streamSource)
     .execute()
     .checkErrors("jbpm configuration " + streamSource);
 }
										
										
										
在这里,我们可以看到,jbpm的配置文件是有两个元素组成的,一个是process-engine-context,另外一个是transaction-context. 其中process-engine-context里面的元素是包括了对外发布的服务,
比如repository-service, execution-service等等. 而transaction-context则包括了他的内部真正实现,比如repository-service对应repository-session.
也可以简单的把repository-servie看做是API, repository-session看做是SPI. 这样做的好处是,SPI的实现,对API一点影响都没有,很大程度上提供了一个容易集成的特性.
  
										
说到这里,应该对jBPM的IOC介绍的差不多了.我自己在用JBoss IDM project[2]来实现jBPM的Identity module时.需要增加如下的配置.
	 
										
												
<jbpm-configuration>
  <process-engine-context>
    <jboss-idm-identity-session-factory jndi="java:/IdentitySessionFactory" />
  </process-engine-context>
  <transaction-context>
    <jboss-idm-identity-session realm="realm://JBossIdentity" />
  </transaction-context>
</jbpm-configuration>
										
于是,我需要增加以下的类来完成对象的创建和实例化. JbossIdmIdentitySessionFactoryBinding,JbossIdmIdentitySessionFactoryDescriptor,JbossIdmIdentitySessionBinding,
JbossIdmIdentitySessionDescriptor
然后,在jbpm.wire.bindings.xml里面注册我们新加的Binding.
从上面我们所说的,不难看出本身这个IOC的实现机制也是很简单的,而且也很容易扩展,如果说到时候和Spring, JBoss MC等IOC容器的集成也是很方便的.