JBPM源码分析(-)-----JbpmConfigurtion

在本节,我们来分析一下jbpm的jbpmConfiguration类

我们生成jbpmConfiguration一般都是通过如下几个方法:

public static JbpmConfiguration getInstance() {
    return getInstance(null);
  }
  public static JbpmConfiguration getInstance(String resource) {
    
    JbpmConfiguration instance = null;
    
    synchronized(instances) {
      if (resource==null) {
        resource = " jbpm.cfg.xml";
      }

      instance = (JbpmConfiguration) instances.get(resource);
      if (instance==null) {

        if (defaultObjectFactory!=null) {
          log.debug("creating jbpm configuration from given default object factory

'"+defaultObjectFactory+"'");
          instance = new JbpmConfiguration(defaultObjectFactory);

        } else {
          
          try {
            log.info("using jbpm configuration resource '"+resource+"'");
            InputStream jbpmCfgXmlStream = ClassLoaderUtil.getStream(resource);

            if (jbpmCfgXmlStream==null)
              throw new JbpmException("jbpm configuration resource '"+resource+"' is not

available");

            ObjectFactory objectFactory = parseObjectFactory(jbpmCfgXmlStream);
            instance = createJbpmConfiguration(objectFactory);
            
          } catch (RuntimeException e) {
            throw new JbpmException("couldn't parse jbpm configuration from resource

'"+resource+"'", e);
          }
        }

        instances.put(resource, instance);
      }
    }

    return instance;
  }

从上面的三种方式,我们可以发现jbpmConfiguration是 一个不完全封闭的多例模式,他里面含有一个静

态的hashMap中,存储这JbpmConfiguration实例; 每一个实例都对应的是一个resource文件,也就是说一

个资源文件对应一个实例;

JbpmConfiguration实例还允许用户自己new实例化实例,并没有平常单例模式那样将其构造方法私有化,

允许了用户的自定义传入对象工厂;

下面我们来详细的了解一个其方法:

由下面这句我们知道newInstance的时候是 线程安全的

synchronized(instances)


下面这两句分别是得到这个资源文件的输入流,并且对他进行解析:

 ObjectFactory objectFactory = parseObjectFactory(jbpmCfgXmlStream);
 instance = createJbpmConfiguration(objectFactory);

 解析资源文件得到一个ObjectFactory对象:

 protected static ObjectFactory parseObjectFactory(InputStream inputStream) {
    log.debug("loading defaults in jbpm configuration");
    //构造解析的功能对象;
    ObjectFactoryParser objectFactoryParser = new ObjectFactoryParser();
    //对象工厂能够生产出对象;
    ObjectFactoryImpl objectFactoryImpl = new ObjectFactoryImpl();
    //会先解析org/jbpm/default.jbpm.cfg.xml的默认配置文件;
    objectFactoryParser.parseElementsFromResource(" org/jbpm/default.jbpm.cfg.xml",

objectFactoryImpl);

    if (inputStream!=null) {
      //然后在解析子定义的文件;
      objectFactoryParser.parseElementsStream(inputStream, objectFactoryImpl);
    }

    return 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);
    }
  }

public ObjectInfo parse(Element element) {
    //被解析每一个子元素都是一个Bean的信息,他描述了这个bean的类型以及值;记住,只是类型
    //对象工厂拿到这些bean类型能够生成bean对象;
    ObjectInfo objectInfo = null;
    String elementTagName = element.getTagName().toLowerCase();
    // 这个地方是用反射来实例化beanInfo对象;
    Constructor constructor = (Constructor) mappings.get(elementTagName);
    if (constructor==null) {
      throw new JbpmException("no ObjectInfo class specified for element

'"+elementTagName+"'");
    }
    try {
      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;
  }


从下面这个mapping我们可以看出来:

if (defaultMappings==null) {
      defaultMappings = new HashMap();
      addMapping(defaultMappings, "bean",         BeanInfo.class);
      addMapping(defaultMappings, "ref",          RefInfo.class);
      addMapping(defaultMappings, "list",         ListInfo.class);
      addMapping(defaultMappings, "map",          MapInfo.class);
      addMapping(defaultMappings, "string",       StringInfo.class);
      addMapping(defaultMappings, "int",          IntegerInfo.class);
      addMapping(defaultMappings, "integer",      IntegerInfo.class);
      addMapping(defaultMappings, "long",         LongInfo.class);
      addMapping(defaultMappings, "float",        FloatInfo.class);
      addMapping(defaultMappings, "double",       DoubleInfo.class);
      addMapping(defaultMappings, "char",         CharacterInfo.class);
      addMapping(defaultMappings, "character",    CharacterInfo.class);
      addMapping(defaultMappings, "boolean",      BooleanInfo.class);
      addMapping(defaultMappings, "true",         BooleanInfo.class);
      addMapping(defaultMappings, "false",        BooleanInfo.class);
      addMapping(defaultMappings, "null",         NullInfo.class);
      addMapping(defaultMappings, "jbpm-context", JbpmContextInfo.class);
      addMapping(defaultMappings, "jbpm-type",    JbpmTypeObjectInfo.class);
    }

能够根据这个tag名字找到实例化的构造函数,因为他们有同样参数的构造函数,这样就很好进行统一的

反射:

static void addMapping(Map mappings, String elementTagName, Class objectInfoClass) {
    try {
      Constructor constructor =

objectInfoClass.getDeclaredConstructor(constructorParameterTypes);
      mappings.put(elementTagName, constructor);
    } catch (Exception e) {
      throw new JbpmException("couldn't add mapping for element '"+elementTagName+"':

constructor("+Element.class.getName()+","+ObjectFactoryParser.class.getName()+") was missing

for class '"+objectInfoClass.getName()+"'", e);
    }
  }


通过这样,我们可以看见如下的类图;



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值