ContainerLoader类实现StartupLoader接口,目的是装入各种Container容器。

/**
* An OFBiz container. A container can be thought of as a background process.
*
* <p>
* When OFBiz starts, the main thread will create the <code>Container</code> instance and
* then call the container's <code>init</code> method. If the method returns without
* throwing an exception the container will be added to a list of initialized containers.
* After all instances have been created and initialized, the main thread will call the
* <code>start</code> method of each container in the list. When OFBiz shuts down, a
* separate shutdown thread will call the <code>stop</code> method of each container.
* Implementations should anticipate asynchronous calls to the methods by different
* threads.
* </p>
*
* <p>Containers might be loaded more than once (have more than one instance).<p>
*/
public interface Container { /** Initialize the container. This method must not block - implementations
* should initialize internal structures and then return.
*
* @param args Command-line arguments.
* @param name Unique name of the container's instance.
* @param configFile Location of the configuration file used to load this container.
* @throws ContainerException If an error was encountered. Throwing this exception
* will halt container loading, so it should be thrown only when other containers
* might depend on this one.
*/
public void init(String[] args, String name, String configFile) throws ContainerException; /**
* Start the container process. This method must not block - implementations
* that require thread blocking must create a separate thread and then return.
*
* @return <code>true</code> if the process started.
* @throws ContainerException If an error was encountered.
*/
public boolean start() throws ContainerException; /**
* Stop the container process. This method must not block.
*
* @throws ContainerException If an error was encountered.
*/
public void stop() throws ContainerException; /**
* Return the container name.
*
* @return Name of the container's instance.
*/
public String getName();
}

ContainerLoader会以三种方式寻找Container。第一种方式从配置文件中找,默认的配置文件是framework/base/config/ofbiz-containers.xml。第二种方式找组件Component总定义的容器。第三种方式找hot-deploy容器,这也是一个配置文件hot-deploy-containers.xml。

ofbiz-containers.xml定义了整个OFBIZ最重要的ComponentContainer容器,该容器载入所有的Component。

<ofbiz-containers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-containers.xsd"> <!-- load the ofbiz component container (always first) -->
<container name="component-container" loaders="main,rmi,pos,install" class="org.ofbiz.base.container.ComponentContainer"/> <container name="component-container-test" loaders="test" class="org.ofbiz.base.container.ComponentContainer">
<property name="ofbiz.instrumenterClassName" value="org.ofbiz.base.config.CoberturaInstrumenter"/>
<property name="ofbiz.instrumenterFile" value="runtime/logs/cobertura-components.dat"/>
</container> <container name="component-container-limited" loaders="limited" class="org.ofbiz.base.container.ComponentContainer">
<property name="update-classpath" value="false"/>
</container> <container name="component-container" loaders="testlist" class="org.ofbiz.base.container.JustLoadComponentsContainer"/> </ofbiz-containers>

ContainerLoader首先载入ofbiz-containers.xml中的容器:

this.loadedContainers.clear();

// get this loader's configuration file
// default: framework/base/config/ofbiz-containers.xml
this.configFile = config.containerConfig; Collection<ContainerConfig.Container> containers = null;
try {
containers = ContainerConfig.getContainers(configFile);
} catch (ContainerException e) {
throw new StartupException(e);
} for (ContainerConfig.Container containerCfg : containers) {
if (this.unloading) {
return;
}
boolean matchingLoaderFound = false;
if (UtilValidate.isEmpty(containerCfg.loaders) && UtilValidate.isEmpty(loaders)) {
matchingLoaderFound = true;
} else {
for (String loader: loaders) {
if (UtilValidate.isEmpty(containerCfg.loaders) || containerCfg.loaders.contains(loader)) {
matchingLoaderFound = true;
break;
}
}
}
if (matchingLoaderFound) {
Debug.logInfo("Loading container: " + containerCfg.name, module);
Container tmpContainer = loadContainer(containerCfg, args);
this.loadedContainers.add(tmpContainer);
Debug.logInfo("Loaded container: " + containerCfg.name, module);
}
} private Container loadContainer(ContainerConfig.Container containerCfg, String[] args) throws StartupException {
// load the container class
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if (loader == null) {
Debug.logWarning("Unable to get context classloader; using system", module);
loader = ClassLoader.getSystemClassLoader();
}
Class<?> containerClass = null;
try {
containerClass = loader.loadClass(containerCfg.className);
} catch (ClassNotFoundException e) {
throw new StartupException("Cannot locate container class", e);
}
if (containerClass == null) {
throw new StartupException("Component container class not loaded");
} // create a new instance of the container object
Container containerObj = null;
try {
containerObj = (Container) containerClass.newInstance();
} catch (InstantiationException e) {
throw new StartupException("Cannot create " + containerCfg.name, e);
} catch (IllegalAccessException e) {
throw new StartupException("Cannot create " + containerCfg.name, e);
} catch (ClassCastException e) {
throw new StartupException("Cannot create " + containerCfg.name, e);
} if (containerObj == null) {
throw new StartupException("Unable to create instance of component container");
} // initialize the container object
try {
containerObj.init(args, containerCfg.name, configFile);
} catch (ContainerException e) {
throw new StartupException("Cannot init() " + containerCfg.name, e);
} catch (java.lang.AbstractMethodError e) {
throw new StartupException("Cannot init() " + containerCfg.name, e);
} return containerObj;
}

然后载入Component中定义的容器:

List<ContainerConfig.Container> containersDefinedInComponents = ComponentConfig.getAllContainers();
for (ContainerConfig.Container containerCfg: containersDefinedInComponents) {
boolean matchingLoaderFound = false;
if (UtilValidate.isEmpty(containerCfg.loaders) && UtilValidate.isEmpty(loaders)) {
matchingLoaderFound = true;
} else {
for (String loader: loaders) {
if (UtilValidate.isEmpty(containerCfg.loaders) || containerCfg.loaders.contains(loader)) {
matchingLoaderFound = true;
break;
}
}
}
if (matchingLoaderFound) {
Debug.logInfo("Loading component's container: " + containerCfg.name, module);
Container tmpContainer = loadContainer(containerCfg, args);
this.loadedContainers.add(tmpContainer);
Debug.logInfo("Loaded component's container: " + containerCfg.name, module);
}
}

第三步载入hot-deploy容器:

ClassLoader loader = Thread.currentThread().getContextClassLoader();
Enumeration<URL> resources;
try {
resources = loader.getResources("hot-deploy-containers.xml");
while (resources.hasMoreElements() && !this.unloading) {
URL xmlUrl = resources.nextElement();
Debug.logInfo("Loading hot-deploy containers from " + xmlUrl, module);
Collection<ContainerConfig.Container> hotDeployContainers = ContainerConfig.getContainers(xmlUrl);
for (ContainerConfig.Container containerCfg : hotDeployContainers) {
if (this.unloading) {
return;
}
Container tmpContainer = loadContainer(containerCfg, args);
this.loadedContainers.add(tmpContainer);
}
}
} catch (Exception e) {
Debug.logError(e, "Could not load hot-deploy-containers.xml", module);
throw new StartupException(e);
}

最后ContainerLoader启动时,执行所有Container的start()方法。

public synchronized void start() throws StartupException {
if (!this.loaded || this.unloading) {
throw new IllegalStateException("start() called on unloaded containers");
}
Debug.logInfo("[Startup] Starting containers...", module);
// start each container object
for (Container container: this.loadedContainers) {
if (this.unloading) {
return;
}
Debug.logInfo("Starting container " + container.getName(), module);
try {
container.start();
} catch (ContainerException e) {
throw new StartupException("Cannot start() " + container.getClass().getName(), e);
} catch (java.lang.AbstractMethodError e) {
throw new StartupException("Cannot start() " + container.getClass().getName(), e);
}
Debug.logInfo("Started container " + container.getName(), module);
}
}

OFBIZ:启动之ContainerLoader的更多相关文章

  1. OFBIZ:启动之StartupLoader

    任意一个JAVA程序都是从main()开始启动的,OFBIZ也不例外.OFBIZ的main()位于framework/start/src/org/ofbiz/base/start/Start.java ...

  2. OFBIZ+ECLIPSE

    1. 首先要安装好OFBIZ,参考<OFBIZ安装>. 2. 安装ECLIPSE. 3. 安装FreeMarker插件,这是OFBIZ的模版引擎.在"Eclipse Market ...

  3. [OFBiz]开发 三

    1. Debug不要在Eclipse中使用Ant来启动ofbiz, 因为在Eclipse中无法kill掉Ant的进程,而ofbiz又没有提供stop的方法.(有一个hook shutdown的方法,但 ...

  4. OFBiz:配置过程

    OFBiz使用了大量的配置文件,整个过程有点复杂.这里将配置过程大略整理了一下,方便后面查阅. 第一层:org.ofbiz.base.start.Start启动类.该类载入org/ofbiz/base ...

  5. 【转】Ofbiz学习经验谈

    不可否认,OFBiz这个开源的系统功能是非常强大的,涉及到的东西太多了,其实对我们现在而言,最有用的只有这么几个:实体引擎.服务引擎.WebTools.用户权限管理.最先要提醒各位的是,在配置一个OF ...

  6. ofbiz安装优化

    一. 1.安装jdk 2.安装数据库 3.安装ant yum install ant 4.编译启动ofbiz cd /ofbiz目录下 ant run-install ./startofbiz.sh ...

  7. OFBiz:添加实体栏位

    如何添加实体栏位?这里演示为PostalAddress添加planet栏位.打开applications/party/entitydef/entitymodel.xml,找到PostalAddress ...

  8. gradle ofbiz 16 开发环境搭建

    原 gradle ofbiz 16 开发环境搭建 2017年02月13日 10:59:19 阅读数:2702 1.安装jdk 2.配置jdk环境变量 3.eclipse 安装svn 插件 4.svn下 ...

  9. ApacheOFBiz的相关介绍以及使用总结(一)

    由于最近一段时间在给一个创业的公司做客户关系管理CRM系统,限于人力要求(其实是没有多少人力),只能看能否有稳定,开源的半成品进行改造,而且最好不需要前端(js)相关开发人员的支援就可以把事情做成,经 ...

随机推荐

  1. iOS开发UI篇—Quartz2D使用(信纸条纹)

    iOS开发UI篇—Quartz2D使用(信纸条纹) 一.前导程序 新建一个项目,在主控制器文件中实现以下几行代码,就能轻松的完成图片在视图中的平铺. #import "YYViewContr ...

  2. SSL/TLS 高强度加密: 常见问题解答

    关于这个模块 mod_ssl 简史 mod_ssl会受到Wassenaar Arrangement(瓦森纳协议)的影响吗? mod_ssl 简史 mod_ssl v1 最早在1998年4月由Ralf ...

  3. Python的平凡之路(3)

     一.函数基本语法及特性 面向对象:(华山派)—类 —class 面向过程:(少林派)—过程 —df 函数式编程:逍遥派    —函数— df 一般的,在一个变化过程中,如果有两个变量x和y,并且对于 ...

  4. 数据交互 ajax 初始化省

    1 //初始化省 2 function initProvince() { 3 if( areaLvel == 0 ) { 4 return; 5 } 6 // 清空option 7 $("# ...

  5. 网页版电子表格控件tmlxSpreadsheet免费下载地址

    tmlxSpreadsheet 是一个由JavaScript 和 PHP 写成的电子表格控件(包含WP插件, Joomla插件等等).. 程序员可以容易的添加一个类似Excel功能的,可编辑的表格功能 ...

  6. windows核心编程---第四章 进程

    上一章介绍了内核对象,这一节开始就要不断接触各种内核对象了.首先要给大家介绍的是进程内核对象.进程大家都不陌生,它是资源和分配的基本单位,而进程内核对象就是与进程相关联的一个数据结构.操作系统内核通过 ...

  7. 《JavaScript模式》第3章 字面量和构造函数

    @by Ruth92(转载请注明出处) 第3章:字面量和构造函数 一.创建对象的三种方式 // 对象字面量 var car = {goes: "far"}; // 内置构造函数(反 ...

  8. 类似title的鼠标跟随事件

    $(document).ready(function(){ // 创建一个div显示提示信息 var dropTitle = document.createElement("div" ...

  9. PHP、JAVA、C#、Object-C 通用的DES加密

    PHP.JAVA.C#.Object-C 通用的DES加密 PHP: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ...

  10. C#访问非托管内存

    示例1:分配一个新的内存地址给新变量 Point p; // Initialize unmanged memory to hold the struct. IntPtr pnt = Marshal.A ...