一起因:
1)最近,有个小的工具需进行数据库操作,用到Jfinal的ActiveRecord,但是发现若要从配置文件中读取参数的,Jfinal中相应的代码都在JFinalConfig中。最后只能把相关的代码抽取出来来实现配置参数的读取。
2)一个基于Jfinal的项目中有不少配置参数,个人有个喜好,就是一个配置文件只干一件事情,比如database.properties里面只存取几个数据库连接信息。router.properties里面只存储路由相关信息。个人不喜欢将所有配置都塞到一个类似app.properties的文件里。
重构目标:
1)将从配置文件中读取参数相关代码从JFinalConfig中移除,专门建立一个类来做此事,方便单独需要ActiveRecord模块的场合使用,提高灵活性。
2)支持从多个properties文件中读取配置,并能通过统一的接口来获取这些文件中的所有配置信息。
上代码:
01 |
public abstract class JFinalConfig { |
06 |
public abstract void configConstant(Constants me); |
11 |
public abstract void configRoute(Routes me); |
16 |
public abstract void configPlugin(Plugins me); |
19 |
* Config interceptor applied to all actions. |
21 |
public abstract void configInterceptor(Interceptors me); |
26 |
public abstract void configHandler(Handlers me); |
29 |
* Call back after JFinal start |
31 |
public void afterJFinalStart(){}; |
34 |
* Call back before JFinal stop |
36 |
public void beforeJFinalStop(){}; |
新建的PropertyConfig类代码,
1)允许多文件读取
2)除了兼容JFianl从WEB-INF读取配置信息外,也允许从classpath中读取配置信息。
3)单例模式运行。
002 |
import java.io.FileInputStream; |
003 |
import java.io.IOException; |
004 |
import java.io.InputStream; |
005 |
import java.util.Map.Entry; |
006 |
import java.util.Properties; |
007 |
import java.util.concurrent.ConcurrentHashMap; |
008 |
import java.util.concurrent.ConcurrentMap; |
010 |
import com.jfinal.kit.PathKit; |
011 |
import com.jfinal.kit.StringKit; |
015 |
* PropertyConfig: read properties file |
016 |
* file path: ../WEB-INFO/ or classpath |
019 |
public class PropertyConfig { |
021 |
private ConcurrentMap<String, Object> properties = new ConcurrentHashMap<String, Object>(); |
023 |
private static PropertyConfig config = new PropertyConfig(); |
025 |
private PropertyConfig(){} |
027 |
public static PropertyConfig me(){ |
032 |
public void loadPropertyFile(String file){ |
033 |
Properties property = new Properties(); |
034 |
if (StringKit.isBlank(file)) |
035 |
throw new IllegalArgumentException( "Parameter of file can not be blank" ); |
036 |
if (file.contains( ".." )) |
037 |
throw new IllegalArgumentException( "Parameter of file can not contains \"..\"" ); |
039 |
InputStream inputStream = null ; |
041 |
if (file.startsWith(File.separator)) |
042 |
fullFile = PathKit.getWebRootPath() + File.separator + "WEB-INF" + file; |
044 |
fullFile = PathKit.getWebRootPath() + File.separator + "WEB-INF" + File.separator + file; |
047 |
inputStream = new FileInputStream( new File(fullFile)); |
048 |
property.load(inputStream); |
049 |
} catch (Exception eOne) { |
051 |
ClassLoader loader = Thread.currentThread().getContextClassLoader(); |
052 |
property.load(loader.getResourceAsStream(file)); |
053 |
} catch (IOException eTwo) { |
054 |
throw new IllegalArgumentException( "Properties file loading failed: " + eTwo.getMessage()); |
058 |
try { if (inputStream != null ) inputStream.close();} catch (IOException e) {e.printStackTrace();} |
060 |
if (property != null ){ |
061 |
for (Entry<Object,Object> entry : property.entrySet()){ |
062 |
this .properties.put(entry.getKey().toString(), entry.getValue()); |
067 |
public String getProperty(String key) { |
068 |
if ( this .properties.containsKey(key)){ |
069 |
return properties.get(key).toString(); |
074 |
public String getProperty(String key, String defaultValue) { |
075 |
if ( this .properties.containsKey(key)){ |
076 |
return properties.get(key).toString(); |
081 |
public Integer getPropertyToInt(String key) { |
082 |
Integer resultInt = null ; |
083 |
String resultStr = this .getProperty(key); |
084 |
if (resultStr != null ) |
085 |
resultInt = Integer.parseInt(resultStr); |
089 |
public Integer getPropertyToInt(String key, Integer defaultValue) { |
090 |
Integer result = getPropertyToInt(key); |
091 |
return result != null ? result : defaultValue; |
094 |
public Boolean getPropertyToBoolean(String key) { |
095 |
String resultStr = this .getProperty(key); |
096 |
Boolean resultBool = null ; |
097 |
if (resultStr != null ) { |
098 |
if (resultStr.trim().equalsIgnoreCase( "true" )) |
100 |
else if (resultStr.trim().equalsIgnoreCase( "false" )) |
106 |
public Boolean getPropertyToBoolean(String key, boolean defaultValue) { |
107 |
Boolean result = getPropertyToBoolean(key); |
108 |
return result != null ? result : defaultValue; |
使用例子:
1 |
public void configConstant(Constants me) { |
3 |
PropertyConfig.me().loadPropertyFile( "database.properties" ); |
4 |
PropertyConfig.me().loadPropertyFile( "app.properties" ); |
6 |
me.setDevMode(PropertyConfig.me().getPropertyToBoolean( "jfinal.devmode" , false )); |
1 |
public void configPlugin(Plugins me) { |
3 |
PropertyConfig config = PropertyConfig.me(); |
4 |
String driver = config.getProperty( "dataSource.driverClass" ); |
5 |
String jdbcUrl = config.getProperty( "dataSource.url" ); |
6 |
String username = config.getProperty( "dataSource.userName" ); |
7 |
String password = config.getProperty( "dataSource.password" ); |
打完收工。