ofbiz3-entity的加载流程

类别:Java 点击:0 评论:0 推荐:

 
   GenericDelegator.java
 
 protected GenericDelegator(String delegatorName) throws GenericEntityException {
        if (Debug.infoOn()) Debug.logInfo("Creating new Delegator with name \"" + delegatorName + "\".", module);

        this.delegatorName = delegatorName;
        if (keepLocalReaders) {
   /*
      读取 components\accounting\entitydef\entitymodel.xml等文件,
      这些文件是配置在components\...\ofbiz-component.xml中
   */
            modelReader = ModelReader.getModelReader(delegatorName);

            /*
     Group的方法和Model的读取方法类似,也是先从entitymodel.xml和ofbiz-component.xml
     取到资源文件,然后加载.
     有一点须要说明:
   
   */
            modelGroupReader = ModelGroupReader.getModelGroupReader(delegatorName);
        }

        primaryKeyCache = new UtilCache("entity.FindByPrimaryKey." + delegatorName, 0, 0, true);
        allCache = new UtilCache("entity.FindAll." + delegatorName, 0, 0, true);
        andCache = new UtilCache("entity.FindByAnd." + delegatorName, 0, 0, true);

        // initialize helpers by group
  /*
   一个Group包含多个entitymodel.不同的Group可以对应不同的数据源,也就是说,可以和多个数据库相连
  */
        Iterator groups = UtilMisc.toIterator(getModelGroupReader().getGroupNames());

        while (groups != null && groups.hasNext()) {
   /*
      取到entityengine.xml中定义的group
      比如:
             <delegator name="default" entity-model-reader="main" entity-group-reader="main" entity-eca-reader="main" distributed-cache-clear-enabled="false">
               <group-map group-name="org.ofbiz" datasource-name="localmssql"/>
         <group-map group-name="other" datasource-name="localpostgres"/>
            </delegator>
      你定义entitygroup.xml文件中就可以这样定义
            <entitygroup>
              <entity-group group="other" entity="SequenceValueItem" />
              <entity-group group="org.ofbiz" entity="SequenceValueItem" />
            </entitygroup>

         
   */
            String groupName = (String) groups.next();
            String helperName = this.getGroupHelperName(groupName);

            if (Debug.infoOn()) Debug.logInfo("Delegator \"" + delegatorName + "\" initializing helper \"" +
                    helperName + "\" for entity group \"" + groupName + "\".", module);
            TreeSet helpersDone = new TreeSet();

            if (helperName != null && helperName.length() > 0) {
                // make sure each helper is only loaded once
                if (helpersDone.contains(helperName)) {
                    if (Debug.infoOn()) Debug.logInfo("Helper \"" + helperName + "\" already initialized, not re-initializing.", module);
                    continue;
                }
                helpersDone.add(helperName);
                // pre-load field type defs, the return value is ignored
    /*
      读取group 对应的fieldtype,这些文件处在entity/fieldtype
    
    */
                ModelFieldTypeReader.getModelFieldTypeReader(helperName);
                // get the helper and if configured, do the datasource check
                GenericHelper helper = GenericHelperFactory.getHelper(helperName);
                /*
       生成group对应的datasourceinfo
    */
                EntityConfigUtil.DatasourceInfo datasourceInfo = EntityConfigUtil.getDatasourceInfo(helperName);

                if (datasourceInfo.checkOnStart) {
                    if (Debug.infoOn()) Debug.logInfo("Doing database check as requested in entityengine.xml with addMissing=" + datasourceInfo.addMissingOnStart, module);
                    try {
      /*
        1:读取group对应数据库所在的表
        2:读取group对应数据所有的列
        3:读到group对应的索引等...
        它的读取方法有点特别,至少我是第一次见过,一般我们是从系统表里面去取,而它不是.
        有兴趣可以看看DatabaseUtil.java里面的 checkdb方法,简单地copy一些代码出来
        取table
         DatabaseMetaData dbData = this.getDatabaseMetaData(connection, messages);
         String[] types = {"TABLE", "VIEW", "ALIAS", "SYNONYM"};
         tableSet = dbData.getTables(null, lookupSchemaName, null, types);
                          取 col
                           ResultSet rsCols = dbData.getColumns(null, lookupSchemaName, null, null);
        4:this.getModelEntityMapByGroup(groupName)表示得到group对应的所有entity
        checkDataSource的作用很明显,它用读到tables,columns,indexes等与entitymodel相比较,
        如果不同,它就以entitymodel为基准,修改数据库,修改时都采用alert table等sql语句,
        这样,ofbiz服务启动时,就会自动的把entitymodel中对应的关系反映到数据库,由于entitymodel]
        并不是象hibenate那样,对应一个JavaBean,所以我们可以在系统运行时,很方便的修改entitymodel,
        进而修改数据库,而不用动另何java文件.

      */
                        helper.checkDataSource(this.getModelEntityMapByGroup(groupName), null, datasourceInfo.addMissingOnStart);
                    } catch (GenericEntityException e) {
                        Debug.logWarning(e.getMessage(), module);
                    }
                }
            }
        }

        //time to do some tricks with manual class loading that resolves circular dependencies, like calling services...
        ClassLoader loader = Thread.currentThread().getContextClassLoader();

        // if useDistributedCacheClear is false do nothing since the
        // distributedCacheClear member field with a null value will cause the
        // dcc code to do nothing
        if (getDelegatorInfo().useDistributedCacheClear) {
            // initialize the distributedCacheClear mechanism
            String distributedCacheClearClassName = getDelegatorInfo().distributedCacheClearClassName;

            try {
                Class dccClass = loader.loadClass(distributedCacheClearClassName);
                this.distributedCacheClear = (DistributedCacheClear) dccClass.newInstance();
                this.distributedCacheClear.setDelegator(this, getDelegatorInfo().distributedCacheClearUserLoginId);
            } catch (ClassNotFoundException e) {
                Debug.logWarning(e, "DistributedCacheClear class with name " + distributedCacheClearClassName + " was not found, distributed cache clearing will be disabled", module);
            } catch (InstantiationException e) {
                Debug.logWarning(e, "DistributedCacheClear class with name " + distributedCacheClearClassName + " could not be instantiated, distributed cache clearing will be disabled", module);
            } catch (IllegalAccessException e) {
                Debug.logWarning(e, "DistributedCacheClear class with name " + distributedCacheClearClassName + " could not be accessed (illegal), distributed cache clearing will be disabled", module);
            } catch (ClassCastException e) {
                Debug.logWarning(e, "DistributedCacheClear class with name " + distributedCacheClearClassName + " does not implement the DistributedCacheClear interface, distributed cache clearing will be disabled", module);
            }
        }

    
        try {
   /*
      安装enitty eca处理器
   */
            Class eecahClass = loader.loadClass(ECA_HANDLER_CLASS_NAME);
            this.entityEcaHandler = (EntityEcaHandler) eecahClass.newInstance();
            this.entityEcaHandler.setDelegator(this);
        } catch (ClassNotFoundException e) {
            Debug.logWarning(e, "EntityEcaHandler class with name " + ECA_HANDLER_CLASS_NAME + " was not found, Entity ECA Rules will be disabled", module);
        } catch (InstantiationException e) {
            Debug.logWarning(e, "EntityEcaHandler class with name " + ECA_HANDLER_CLASS_NAME + " could not be instantiated, Entity ECA Rules will be disabled", module);
        } catch (IllegalAccessException e) {
            Debug.logWarning(e, "EntityEcaHandler class with name " + ECA_HANDLER_CLASS_NAME + " could not be accessed (illegal), Entity ECA Rules will be disabled", module);
        } catch (ClassCastException e) {
            Debug.logWarning(e, "EntityEcaHandler class with name " + ECA_HANDLER_CLASS_NAME + " does not implement the EntityEcaHandler interface, Entity ECA Rules will be disabled", module);
        }
    }

    /** Gets the name of the server configuration that corresponds to this delegator
     * @return server configuration name
     */
    public String getDelegatorName() {
        return this.delegatorName;
    }


 ModelReader.java

 public static ModelReader getModelReader(String delegatorName) throws GenericEntityException {
        /*
    EntityConfigUtil将读取component\entity\config\entityengine.xml文件
  */
  EntityConfigUtil.DelegatorInfo delegatorInfo = EntityConfigUtil.getDelegatorInfo(delegatorName);

        if (delegatorInfo == null) {
            throw new GenericEntityConfException("Could not find a delegator with the name " + delegatorName);
        }

        String tempModelName = delegatorInfo.entityModelReader;
        ModelReader reader = (ModelReader) readers.get(tempModelName);

        if (reader == null) { // don't want to block here
            synchronized (ModelReader.class) {
                // must check if null again as one of the blocked threads can still enter
                reader = (ModelReader) readers.get(tempModelName);
                if (reader == null) {
     /*
        1:读取entityengine.xml定义的model文件
        2:读取ofbiz-component.xml取到的model文件
     */
                    reader = new ModelReader(tempModelName);
                    // preload caches...
     /*
       1:加载所有的entity
       每个entity对应一个ModelEntity对象
       2:系统默认,每个entity将自动加上:lastUpdatedStamp,lastUpdatedTxStamp
         ,createdStamp,createdStamp,
      这些是不需要在entitymodel.xml中定义的
                      3:ofbiz3中entitymodel.xml中每个node将会对应一个对象.
         比如:
      <field name="budgetId" type="id-ne"></field>
      对应ModelField对象
          <relation type="many" rel-entity-name="BudgetRevision">
           对应 ModelRelation 对象
            <index name="GLACCT_UNQCD" unique="true">
                     <index-field name="accountCode"/>
             </index>
           对应 ModelIndex 对象
      等等
     */
                    reader.getEntityCache();
                    readers.put(tempModelName, reader);
                }
            }
        }
        return reader;
    }

本文地址:http://com.8s8s.com/it/it11208.htm