翻阅网上已有文章,解决该问题的少之又少,虽然已有很多方案,但尝试后都失效,下面我将采用另外一种方式对该问题提供解决方案;
我的解决思路是,当前该类只提供了这一种方法进行初始化,那么我们就自己实现一个,这个方法的本身意义也就是将配置文件中的配置加载到当前配置中去
对已有的类中的方法进行修饰我们能很直观的想到可以采用装饰者模式进行对现在已有的功能进行装饰,增强现有类中的方法功能
首先我们需要知道,ClientGlobal.init他的内部方法其实是一个单例模式的简单实现,将构造方法设置成了私有化,如果采用继承方式是实现不了的,用传统的装饰者模式模型进行构造直接就可以抛弃,设计模式只是一种思想,不可以拘泥于固定模型逻辑进行实现,应该结合具体业务进行灵活的改造
查看当前类成员变量,都是为 public static 类型,其实这样我们就直接可以通过类名.变量名直接进行初始化就行了
那我们就开始进行实操:
增强 ClientGlobal 实现ClientGlobalPower
import org.csource.common.MyException;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.TrackerGroup;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Properties;
public class ClientGlobalPower {
/**
* 采用Properties进行全局加载配置
* @param propsFilePath
* @throws IOException
* @throws MyException
*/
public static void initByProperties(String propsFilePath) throws IOException, MyException {
Properties props = new Properties();
InputStream in = IniFileReaderPower.loadFromOsFileSystemOrClasspathAsStream(propsFilePath);
if (in != null) {
props.load(in);
}
initByProperties(props,propsFilePath);
}
/**
* 装饰当前版本 ClientGlobal.init()方法
* @param props
* @param conf_filename
* @throws IOException
* @throws MyException
*/
public static void initByProperties(Properties props,String conf_filename) throws IOException, MyException {
ClientGlobal.g_connect_timeout = stringToInteger(props.getProperty("connect_timeout","5"));
if (ClientGlobal.g_connect_timeout < 0) {
ClientGlobal.g_connect_timeout = 5;
}
ClientGlobal.g_connect_timeout *= 1000;
ClientGlobal.g_network_timeout = stringToInteger(props.getProperty("network_timeout","30"));
if (ClientGlobal.g_network_timeout < 0) {
ClientGlobal.g_network_timeout = 30;
}
ClientGlobal.g_network_timeout *= 1000;
ClientGlobal.g_charset = props.getProperty("charset");
if (ClientGlobal.g_charset == null || ClientGlobal.g_charset.length() == 0) {
ClientGlobal.g_charset = "ISO8859-1";
}
String[] szTrackerServers = getValues(props.getProperty("tracker_server"));
if (szTrackerServers == null) {
throw new MyException("item \"tracker_server\" in " + conf_filename + " not found");
} else {
InetSocketAddress[] tracker_servers = new InetSocketAddress[szTrackerServers.length];
for(int i = 0; i < szTrackerServers.length; ++i) {
String[] parts = szTrackerServers[i].split("\\:", 2);
if (parts.length != 2) {
throw new MyException("the value of item \"tracker_server\" is invalid, the correct format is host:port");
}
tracker_servers[i] = new InetSocketAddress(parts[0].trim(), Integer.parseInt(parts[1].trim()));
}
ClientGlobal.g_tracker_group = new TrackerGroup(tracker_servers);
stringToBoolean(props.getProperty("http.anti_steal_token","false"));
ClientGlobal.g_tracker_http_port = stringToInteger(props.getProperty("http.tracker_http_port","80"));
ClientGlobal.g_anti_steal_token = stringToBoolean(props.getProperty("http.anti_steal_token","false"));
if (ClientGlobal.g_anti_steal_token) {
ClientGlobal.g_secret_key = props.getProperty("http.secret_key");
}
}
}
private static String[] getValues(Object obj) {
if (obj == null) {
return null;
} else {
String[] values;
if (obj instanceof String) {
values = new String[]{(String)obj};
return values;
} else {
Object[] objs = ((ArrayList)obj).toArray();
values = new String[objs.length];
System.arraycopy(objs, 0, values, 0, objs.length);
return values;
}
}
}
private static Integer stringToInteger(String target){
return Integer.valueOf(target);
}
private static Boolean stringToBoolean(String target){
return Boolean.valueOf(target);
}
}
还需增强 IniFileReader 实现IniFileReaderPower
import org.csource.common.IniFileReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class IniFileReaderPower extends IniFileReader {
public IniFileReaderPower(String conf_filename) throws IOException {
super(conf_filename);
}
public static InputStream loadFromOsFileSystemOrClasspathAsStream(String filePath) {
InputStream in = null;
try {
// 优先从文件系统路径加载
if (new File(filePath).exists()) {
in = new FileInputStream(filePath);
//System.out.println("loadFrom...file path done");
}
// 从类路径加载
else {
in = classLoader().getResourceAsStream(filePath);
//System.out.println("loadFrom...class path done");
}
} catch (Exception ex) {
ex.printStackTrace();
}
return in;
}
public static ClassLoader classLoader() {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if (loader == null) {
loader = ClassLoader.getSystemClassLoader();
}
return loader;
}
}
我们需要将StorageClient1交由spring进行管理,以供后期业务逻辑的使用
@Slf4j
@Configuration
public class FastDfsConfig {
private static final String CONFIG_FILENAME = "fastdfs-client.properties";
/**
* 注入StorageClient1
* @return
*/
@Bean
public StorageClient1 storageClient1(){
try {
//全局初始化配置文件
ClientGlobalPower.initByProperties(CONFIG_FILENAME);
//定义TrackerClient,用于请求TrackerServer
TrackerClient trackerClient = new TrackerClient();
//连接tracker
TrackerServer trackerServer = trackerClient.getConnection();
//获取Stroage
StorageServer storeStorage = trackerClient.getStoreStorage(trackerServer);
//创建stroageClient
return new StorageClient1(trackerServer,storeStorage);
} catch (Exception e) {
log.error("加载fastDfs配置失败",e);
}
return null;
}
}