ConfigEngine使用示例

本文介绍ConfigEngine配置管理工具的使用方法。通过简单的步骤,您可以轻松地定义、编译配置文件并将其集成到应用程序中。支持多种数据类型,方便配置项的读取与修改。

ConfigEngine使用示例

  • 前提:本系统基于公开的原则,采用了Python作为开发语言。因此你需要下载安装Python环境才能运行本系统。

    当然,你还需要下载一份最新的ConfEngine配置编译引擎。地址在这里:

    http://code.google.com/p/confengine/downloads/list

    简要过程如下:

    • 步骤1: 下载安装Python运行环境
    • 步骤2: 下载ConfEngine最新版本。解开到一个目录中。
    • 步骤3: 编写你的配置定义文件 raw.f。
    • 步骤4: 调用ConfEngine里的genconf.py编译raw.f,生成raw.h.
    • 步骤5: include "raw.h"。 使用AppRaw().来访问你的配置相关的功能。

    第一步,定义需要的配置项,保存在raw.f

    • 注意这里文件名取为raw.f, 其中的raw会被当作名称的一部分。因此如果你想定义多个独立的配置系统的话,需要精确的选择这个名字。而.f的扩展名,是本系统的建议扩展名,你硬要换也没关系。

      raw.f 文件按的类容如下:

      • ; System配置范围
        s 	system:account:agnet		firefox		dd
        s 	system:account:username		"zhang san"	default user name
        b 	system:account:remember		0.0		  	remember last logon user?
        n	system:account:retry		3756		fail count allowed before exit.
        n	system:registered		0		is this copy copyleft?
        
        ; 顶级配置项
        b	lastupdate			12345678	last date for update.
            

      raw.f文件的解释如下:

      • 文件的每一行为一个配置项。
      • 空行只是为了添加可读性,实际处理被略过。
      • 以分号开始的行为注释行,实际处理也被略过。
      • 配置项的每一行,分为3~4个列,每一列用空白(空格或者Tab)分开。
        • 第一列为单个字符,表明数据类型,如s表示字符串;b表示布尔值;n表示数值。

          第二列为可分层次的配置项。每一层之间用:区分(早期曾用'/'区分,但是在某些环境下引起歧义,新版本改为用':')。

          • 分层可以理解为按名字空间组织。
          • 层间用':'分割,最后一项为实际配置项
          • 也可以不使用分层,直接使用配置项。
          • 注意不要混合层名字和配置项名字。
            • 如:如果定义了system:account:username
            • 配置项为username, 他的层次为system.account。
            • 这个时候你仍可以定义其他的层次,和其他层次的配置项,如 system:agent:proxy;或者system:lastupdate。
            • 但是不能再定义 system:account了。因为account已经是system的子层次,不能再是配置项了。

          第三列为默认值。注意列是由空白分开的,所以如果默认值中包含空格的话(字符串类型),就需要用双引号包含起来。类似长路径名的处理。

          第四列是可选的,表示注释项。注意这是最后一项,因此不再考虑空白区分,所有第三列以后的剩余内容,都认为是第四列的。

      • 目前只支持s, b, n三种类型,大概可以涵盖绝大部分的用途了。

    第二步,调用ConfEngine编译raw.f。  如:E:/confengine/genconf.py   E:/dev/marvel/raw.f

    • genconf.py 编译raw.f后,如果raw.f没有语法错误,会生成raw.h(注意名称一致)。同时如果需要的话,会拷贝一份公用类定义文件baseconf.h到raw.h的目录。

       

      可以手工运行,可以看看他的命令行输出的信息。 了解这个过程后,就可以直接把raw.f文件和genconf.py关联起来,没必要每次手工运行了。

       

      这里有三个文件:

      raw.f

      raw.h

      baseconf.h。

       

      raw.f是你的定义文件,应该加入到你的工程里面。如果有版本管理系统的话,也应该加入到版本管理系统里面。

      raw.h 和 baseconf.h 是编译raw.f产生的文件,就像编译 .cpp产生的.obj文件一样,是没必要加入到工程和版本管理里面的。

       

       

      • 有时候.h不加入到工程里面,他里面的代码自动完成提示就不完全。这个时候可以将raw.h和baseconf.h加入到工程里。

         

        加raw.h或者baseconf.h或者同时加入到工程,视你的习惯而定。他们仅仅起自动完成提示的作用,除此外,是完全不必加入到工程里面的。

         

        加入到代码管理则是完全不必要的,因为他的内容完全决定于raw.f。

      生成的baseconf.h是公用类容,不必理会。生成的raw.h是你要的内容, 最好include到你的全局头文件定义里。 如stdafx.h 或者 YourApp.h 等里面。

      建议:

          将raw.f 加入你的工程,然后设定自定义编译选项,这样子每次修改raw.f,编译时就能自动即时的反应更改了。 设定自定义编译选项,VC6的操作如下:在Project的FileView中,选择raw.f, 右键点击弹出上下文菜单,选择settings;在打开的project settings里,选择 custom build 选项页。 在commands里面,输入编译命令, 如 genconf.py $(InputName), outputs里面,填入生成的文件,这里是raw.h。确定即可。

       

          这里genconf.py假定在可以找到的目录下,否则要加上全路径。

      raw.h里面会定义一个 AppRaw();的函数(),其中App是固定前缀,Raw来自于定义文件。 这个函数会返回一个CRaw& 类引用。 类的名称一看就知道,而类的类容则包含了配置项的所有内容。

    第三步,享受你轻便简洁的配置访问功能。

    • 示例如下:
      • 当然,先要包含头文件。  #include "raw.h"

        在程序初始化时,载入全局配置项。代码为

         

        AppRaw().LoadGlobal();

        你可以选择是否继续载入其他的用户或者OEM自定义项,如:

         

        AppRaw().LoadUserProfile("lenovo.conf");

        AppRaw().LoadUserProfile("Optimization.conf");

        可以直接或间接的访问配置项:

         

          int i = AppRaw().system.account.retry;

         

          if (3 < AppRaw().system.account.retry) ...;

        • 注意到没有,代码一目了然的逻辑层次,体现了层次分明的配置项的强大优势。
        • 而且,你无需记住配置的详细内容,由于有层次,只需要打一个点,自动完成就会列出接下来的所有项。

        不止是读取这么简单,你还可以修改它:

         

        AppRaw().system.account.retry = 33;

        或者在弹出系统选项设置对话框时,你还可以提供一个复位(恢复默认值)的按钮,同样很简单。只需要调用配置项的reset即可:

         

        AppRaw().system.account.retry.Reset();

        或者你不想挨个复位每个配置项,你可以一次复位一个层次的所有配置项,如:

         

        AppRaw().system.account.Reset();

        或者调用顶层的reset,复位所有的配置项:

         

        AppRaw().Reset();

         

        在修改了你的配置,或者复位了一些项之后,你需要将配置保存到配置文件中。

        你可以调用:

         

        AppRaw().WriteGlobalProfile();

         

        保存一份全局配置文件。 也可以仅仅是保存用户修改部分,作为用户配置文件,如:

         

        AppRaw().WriteUserProfile("Optimization.conf");

         

         

        • 全局配置文件和用户配置文件的区别
          • 1. 全局配置文件只有一个;用户配置文件数目不限。

            3. 全局配置文件保存了所有的配置项,不管是否是默认值;用户配置文件仅保存不是默认值的配置项。

            4. 由于用户配置文件需要指定名字,因此需要特别注意读取和保存的文件名的一致。

            2. 全局配置文件名字固定为exe的名字,仅扩展名变为.conf,因此无需指定;用户配置文件需要指定名字,但是需要注意到不要跟exe名字相同,因为全局配置文件已经占用了这个名字。

        • 用户配置文件可以不带路径,默认是在.exe所在目录下。但是带完整路径也是可以的。

    后记,看看最终用户看到配置文件是什么样子的:

    • 注:下面的配置文件并不是来源于raw.f。而是来自于一个真实的项目的一小部分,这些内容全是由配置引擎完成的,程序员完全无需关注。可以看到他完备的注释让最终用户也一目了然。

       

      # 主窗口位置左, Default value: 0

      MainWnd:Area:l=363

       

      # 主窗口位置上, Default value: 0

      MainWnd:Area:t=140

       

      # 主窗口位置又, Default value: 800

      MainWnd:Area:r=1386

       

      # 主窗口位置下, Default value: 600

      MainWnd:Area:b=967

       

      # 浮动窗口方式 0: 自动隐藏,漂浮在鼠标位置; 1: 固定位置显示; 2: 停靠在主窗口右侧; 3: 停靠在主窗口下侧; 4: 停靠在主窗口上侧, Default value: 1

      FloatWnd:Dock=1

       

      # 浮动窗口自动隐藏模式位置宽, Default value: 700

      FloatWnd:ModeAuto:cx=700

       

      # 浮动窗口自动隐藏模式位置高, Default value: 300

      FloatWnd:ModeAuto:cy=300

       

      # 浮动窗口固定模式位置左, Default value: 700

      FloatWnd:ModeFix:l=700

       

      # 浮动窗口固定模式位置上, Default value: 300

      FloatWnd:ModeFix:t=300

       

      # 浮动窗口固定模式位置又, Default value: 1024

      FloatWnd:ModeFix:r=1024

       

      # 浮动窗口固定模式位置下, Default value: 500

      FloatWnd:ModeFix:b=500

       

      # 浮动窗口右侧停靠模式宽, Default value: 500

      FloatWnd:ModeRight:cx=500

       

      # 浮动窗口下侧停靠模式高, Default value: 500

      FloatWnd:ModeBottom:cy=500

       

      # 浮动窗口上侧停靠模式高, Default value: 700

      FloatWnd:ModeTop:cy=700

       

package com.sxjlrj.common.config; import com.alibaba.druid.filter.stat.StatFilter; import com.alibaba.druid.wall.WallFilter; import com.jfinal.config.*; import com.jfinal.core.JFinal; import com.jfinal.ext.interceptor.SessionInViewInterceptor; import com.jfinal.json.FastJsonFactory; import com.jfinal.kit.Prop; import com.jfinal.kit.PropKit; import com.jfinal.plugin.activerecord.CaseInsensitiveContainerFactory; import com.jfinal.plugin.activerecord.SqlReporter; import com.jfinal.plugin.druid.DruidPlugin; import com.jfinal.plugin.ehcache.EhCachePlugin; import com.jfinal.server.undertow.UndertowServer; import com.jfinal.template.Engine; import com.jfinal.template.source.ClassPathSourceFactory; import com.sxjlrj.common.directive.MyNowDirective; import com.sxjlrj.common.handler.CommonHandler; import com.sxjlrj.common.intercepor.ExceptionInterceptor; import com.sxjlrj.common.intercepor.LoggerInterceptor; import com.sxjlrj.common.intercepor.SessionInterceptor; import com.sxjlrj.common.kit.DruidKit; import com.sxjlrj.common.routes.AutoBindRoutes; import com.sxjlrj.common.tables.AutoTableBindPlugin; import com.sxjlrj.common.tables.DbManager; import com.sxjlrj.common.util.job.ScheduleUtils; import top.hequehua.swagger.config.SwaggerPlugin; import top.hequehua.swagger.handler.WebJarsHandler; import top.hequehua.swagger.model.SwaggerDoc; import top.hequehua.swagger.routes.MySwaggerRoutes; public class MainConfig extends JFinalConfig { /** * 运行main方法启动项目 */ public static void main(String[] args) { UndertowServer.create(MainConfig.class).configWeb(webBuilder -> { //解决xss & sql漏洞 webBuilder.addFilter("xssAndSqlFilter","com.sxjlrj.common.filter.XssAndSqlFilter"); webBuilder.addFilterUrlMapping("xssAndSqlFilter","*"); }).start(); } // 使用 jfinal-undertow 时此处仅保留声明,不能有加载代码 private static Prop p; // 先加载开发环境配置,再追加生产环境的少量配置覆盖掉开发环境配置 static void loadConfig() { if (p == null) { p = PropKit.use("config-dev.txt").appendIfExists("config-pro.txt"); } } /** * 配置JFinal常量 */ @Override public void configConstant(Constants me) { // 读取数据库配置文件 loadConfig(); // 设置当前是否为开发模式 me.setDevMode(p.getBoolean("devMode")); // 设置默认上传文件保存路径 getFile等使用 me.setBaseUploadPath(p.get("baseUploadPath")); // 设置默认下载文件路径 renderFile使用 me.setBaseDownloadPath(p.get("baseDownloadPath")); // 设置error渲染视图 me.setError403View(WebContant.error403View); me.setError404View(WebContant.error404View); me.setError500View(WebContant.error500View); //Json配置 me.setJsonFactory(FastJsonFactory.me()); //开启依赖注入 me.setInjectDependency(true); } /** * 配置JFinal路由映射 */ @Override public void configRoute(Routes me) { //配置Swagger接口文档插件 me.add(new MySwaggerRoutes()); // 配置ControllerBind注解路由 AutoBindRoutes autoBindRoutes = new AutoBindRoutes(); autoBindRoutes.includeAllJarsInLib(!p.getBoolean("devMode")); autoBindRoutes.setBaseViewPath(WebContant.baseViewPath); me.add(autoBindRoutes); } /** * 配置JFinal插件 数据库连接池 ORM 缓存等插件 自定义插件 */ @Override public void configPlugin(Plugins me) { // 配置数据库连接池插件 DruidPlugin dbPlugin = new DruidPlugin(p.get("jdbcUrl"), p.get("user"), p.get("password").trim()); /** 配置druid监控 **/ dbPlugin.addFilter(new StatFilter()); WallFilter wall = new WallFilter(); wall.setDbType(p.get("dbType")); dbPlugin.addFilter(wall); // 添加自动绑定model与表插件 AutoTableBindPlugin arp = new AutoTableBindPlugin(dbPlugin); //sql模板 arp.getEngine().setSourceFactory(new ClassPathSourceFactory()); arp.addSqlTemplate(WebContant.sqlTemplate); // sql输出到日志 SqlReporter.setLog(!p.getBoolean("devMode")); arp.setShowSql(p.getBoolean("devMode")); //设置方言 DbManager.configDialect(arp,p.get("dbType")); // 配置属性名(字段名)大小写,true:小写,false:大写,统一小写,切换oracle数据库的时候可以不用改页面字段 arp.setContainerFactory(new CaseInsensitiveContainerFactory(true)); dbPlugin.setDriverClass(p.get("driverClass")); // 添加到插件列表中 me.add(dbPlugin); me.add(arp); // 配置缓存插件 me.add(new EhCachePlugin()); // 配置Swagger接口文档 me.add(new SwaggerPlugin(p.getBoolean("ENABLE_SWAGGER")).addSwaggerDoc(new SwaggerDoc("127.0.0.1","com.sxjlrj.api","API接口","swagger/api"))); } /** * 配置全局拦截器 */ @Override public void configInterceptor(Interceptors me) { me.addGlobalActionInterceptor(new SessionInViewInterceptor()); me.addGlobalActionInterceptor(new SessionInterceptor()); me.addGlobalActionInterceptor(new ExceptionInterceptor()); me.addGlobalActionInterceptor(new LoggerInterceptor()); } /** * 配置全局处理器 */ @Override public void configHandler(Handlers me) { /** 配置druid监控 **/ me.add(DruidKit.getDruidStatViewHandler()); // 路由处理 me.add(new CommonHandler()); //配置Swagger接口文档插件 me.add(new WebJarsHandler()); } /** * 配置模板引擎 */ @Override public void configEngine(Engine me) { // 这里只有选择JFinal TPL的时候才用 me.setDevMode(p.getBoolean("engineDevMode")); // 当前时间指令 me.addDirective("now", MyNowDirective.class); // 项目根路径 me.addSharedObject("path", JFinal.me().getContextPath()); // 项目名称 me.addSharedObject("projectName", p.get("projectName")); // 项目版权 me.addSharedObject("copyright", p.get("copyright")); // 配置共享函数模板 me.addSharedFunction(WebContant.functionTemp); } @Override public void onStart() { super.onStart(); //加载定时任务 ScheduleUtils scheduleUtils = new ScheduleUtils(); scheduleUtils.initJob(); } }
08-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值