文档章节

对JFinal的JFinalConfig的一次重构尝试。

玛雅牛
 玛雅牛
发布于 2013/07/16 02:04
字数 742
阅读 4669
收藏 25

一起因:

1)最近,有个小的工具需进行数据库操作,用到Jfinal的ActiveRecord,但是发现若要从配置文件中读取参数的,Jfinal中相应的代码都在JFinalConfig中。最后只能把相关的代码抽取出来来实现配置参数的读取。

2)一个基于Jfinal的项目中有不少配置参数,个人有个喜好,就是一个配置文件只干一件事情,比如database.properties里面只存取几个数据库连接信息。router.properties里面只存储路由相关信息。个人不喜欢将所有配置都塞到一个类似app.properties的文件里。

重构目标:

 

1)将从配置文件中读取参数相关代码从JFinalConfig中移除,专门建立一个类来做此事,方便单独需要ActiveRecord模块的场合使用,提高灵活性。

2)支持从多个properties文件中读取配置,并能通过统一的接口来获取这些文件中的所有配置信息。

上代码:

 

public abstract class JFinalConfig {

	/**
	 * Config constant
	 */
	public abstract void configConstant(Constants me);

	/**
	 * Config route
	 */
	public abstract void configRoute(Routes me);

	/**
	 * Config plugin
	 */
	public abstract void configPlugin(Plugins me);

	/**
	 * Config interceptor applied to all actions.
	 */
	public abstract void configInterceptor(Interceptors me);

	/**
	 * Config handler
	 */
	public abstract void configHandler(Handlers me);

	/**
	 * Call back after JFinal start
	 */
	public void afterJFinalStart(){};

	/**
	 * Call back before JFinal stop
	 */
	public void beforeJFinalStop(){};
}

 

 

新建的PropertyConfig类代码,

1)允许多文件读取
2)除了兼容JFianl从WEB-INF读取配置信息外,也允许从classpath中读取配置信息。
3)单例模式运行。

 

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import com.jfinal.kit.PathKit;
import com.jfinal.kit.StringKit;

/**
 *
 * PropertyConfig: read properties file
 * file path: ../WEB-INFO/ or classpath
 *
 */
public class PropertyConfig {

	private ConcurrentMap<String, Object> properties =  new ConcurrentHashMap<String, Object>();

	private static PropertyConfig config = new PropertyConfig();

	private PropertyConfig(){}

	public static PropertyConfig me(){
		return config;
	}


	public void loadPropertyFile(String file){
		Properties property = new Properties();
		if (StringKit.isBlank(file))
			throw new IllegalArgumentException("Parameter of file can not be blank");
		if (file.contains(".."))
			throw new IllegalArgumentException("Parameter of file can not contains \"..\"");

		InputStream inputStream = null;
		String fullFile;	// String fullFile = PathUtil.getWebRootPath() + file;
		if (file.startsWith(File.separator))
			fullFile = PathKit.getWebRootPath() + File.separator + "WEB-INF" + file;
		else
			fullFile = PathKit.getWebRootPath() + File.separator + "WEB-INF" + File.separator + file;

		try {
			inputStream = new FileInputStream(new File(fullFile));
			property.load(inputStream);
		} catch (Exception eOne) {
            try {
            	ClassLoader loader = Thread.currentThread().getContextClassLoader();
            	property.load(loader.getResourceAsStream(file));
			} catch (IOException eTwo) {
				throw new IllegalArgumentException("Properties file loading failed: " + eTwo.getMessage());
			}
		}
		finally {
			try {if (inputStream != null) inputStream.close();} catch (IOException e) {e.printStackTrace();}
		}
		if (property != null){
			for(Entry<Object,Object>  entry : property.entrySet()){
				this.properties.put(entry.getKey().toString(), entry.getValue());
			}
		}
	}

	public String getProperty(String key) {
		if(this.properties.containsKey(key)){
			return properties.get(key).toString();
		}
		return null;
	}

	public String getProperty(String key, String defaultValue) {
		if(this.properties.containsKey(key)){
			return properties.get(key).toString();
		}
		return defaultValue;
	}

	public Integer getPropertyToInt(String key) {
		Integer resultInt = null;
		String resultStr = this.getProperty(key);
		if (resultStr != null)
			resultInt =  Integer.parseInt(resultStr);
		return resultInt;
	}

	public Integer getPropertyToInt(String key, Integer defaultValue) {
		Integer result = getPropertyToInt(key);
		return result != null ? result : defaultValue;
	}

	public Boolean getPropertyToBoolean(String key) {
		String resultStr = this.getProperty(key);
		Boolean resultBool = null;
		if (resultStr != null) {
			if (resultStr.trim().equalsIgnoreCase("true"))
				resultBool = true;
			else if (resultStr.trim().equalsIgnoreCase("false"))
				resultBool = false;
		}
		return resultBool;
	}

	public Boolean getPropertyToBoolean(String key, boolean defaultValue) {
		Boolean result = getPropertyToBoolean(key);
		return result != null ? result : defaultValue;
	}
}

使用例子:

 

 

public void configConstant(Constants me) {
		//加载数据库配置文件
		PropertyConfig.me().loadPropertyFile("database.properties");
		PropertyConfig.me().loadPropertyFile("app.properties");
               //设定为开发者模式
 me.setDevMode(PropertyConfig.me().getPropertyToBoolean("jfinal.devmode", false));

 

 

public void configPlugin(Plugins me) {
		//从配置文件中获取数据库配置项
		PropertyConfig config = PropertyConfig.me();
        String driver = config.getProperty("dataSource.driverClass");
        String jdbcUrl = config.getProperty("dataSource.url");
        String username = config.getProperty("dataSource.userName");
        String password = config.getProperty("dataSource.password");

 

打完收工。

© 著作权归作者所有

共有 人打赏支持
玛雅牛

玛雅牛

粉丝 484
博文 113
码字总数 27442
作品 4
高级程序员
私信 提问
加载中

评论(16)

玛雅牛
玛雅牛
最新1.9版本已经自带这个功能,已经切换到官方版本了。
走位风骚闪着腰
走位风骚闪着腰

引用来自“王仁辉(java)”的评论

@JFinal @玛雅牛 关于这个加载文件的配置 其实没有必要搞得这个复杂 还修改了用户使用方式 我是这样写的
自定义一个Config类 extends com.jfinal.config.JFinalConfig,然后修改里面的loadPropertyFile方法
<code>//判断是否带有文件分隔符
boolean startStuff = file.startsWith(File.separator);
if (startStuff)
fullFile = PathKit.getWebRootPath() + File.separator + "WEB-INF" + file;
else
fullFile = PathKit.getWebRootPath() + File.separator + "WEB-INF" + File.separator + file;
File propFile = new File(fullFile);
//判断文件是否存在WebInf
if (!propFile.exists()) {
if (startStuff)
fullFile = PathKit.getRootClassPath() + file;
else
fullFile = PathKit.getRootClassPath() + File.separator + file;
propFile = new File(fullFile);
//判断文件是否存在class
if (!propFile.exists()) {
throw new IllegalArgumentException("Properties file not found: " + fullFile);
}
}
</code>
表示没看懂你要做什么
JFinal
JFinal

引用来自“王仁辉(java)”的评论

@JFinal @玛雅牛 关于这个加载文件的配置 其实没有必要搞得这个复杂 还修改了用户使用方式 我是这样写的
自定义一个Config类 extends com.jfinal.config.JFinalConfig,然后修改里面的loadPropertyFile方法
<code>//判断是否带有文件分隔符
boolean startStuff = file.startsWith(File.separator);
if (startStuff)
fullFile = PathKit.getWebRootPath() + File.separator + "WEB-INF" + file;
else
fullFile = PathKit.getWebRootPath() + File.separator + "WEB-INF" + File.separator + file;
File propFile = new File(fullFile);
//判断文件是否存在WebInf
if (!propFile.exists()) {
if (startStuff)
fullFile = PathKit.getRootClassPath() + file;
else
fullFile = PathKit.getRootClassPath() + File.separator + file;
propFile = new File(fullFile);
//判断文件是否存在class
if (!propFile.exists()) {
throw new IllegalArgumentException("Properties file not found: " + fullFile);
}
}
</code>

回头我看看你的设计,感谢支持 ^_^
Dreampie
Dreampie
@JFinal @玛雅牛 关于这个加载文件的配置 其实没有必要搞得这个复杂 还修改了用户使用方式 我是这样写的
自定义一个Config类 extends com.jfinal.config.JFinalConfig,然后修改里面的loadPropertyFile方法
<code>//判断是否带有文件分隔符
boolean startStuff = file.startsWith(File.separator);
if (startStuff)
fullFile = PathKit.getWebRootPath() + File.separator + "WEB-INF" + file;
else
fullFile = PathKit.getWebRootPath() + File.separator + "WEB-INF" + File.separator + file;
File propFile = new File(fullFile);
//判断文件是否存在WebInf
if (!propFile.exists()) {
if (startStuff)
fullFile = PathKit.getRootClassPath() + file;
else
fullFile = PathKit.getRootClassPath() + File.separator + file;
propFile = new File(fullFile);
//判断文件是否存在class
if (!propFile.exists()) {
throw new IllegalArgumentException("Properties file not found: " + fullFile);
}
}
</code>
一路找北
顺手贴来用了。另外,
for(Entry<Object,Object> entry : property.entrySet()){
this.properties.put(entry.getKey().toString(), entry.getValue());
}
直接putAll就OK了吧?
后天雨街
后天雨街
这个想法不错,还有activerecord如何原生实现多数据源操作,并且具备事物管理多数据源就最好了。
JFinal
JFinal

引用来自“玛雅牛”的评论

引用来自“JFinal”的评论

正常来说是应该分离出来的,这样的代码也更清晰,但jfinal也有一些考虑,例如目前的实现方式可以省些代码这是一点,另外jfinal就是希望做到极简,引入PropertyConfig这个类虽然简单,但也还是需要了解学习怎么用的。还有一点jfinal目前的设计是可以支持加载多个属性文件的,可以多次调用loadPropertyFile方法,这样可以在不同地方调用就可以使用不同的配置文件

嗯。若使用JFinal全栈的情况下,引入PropertyConfig的必要性不是很大。但若要在其他项目中使用JFinal的ActiveRecord模块,需要读取配置文档化,JFinal本身引入PropertyConfig的话能减少一些代码量。

有时间的时候我考虑做个 com.jfinal.kit.PropertyKit
JFinal
JFinal

引用来自“玛雅牛”的评论

引用来自“JFinal”的评论

正常来说是应该分离出来的,这样的代码也更清晰,但jfinal也有一些考虑,例如目前的实现方式可以省些代码这是一点,另外jfinal就是希望做到极简,引入PropertyConfig这个类虽然简单,但也还是需要了解学习怎么用的。还有一点jfinal目前的设计是可以支持加载多个属性文件的,可以多次调用loadPropertyFile方法,这样可以在不同地方调用就可以使用不同的配置文件

嗯。若使用JFinal全栈的情况下,引入PropertyConfig的必要性不是很大。但若要在其他项目中使用JFinal的ActiveRecord模块,需要读取配置文档化,JFinal本身引入PropertyConfig的话能减少一些代码量。

可以考虑将这部分代码做成工具类,然后在 JFinalConfig中的loadPropertyFile、getPropertiy方法中转调一下,这样就能重用这个工具类了
玛雅牛
玛雅牛

引用来自“JFinal”的评论

正常来说是应该分离出来的,这样的代码也更清晰,但jfinal也有一些考虑,例如目前的实现方式可以省些代码这是一点,另外jfinal就是希望做到极简,引入PropertyConfig这个类虽然简单,但也还是需要了解学习怎么用的。还有一点jfinal目前的设计是可以支持加载多个属性文件的,可以多次调用loadPropertyFile方法,这样可以在不同地方调用就可以使用不同的配置文件

嗯。若使用JFinal全栈的情况下,引入PropertyConfig的必要性不是很大。但若要在其他项目中使用JFinal的ActiveRecord模块,需要读取配置文档化,JFinal本身引入PropertyConfig的话能减少一些代码量。
JFinal
JFinal
正常来说是应该分离出来的,这样的代码也更清晰,但jfinal也有一些考虑,例如目前的实现方式可以省些代码这是一点,另外jfinal就是希望做到极简,引入PropertyConfig这个类虽然简单,但也还是需要了解学习怎么用的。还有一点jfinal目前的设计是可以支持加载多个属性文件的,可以多次调用loadPropertyFile方法,这样可以在不同地方调用就可以使用不同的配置文件
对JFinal的JFinalConfig的一次重构尝试。

一起因: 1)最近,有个小的工具需进行数据库操作,用到Jfinal的ActiveRecord,但是发现若要从配置文件中读取参数的,Jfinal中相应的代码都在JFinalConfig中。最后只能把相关的代码抽取出来来...

玛雅牛
2013/07/16
423
2
JFinal 1.1.1 七夕特别版发布

七夕情人节到啦!!! 程序猿们是否还在苦逼编程呢? 屌丝们为嘛没时间陪女友呢?码农们是否还在 CRUD 呢? 如果答案是肯定的,那还等什么呢?花两个小时看看 JFinal,即可为您节省无数青葱岁...

JFinal
2012/08/23
2.8K
63
求助:jfinal2.2事务不回滚

@JFinal 詹总,最近项目中使用了jfinal2.2,始终无法使用事务回滚操作,查找了很久,一直未能找到原因。通过运行jfinal_demo已经证实不是mysql的问题,表是innoDB。mysql版本是5.7.12。请帮忙...

CC88
2016/08/09
506
2
JFinal启动过程

@JFinal 你好,想跟你请教个问题:你好,最近有幸用JFinal做项目,想请问一下,JFinal的具体启动流程是如何的?SysConfig继承JFinalConfig,JFinal,JFinalFilter等类的启动过程的流程是如何...

有梦想的小孩
2013/05/14
686
6
基于JFinal的web插件平台(完全分离)如何加载JFinal库?

@JFinal 你好,想跟你请教个问题: 最近正在做一个基于插件体系的WEB开发平台,而JFinal 本身自带插件功能本身不能焊好的实现我的构想。 其它的库因为不存在父ClassLoader调用子ClassLoader...

行水流云
2015/03/02
650
4

没有更多内容

加载失败,请刷新页面

加载更多

matlab-线性代数 将矩阵变成列、行向量

  matlab : R2018a 64bit     OS : Windows 10 x64 typesetting : Markdown    blog : my.oschina.net/zhichengjiu    gitee : gitee.com/zhichengjiu   将矩阵变成列、行向量(按照......

志成就
昨天
2
0
开始使用Filebeat

认识Beats Beats是用于单用途数据托运人的平台。它们以轻量级代理的形式安装,并将来自成百上千台机器的数据发送到Logstash或Elasticsearch。 (画外音:通俗地理解,就是采集数据,并上报到...

北极南哥
昨天
2
0
shell getopts template

!/bin/bash# ------------------------------------------------------------------# [Author] Title# Description# ---------------------------------------------------......

易野
昨天
2
0
DHCP服务原理与搭建(Linux系统+路由器,二选一方案)

大家都知道上网的最基本前提是要在终端上设置IP、子网掩码、网关、DNS等地址信息,在家里或者在办公室很多时候打开电脑后发现就可以上网,并没有手动设置IP、掩码、DNS地址也能上网,这是什么...

老率的IT私房菜
昨天
7
0
GitLab的安装及使用教程

首页 新随笔 管理 随笔 - 575 文章 - 0 评论 - 27 GitLab的安装及使用教程 1、配置yum源 vim /etc/yum.repos.d/gitlab-ce.repo 复制以下内容: [gitlab-ce] name=Gitlab CE Repository base...

rootliu
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部