说起来,由于以前都用python(python的模块天然就是单例模式),所以对这个设计模式基本没研究过,不过最近在弄java,发现单例模式是有丶东西的。
简单地说,单例模式就是一个类只实例化一次,在你的项目中,不过开多少线程实例化多少次,这个类的内存地址都是一个,下面我们写一个简单的单例模式示例:
public class SignalPattern {
private static SignalPattern instance = new SignalPattern();
private SignalPattern() {}
public static SignalPattern getInstance() {
return instance;
}
}
其实就是简单的加了个private,让类不能直接new,而且一上来就把单例对象给创建出来了。这让我想起来好像java里的静态代码块有点像啊,于是用静态代码块实现了一下:
package signalPattern;
public class StaticToSignal {
private static StaticToSignal staticToSignal;
static {
staticToSignal = new StaticToSignal();
}
private StaticToSignal() {
if (staticToSignal != null) {
throw new IllegalStateException();
}
}//其实讲道理,static代码块是在类加载的时候就执行的,所以理论上不太可能出现这个exception
public static StaticToSignal getStaticToSignal() {
return staticToSignal;
}
}
然后建个main类测一下:
package signalPattern;
public class MainTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
StaticToSignal signal = StaticToSignal.getStaticToSignal();
StaticToSignal signal2 = StaticToSignal.getStaticToSignal();
System.out.println(signal);
System.out.println(signal2);
}
}
输出结果是signalPattern.StaticToSignal@70dea4e signalPattern.StaticToSignal@70dea4e,显然,确实是个单例模式,正好符合我的一个在Spring项目里加载properties文件的需求。。。
先弄了个GlobalConfig类:
package cn.*****.common.config;
import java.io.IOException;
import java.util.Properties;
import cn.ie.cas.geovisupload.start.PropertiesLoader;
public class GlobalConfig {
public static KafkaConfig kafkaConfig;
public static LocalStoragePathConfig localStoragePathConfig;
static{
try {
kafkaConfig = new KafkaConfig();
Properties prop = new Properties();
prop.load(GlobalConfig.class.getResourceAsStream("/kafka.properties"));
String broker = "bootstrap.servers";
if (PropertiesLoader.containsProperty(broker)) {
prop.put(broker, PropertiesLoader.getPropertyValue(broker));
}
String zk = "zookeeper.connect";
if (PropertiesLoader.containsProperty(zk)) {
prop.put(zk, PropertiesLoader.getPropertyValue(zk));
}
kafkaConfig.setProducerPro(prop);
kafkaConfig.setConsumerPro(prop);
localStoragePathConfig = new LocalStoragePathConfig();
Properties storagePathPro = new Properties();
storagePathPro.load(GlobalConfig.class.getResourceAsStream("/localstoragepath.properties"));
localStoragePathConfig.setPathProperties(storagePathPro);
} catch (IOException e) {
e.printStackTrace();
}
}
public static KafkaConfig getKafkaConfig() {
return kafkaConfig;
}
public static void setKafkaConfig(KafkaConfig kafkaConfig) {
GlobalConfig.kafkaConfig = kafkaConfig;
}
public static LocalStoragePathConfig getLocalStoragePathConfig() {
return localStoragePathConfig;
}
public static void setLocalStoragePathConfig(LocalStoragePathConfig localStoragePathConfig) {
GlobalConfig.localStoragePathConfig = localStoragePathConfig;
}
}
在这个类实际上就是用来创建LocalStoragePathConfig和KafkaConfig类的,这俩类一个读取a.properties,一个读取b.properties。例如比较简单的LocalStoragePathConfig.java如下:
package cn.***.common.config;
import java.util.Properties;
public class LocalStoragePathConfig {
Properties pathProperties;
public Properties getPathProperties() {
return pathProperties;
}
public void setPathProperties(Properties pathProperties) {
this.pathProperties = pathProperties;
}
}
丑是丑了点,好歹也能用了。。感觉可以再借鉴简单工厂模式和工厂模式的思路修改一下: