统一对象消息编程(7)—对象消息编程框架应用1(程序架构)

     现在我们将消息对象框架进行具体应用。前面讲过对于消息编程框架,首先启动模块工厂,由工厂来创建、启动其他模块。实际应用中,我把第一个启动的模块称为appCenter作为主模块,这完全是个人喜好。启动一个固定模块有以下两个原因:

 1、可以通过这个模块做程序的初始化。

 2、这个模块可以作为一个程序信息调度中心。可以转发其他模块的信息。

当然我们可以通过工厂启动任何模块。

     在实际应用中,不同的环境有不同的环境变量,主要是针对配置文件的路径设置。比如我发现android环境、普通java环境、web环境的配置路径都不同。因此实际中,根据环境情况不同定义不同的模块工厂,目的主要还是适应不同的环境。定义的模块工厂继承系统的模块工厂。我没有认真研究对于java是否也许可定义一种适应所有环境的工厂。下面看我写的一个应用包:

cn.tianlong.java包下是具体应用、应用案例。其中servletutils 是web框架 ,servletdemo是针对web框架的demo。tlobjdemo是普通java平台应用,里面的base是根据环境自定义的工厂、模块模板,原因上面讲过。在base包下,我们定义了工厂模块、配置文件模块、通用模块和一个主模块APPcenter。所有模块都是对基本包里模块的继承。如MyModule如下:

public abstract class MyModule extends TLBaseModule {

   public MyModule(String name) {
      super(name);   
   }
   public MyModule (String name,TLObjectFactory moduleFactory)  {
      super(name,moduleFactory);
   }
   @Override
   protected void init() {

   }
   public MyModule() {
      super();
   
   }
   protected Object setConfig(){
      String configdir =Myfactory.getConfigDir();
      if(configFile ==null)
          configFile=configdir+name+"_config.xml";
      super.setConfig();
      return mconfig;
   }
}

    可以看到MyModule就是对标准对象模板的一个简单继承。主要目的是设置配置文件,因为在标准对象模板TLBaseModule中并没有指定文件命名规范。这里定义配置文件名为:模块名_config.xml。其他应用模块继承MyModule后,则自动定义配置文件。

  Myfactory也是对标准工厂的一个继承,源码如下:

public class Myfactory extends TLObjectFactory {
   protected static String configDir;
    private static Myfactory instance;
   protected String packageName;
   protected ArrayList<TLMsg> factoryBoot ;


   private Myfactory(String name) {
      super(name);
   }
   @Override
   protected Object setConfig() {
      if(configFile==null)
         configFile = configDir +"appConfig.xml";
      MyAppConfig appConfig = new MyAppConfig(configFile);
      appConfig.init(configFile);
      modules.put("appConfig", appConfig);
      packageName= (String) appConfig.getParams().get("package");
      modulesClass = (HashMap) appConfig.getModules();
      factoryBoot=appConfig .getFactoryBoot();
      doModuleClass();
      return null;

   }
   protected void doModuleClass(){
      for (String key : modulesClass.keySet()) {
         HashMap<String,String> modules=modulesClass.get(key);
         for (String key1 : modules.keySet()) {
            if(key1.equals("classfile")){
               String classfile=addPackage(modules.get(key1));
               modules.put(key1,classfile);
            }
            else {
               if(key1.equals("configfile")){
                  String configfile =configDir+File.separator+modules.get(key1);
                  modules.put(key1,configfile);
               }
            }
         }
      }
   }
   protected String addPackage(String name) {
      if(name==null)
         return null;
      String firstCha = (String) name.subSequence(0, 1);
      if (firstCha.equals(".")) {
         return packageName + name;
      } else
         return name;
   }
    public static Myfactory getInstance(String configDir ,String configFile) {
       Myfactory.configDir =configDir;
       if (instance == null){
          instance = new Myfactory(MODULEFACTORY);
          if(configFile!=null)
              configFile=configDir +configFile;

          instance.start(configFile,null);
       }
           return instance;
       }
   public void boot()  {
      doMsgList(factoryBoot,null,null);
   }
   public static Myfactory getInstance() {
      return instance;
   }
   public static String getConfigDir(){
      return configDir;
   }

定义的工厂目的是为了根据当前环境而进行相关设置,读取配置。对于模块工厂除了标准的模块属性以外,还自定义了一个属性factoryBoot ,主要放置工厂建立时启动的模块。最开始设计标准工厂模块时,工厂的责任主要是创建模块,它没有初始启动其他模块的责任,在后来涉及多线程的时候,我发现有些组件必须在主线程中启动。当我们用putMsg(模块名,msg)发生消息的时候,如果模块没有启动,则从工厂创建,如果在子线程中创建,对于某些模块将发生错误,如ehcache,数据库连接池。通过factoryBoot启动的模块将在主线程中。

模块工厂定义了程序的主配置文件appConfig.xml。这个配置文件也是主模块APPcenter的配置文件。为了方便 和简化,将模块工厂中的一些配置也放到主配置文件里面。下面来看配置文件:

<?xml version="1.0" encoding="UTF-8" ?>
<appConfig>
    <params>
        <verison value="1"/>
        <package value="cn.tianlong.java.tlobjdemo"/>
        <poolNumber value="100"/>
    </params>
 
    <modules>
        <!-- 系统模块 -->
        <module name="appCenter" classfile=".person.MyAppCenter" configfile="appConfig.xml"/>
        <module name="mconfig" classfile="cn.tianlong.tlobjcet.base.TLModuleConfig" singleton="true"  />
        <module name="log" classfile="cn.tianlong.tlobjcet.base.TLLog"
                configfile="log_config.xml"/>
        <module name="monitorConfig" classfile="cn.tianlong.tlobjcet.base.TLMonitorConfigModule"
                configfile="monitorConfig_config.xml"/>
        <module name="broadcast" classfile="cn.tianlong.tlobjcet.base.TLMsgBroadCast" />
        <module name="msgMap"  classfile="cn.tianlong.java.servletutils.TLWClientMsgMap" />
        <module name="serviceMsgMap" classfile="cn.tianlong.tlobjcet.network.http.server.TLWebServiceMsgMap"
                configfile="msgMap_config.xml"/>
        <module name="msgbus" classfile="cn.tianlong.tlobjcet.base.TLMsgBus" />
        <module name="webServerClient" classfile="cn.tianlong.tlobjcet.network.http.client.TLWebServerClient" />
        <module name="HSServer" classfile="cn.tianlong.tlobjcet.network.http.server.HttpServiceServer"
                port="8081"/>
        <module name="httpClient" classfile="cn.tianlong.tlobjcet.network.http.client.HttpJsonClient"
                       port="8081" hostname="127.0.0.1"/>
        <module name="webSeviceClient" classfile="cn.tianlong.tlobjcet.network.http.client.TLWebSeviceClient"/>
        <module name="database" classfile="cn.tianlong.tlobjcet.db.TLDataBase"
                ip="127.0.0.1" configfile="database_config.xml"/>
        <module name="dbserver" classfile="cn.tianlong.tlobjcet.db.TLDBServer" />
        <module name="dbtable" classfile="cn.tianlong.tlobjcet.db.TLTable" />
        <module name="dbview" classfile="cn.tianlong.tlobjcet.db.TLDBView" />
        <module name="fileCache" classfile="cn.tianlong.tlobjcet.cache.TLFileCache" />
        <module name="EhCache"  classfile="cn.tianlong.tlobjcet.cache.TLEhcache" />
        <module name="cachetrigger" classfile="cn.tianlong.tlobjcet.db.TLDBTriggerForCache" />
        <module name="aftercachetrigger" proxyModule="cachetrigger" />
        <module name="c3p0Conn" classfile="cn.tianlong.tlobjcet.db.TLC3P0connect" singleton="false" />
        <module name="cache" proxyModule="EhCache" inSession="false" configfile="filecache_config.xml"/>
        <module name="sessionData"  classfile="cn.tianlong.tlobjcet.base.TLSessionData" />
        <!-- 用户自定义模块 -->
        <module name="house" classfile=".person.House"  singleton="true" />
        <module name="light" classfile=".person.Light" singleton="ture"/>
        <module name="xiaoming" classfile=".person.Person" />
        <module name="wife" classfile=".person.Person" />
        <module name="userTableSplitTrigger" classfile=".dbdemo.UserTableSplitTrigger" />
        <module name="userAfterTrigger" classfile=".dbdemo.userAfterTrigger" />
        <module name="serv1C3p0" classfile="cn.tianlong.tlobjcet.db.TLC3P0connect" />
        <module name="serv2C3p0" classfile="cn.tianlong.tlobjcet.db.TLC3P0connect" />
        <module name="myservice" proxyModule="webSeviceClient"  serverAddress1 ="http://localhost:8080/tltest/tlobject/service"/>
        <module name="userModle" classfile=".dbdemo.userModle" />
        <module name="dbserver1" inSession="true" proxyModule="dbserver" configfile="database_config.xml"/>
        <module name="dbserver2" inSession="true" proxyModule="dbserver" configfile="database_config.xml"/>
        <module name="myTaskManger" classfile=".task.MyTaskManger"  configfile="msgtask_config.xml" />
        <module name="dbtask1" classfile=".task.dbtask1"  />
        <module name="dbtask2" classfile=".task.dbtask1"   />
        <module name="serviceModle" classfile=".http.serviceModle"   />
        <module name="userModle" classfile="cn.tianlong.java.servletdemo.userModle" />
        <module name="servletDbTest"  classfile="cn.tianlong.java.servletdemo.servletDbTest" />
        <module name="myServiceAuth" classfile=".http.myServiceAuth"   />

    </modules>
    <msgTable>
        <msgid  value="setup" >
            <msg action="getModule" destination="moduleFactory" moduleName="wife"/>
            <msg action="getModule" destination="moduleFactory" moduleName="xiaoming"/>
        </msgid>
    </msgTable>
    <initMsg>
        <msg msgid="setup" />
    </initMsg>
    <factoryBoot>
        <factoryBoot>
            <msg action="getModule"  moduleName="log" usePreReturnMsg="false" />
            <msg action="getModule"  moduleName="cache" usePreReturnMsg="false" />
            <msg action="getModule"  moduleName="dbserver1" usePreReturnMsg="false" />
            <msg action="getModule"  moduleName="dbserver2" usePreReturnMsg="false" />

        </factoryBoot>
    </factoryBoot>
</appConfig>

这个配置文件与前面介绍的标准模块配置文件基本是一样的,因为APPcenter模块也是标准的消息模块。唯一有个不同是,将模块工厂的配置也加到里面了,仅仅是为了方便。否则单要给模块工厂另建一个文件,当然也是可以的。

配置文件里面的<modules>、 <factoryBoot>两个目录是用于工厂配置,其他项目用于APPcenter模块配置。 <factoryBoot>是可选项,对于不需要工厂初始启动的模块,可以不用。

<modules>是必须有的,所有通过工厂创建的模块都要在此添加。<modules>里的子项很容易理解,模块名字,模块对应的类,模块的配置文件,如果不指定文件则默认是 Myfactory模块中定义的配置文件。模块名字,模块对应的类是必须的,其他为可选的,对于不需要单独配置文件的模块,可将少数参数配置这里。如模块httpClient定义了端口和地址。在 <params>目录下,定义了一个package项,指定当前的包,对当前包下的类,类可用,开始,否则类必须是全名。 当前配置的包为"cn.tianlong.java.tlobjdemo",则模块<module name="userModle" classfile=".dbdemo.userModle" /> 就是当前包下的。

配置文件里面的模块根据自己的需要而定,这个配置文件其他案例也用,因此模块比较烦杂。

singleton 为模块单例设置。默认下模块为单例模式,如果不是单例,既工厂每次创建新模块,则设置singleton=false

usePreReturnMsg用于消息链结果是否采纳。对了消息链处理,后面的消息是否采用前面消息的返回结果,usePreReturnMsg=false 表明不采纳上个消息的结果,否则上个消息的结果将成为下个消息处理的一个参数。

同一个类可以创建不同的模块,如

<module name="serv1C3p0" classfile="cn.tianlong.tlobjcet.db.TLC3P0connect" />

<module name="serv2C3p0" classfile="cn.tianlong.tlobjcet.db.TLC3P0connect" />

也可以用模块代理的方式实现同一类创建不同的模块,如

<module name="dbserver1" inSession="true" proxyModule="dbserver" configfile="database_config.xml"/>

<module name="dbserver2" inSession="true" proxyModule="dbserver" configfile="database_config.xml"/>

dbserver1 、dbserver2  代理dbserver模块。创建dbserver1时,用 dbserver 的 类参数。

以上是普通应用环境的框架简单介绍,我们发现框架很简单,主要是因为我们的许多工作已经在标准模板类中做了。下章介绍根据这个环境开发的案例。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值