InstanceManager.java
package org.example.testmgr;
import org.reflections.Reflections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public abstract class InstanceManager {
private static Map<String, InstanceManager> instances = new ConcurrentHashMap<>();
/**
* 暴露出接口,获取单例类
*
* @param clazz
* @param <T>
* @return
*/
public static <T extends InstanceManager> T inst(Class<?> clazz) {
Object inst = instances.get(clazz.getName());
if (inst == null) {
throw new RuntimeException("获取单例出错" + clazz.getName());
}
return (T) inst;
}
/**
* 供自己调用下初始化所有的单例类
* 一般是起服时调用
*/
public static void initialize() {
Reflections reflections = new Reflections("org");
Set<Class<? extends InstanceManager>> set = reflections.getSubTypesOf(InstanceManager.class);
set.forEach(c -> {
try {
InstanceManager inst = c.getConstructor().newInstance();
inst.init();
instances.put(c.getName(), inst);
} catch (Exception e) {
e.printStackTrace();
}
});
}
/**
* 留给子类去初始化
*/
public abstract void init();
}
GuildConfig.java
package org.example.testmgr;
public class GuildConfig extends InstanceManager {
private int status = 0;
@Override
public void init() {
System.out.println("Guild init");
status = 1;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
Main.java
package org.example.testmgr;
public class Main {
public static void main(String[] args) {
// 初始化 所有的代理对象
InstanceManager.initialize();
// 单例类测试
GuildConfig guild = InstanceManager.inst(GuildConfig.class);
int status = guild.getStatus();
System.out.println(status);
}
}
/*
Guild init
1
*/
思考:
这个单例类写法有各种各样,有些要求起服时做下初始化,如:配置不能重复读取,需要加载到内存。这种写法相当于起服时会自动调用init方法。
如:排行榜需要15min持久化一次到数据库,那么起服时会启动一个定时器,因此这种都可以使用这类单例模式。
甚至最好在inst中再写一下inst方法,返回InstanceManager.inst(xxx.class)这样子 可以不用传参数了。