Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.kaka.notice.Facade Maven / Gradle / Ivy
package com.kaka.notice;
import com.kaka.util.NanoId;
import com.kaka.util.ReflectUtils;
import com.kaka.util.StringUtils;
import java.util.*;
import java.util.concurrent.*;
/**
* 整个框架的中枢
*
* @author zkpursuit
*/
public class Facade implements INotifier {
String __name;
private final Map proxyMap = new ConcurrentHashMap<>();
private final Map mediatorMap = new ConcurrentHashMap<>();
private final Map> cmdMediatorMap = new ConcurrentHashMap<>();
private final Map cmdPoolMap = new ConcurrentHashMap<>();
private final Map> listenerMap = new ConcurrentHashMap<>();
private Executor threadPool;
private ScheduledExecutorService scheduleThreadPool;
private final Map> scheduleFutureMap = new ConcurrentHashMap<>();
private RemoteMessagePostman remoteMessagePostman;
/**
* 创建一个内核
*/
protected Facade() {
}
/**
* 获取内核唯一标识名
*
* @return 内核唯一标识名
*/
public String getName() {
return this.__name;
}
/**
* 初始化线程池,用于sendMessage中异步处理消息
*
* 全局设置一次
*
* @param threadPool 线程池
*/
public void initThreadPool(Executor threadPool) {
if (this.threadPool == null) {
this.threadPool = threadPool;
}
}
/**
* 异步定时调度线程池
*
* 全局设置一次
*
* @param scheduleThreadPool 定时调度线程池
*/
public void initScheduleThreadPool(ScheduledExecutorService scheduleThreadPool) {
if (this.scheduleThreadPool == null) {
this.scheduleThreadPool = scheduleThreadPool;
}
}
/**
* 初始化远程消息队列服务
*
* 全局设置一次
*
* @param remoteMessagePostman 远程消息处理器
*/
public void initRemoteMessagePostman(RemoteMessagePostman remoteMessagePostman) {
if (this.remoteMessagePostman == null) {
this.remoteMessagePostman = remoteMessagePostman;
this.remoteMessagePostman.setFacade(this);
}
}
/**
* 获取异步执行线程池
*
* @return 异步执行线程池
*/
public Executor getThreadPool() {
return this.threadPool;
}
/**
* 获取定时调度线程池
*
* @return 定时调度线程池
*/
public ScheduledExecutorService getScheduleThreadPool() {
return this.scheduleThreadPool;
}
/**
* 创建对象
*
* @param clasz 对象Class
* @return 实例
*/
Object createObject(Class clasz) {
try {
return ReflectUtils.newInstance(clasz);
} catch (Exception ex) {
throw new RuntimeException("必须声明一个无参构造方法", ex);
}
}
/**
* 注册
*
* @param obj 消息发送者
*/
final void register(Notifier obj) {
if (obj instanceof Mediator) {
this.registerMediator((Mediator) obj);
} else if (obj instanceof Proxy) {
this.registerProxy((Proxy) obj);
}
}
/**
* 注册数据代理
*
* @param name 数据代理唯一标识名
* @param proxy 数据处理集中代理器,当并发高的情况下需手动处理数据同步访问问题
*/
final void registerProxy(String name, Proxy proxy) {
if (proxy == null) {
return;
}
if (!StringUtils.isNotEmpty(name)) {
throw new RuntimeException("注册的Proxy.name不能为空");
}
if (hasProxy(name)) {
removeProxy(name);
}
proxyMap.put(name, proxy);
}
/**
* 注册数据代理,此方式会以别名的方式多次注册同一对象,即注册单例
*
* @param 限定类型
* @param proxyClass 数据处理集中代理器
* @param names 数据代理的唯一名称,可以为null,为null则将类限定名作为唯一名称
* @return 数据代理模型对象
*/
final public T registerProxy(Class proxyClass, String... names) {
final Proxy proxy = (Proxy) createObject(proxyClass);
String typeName = proxyClass.getTypeName();
Set aliasSet = names.length > 0 ? new HashSet<>(names.length + 1) : new HashSet<>(1);
if (proxy.name != null) {
registerProxy(proxy.name, proxy);
aliasSet.add(typeName);
} else {
ReflectUtils.setFieldValue(proxy, "name", typeName);
registerProxy(typeName, proxy);
}
for (String name : names) {
if (name != null && !name.equals(proxy.name) && !name.equals(typeName)) {
aliasSet.add(name);
}
}
for (String name : aliasSet) {
registerProxy(name, proxy);
proxy.addAlias(name);
}
proxy.setFacade(this);
proxy.onRegister();
return (T) proxy;
}
/**
* 注册数据代理,此方式会以别名的方式多次注册同一对象,即注册单例
*
* @param 限定类型
* @param proxyClass 数据处理集中代理器
* @return 数据代理模型对象
*/
final public T registerProxy(Class proxyClass) {
return registerProxy(proxyClass, (String) null);
}
/**
* 注册数据代理
*
* @param 限定类型
* @param proxy 数据处理集中代理器,当并发高的情况下需手动处理数据同步访问问题
* @return 数据处理
*/
final public T registerProxy(Proxy proxy) {
registerProxy(proxy.name, proxy);
proxy.setFacade(this);
proxy.onRegister();
return (T) proxy;
}
/**
* 是否已经注册了名为proxyName的数据代理处理器
*
* @param proxyName 数据处理代理器名称,此代理器的唯一标识
* @return true 存在此代理器
*/
final public boolean hasProxy(String proxyName) {
return proxyMap.containsKey(proxyName);
}
/**
* 是否存在相应的数据模型
*
* @param proxyClass 模型代理类
* @return true 存在
*/
final public boolean hasProxy(Class extends Proxy> proxyClass) {
String _name = proxyClass.getTypeName();
return hasProxy(_name);
}
/**
* 获取数据代理
*
* @param 限定类型
* @param proxyName 数据处理代理器名称,此代理器的唯一标识
* @return 数据处理代理器
*/
final public T retrieveProxy(String proxyName) {
return (T) proxyMap.get(proxyName);
}
/**
* 获取数据代理
*
* @param 限定类型
* @param proxyClass 数据处理代理器类
* @return 数据处理代理器
*/
final public T retrieveProxy(Class proxyClass) {
return retrieveProxy(proxyClass.getTypeName());
}
/**
* 移除数据代理
*
* @param 限定类型
* @param proxyName 数据代理器唯一标识
* @return 数据代理
*/
final public T removeProxy(String proxyName) {
Proxy proxy = proxyMap.remove(proxyName);
if (proxy != null) {
proxy.onRemove();
}
return (T) proxy;
}
/**
* 移除数据代理
*
* @param 限定类型
* @param proxy 数据代理器
* @return 数据代理
*/
final public T removeProxy(Proxy proxy) {
if (proxy == null) {
return null;
}
//因为是注册的相同对象,所以此处注册的别名对应的观察者也一并清除
String[] alis = proxy.getAliases();
if (alis != null && alis.length > 0) {
for (String alisName : alis) {
proxyMap.remove(alisName);
}
}
return removeProxy(proxy.name);
}
/**
* 移除数据代理
*
* @param 限定类型
* @param proxyClass 数据代理类型
* @return 数据代理
*/
final public T removeProxy(Class proxyClass) {
Proxy proxy = retrieveProxy(proxyClass.getTypeName());
removeProxy(proxy);
return (T) proxy;
}
/**
* 注册事件观察者
*
* @param name 事件观察者名称
* @param mediator 事件观察者
*/
final void registerMediator(String name, Mediator mediator) {
if (mediator == null) {
return;
}
if (!StringUtils.isNotEmpty(name)) {
throw new RuntimeException("注册的Observer.name不能为空");
}
if (hasMediator(name)) {
removeMediator(name);
}
mediatorMap.put(name, mediator);
}
/**
* 注册事件观察者感兴趣的事件
*
* @param mediator 事件观察者
*/
final void registerMediatorMessageInterests(Mediator mediator) {
Object[] nids = mediator.listMessageInterests();
if (nids == null || nids.length == 0) {
return;
}
for (Object nid : nids) {
List list = cmdMediatorMap.computeIfAbsent(nid, k -> Collections.synchronizedList(new ArrayList<>()));
list.add(mediator);
}
mediator.setFacade(this);
mediator.onRegister();
}
/**
* 注册事件观察者,此方式会以别名的方式多次注册同一对象,即注册单例
*
* 事件观察者能集中监听通知消息,可理解为可处理多个Command的对象
*
* @param 限定类型
* @param mediatorClass 事件观察者
* @param names 事件观察者的唯一名称,可以为null,为null则将类限定名作为唯一名称
* @return 事件观察者对象
*/
T registerMediator(Class mediatorClass, String... names) {
final Mediator observer = (Mediator) createObject(mediatorClass);
String typeName = mediatorClass.getTypeName();
Set aliasSet = names.length > 0 ? new HashSet<>(names.length + 1) : new HashSet<>(1);
if (observer.name != null) {
registerMediator(observer.name, observer);
aliasSet.add(typeName);
} else {
ReflectUtils.setFieldValue(observer, "name", typeName);
registerMediator(typeName, observer);
}
for (String name : names) {
if (name != null && !name.equals(observer.name) && !name.equals(typeName)) {
aliasSet.add(name);
}
}
for (String name : aliasSet) {
registerMediator(name, observer);
observer.addAlias(name);
}
registerMediatorMessageInterests(observer);
return (T) observer;
}
/**
* 注册事件观察者
*
* @param 限定类型
* @param mediatorClass 事件观察者,能集中监听通知消息,可理解为可处理多个Command的对象
* @return 事件观察者
*/
final public T registerMediator(Class mediatorClass) {
return registerMediator(mediatorClass, (String) null);
}
/**
* 注册事件观察者
*
* @param 限定类型
* @param mediator 视图代理,能集中监听通知消息,可理解为可处理多个Command的对象
* @return 事件观察者
*/
final T registerMediator(Mediator mediator) {
registerMediator(mediator.name, mediator);
registerMediatorMessageInterests(mediator);
return (T) mediator;
}
/**
* 是否已经注册了名为observerName的事件观察者
*
* @param mediatorName 视图代理处理唯一标识
* @return true 存在
*/
final public boolean hasMediator(String mediatorName) {
return mediatorMap.containsKey(mediatorName);
}
/**
* 是否存在相应的事件观察者
*
* @param mediatorClass 事件观察者类
* @return true 存在
*/
final public boolean hasMediator(Class extends Mediator> mediatorClass) {
return mediatorMap.containsKey(mediatorClass.getTypeName());
}
/**
* 移除事件观察者
*
* @param mediatorName 事件观察者处理唯一标识
*/
final T removeMediator(String mediatorName) {
Mediator mediator = mediatorMap.remove(mediatorName);
if (mediator != null) {
Object[] nids = mediator.listMessageInterests();
if (nids == null) {
return (T) mediator;
}
for (Object nid : nids) {
List list = cmdMediatorMap.get(nid);
if (list == null || list.isEmpty()) continue;
list.remove(mediator);
}
mediator.setFacade(null);
mediator.onRemove();
}
return (T) mediator;
}
/**
* 移除事件观察者
*
* @param 限定类型
* @param mediator 事件观察者
* @return 事件观察者
*/
final T removeMediator(Mediator mediator) {
if (mediator == null) {
return null;
}
//因为是注册的相同的事件,所以此处注册的别名对应的观察者也一并清除
String[] alis = mediator.getAliases();
if (alis != null && alis.length > 0) {
for (String alisName : alis) {
mediatorMap.remove(alisName);
}
}
return removeMediator(mediator.name);
}
/**
* 移除事件观察者
*
* @param 限定类型
* @param mediatorClass 事件观察者类型
* @return 事件观察者
*/
final public T removeMediator(Class mediatorClass) {
Mediator mediator = retrieveMediator(mediatorClass.getTypeName());
removeMediator(mediator);
return (T) mediator;
}
/**
* 获取事件观察者
*
* @param 限定类型
* @param mediatorName 事件观察者处理唯一标识
* @return 事件观察者�
*/
final T retrieveMediator(String mediatorName) {
return (T) mediatorMap.get(mediatorName);
}
/**
* 获取数据代理
*
* @param 限定类型
* @param mediatorClass 事件观察者类型
* @return 事件观察者
*/
final public T retrieveMediator(Class mediatorClass) {
return retrieveMediator(mediatorClass.getTypeName());
}
/**
* 获取通知对象,可为数据代理处理器或者为视图代理器
*
* @param name 通知对象的唯一标识
* @return 通知对象
* @see Proxy
* @see Mediator
*/
final Notifier retrieve(String name) {
if (proxyMap.containsKey(name)) {
return proxyMap.get(name);
}
return mediatorMap.get(name);
}
/**
* 是否存在命令执行器
*
* @param cmd 命令执行器唯一标识
* @return true 存在
* @see Command
*/
final public boolean hasCommand(Object cmd) {
return cmdPoolMap.containsKey(cmd);
}
/**
* 注册命令执行器
*
* @param cmd 命令执行器唯一标识
* @param clasz 命令执行器类对象
* @param pooledSize 池化大小,-1表示不池化
* @param priority 执行优先级,数字越小越先执行,可依此模拟切面编程
*/
final public void registerCommand(Object cmd, Class extends Command> clasz, int pooledSize, int priority) {
CommandPoolSortedSet sortedSet = cmdPoolMap.computeIfAbsent(cmd, k -> new CommandPoolSortedSet());
sortedSet.add(new CommandPool(this, pooledSize, clasz, priority));
}
/**
* 注册命令执行器
*
* @param cmd 命令执行器唯一标识
* @param clasz 命令执行器类对象
* @param pooledSize 池化大小,-1表示不池化
*/
final public void registerCommand(Object cmd, Class extends Command> clasz, int pooledSize) {
registerCommand(cmd, clasz, pooledSize, 0);
}
/**
* 注册命令执行器,默认不池化
*
* @param cmd 命令执行器唯一标识
* @param clasz 命令执行器类对象
*/
final public void registerCommand(Object cmd, Class extends Command> clasz) {
registerCommand(cmd, clasz, -1);
}
/**
* 移除命令执行器
*
* @param cmd 命令执行器唯一标识
*/
final public void removeCommand(Object cmd) {
cmdPoolMap.remove(cmd);
}
/**
* 移除命令执行器
*
* @param cmd 命令执行器唯一标识
* @param clasz 命令执行器类对象
*/
final public void removeCommand(Object cmd, Class extends Command> clasz) {
if (cmdPoolMap.containsKey(cmd)) {
CommandPoolSortedSet sortedSet = cmdPoolMap.get(cmd);
sortedSet.remove(new CommandPool(clasz));
}
}
/**
* 添加事件监听器
*
* @param cmd 事件名
* @param listener 事件监听器
*/
final public void addListener(Object cmd, IListener listener) {
Set listeners = listenerMap.computeIfAbsent(cmd, k -> Collections.synchronizedSet(new LinkedHashSet<>()));
listeners.add(listener);
}
/**
* 移除事件监听器
*
* @param cmd 事件名
* @param listener 事件监听器
*/
final public void removeListener(Object cmd, IListener listener) {
Set listeners = listenerMap.get(cmd);
if (listeners == null) return;
listeners.remove(listener);
if (listeners.isEmpty()) {
listenerMap.remove(cmd);
}
}
/**
* 移除事件名对应的所有监听器
*
* @param cmd 事件名
*/
final public void removeListener(Object cmd) {
listenerMap.remove(cmd);
}
/**
* 执行所有相同命令号下的{@link com.kaka.notice.Command}对象
*
* @param poolSet 相同命令号的{@link com.kaka.notice.Command}对象池集合
* @param msg 事件消息
*/
private void execCommands(final CommandPoolSortedSet poolSet, final Message msg) {
for (CommandPool pool : poolSet) {
final Command cmd = pool.obtain();
if (cmd == null) continue;
cmd.setFacade(this);
cmd.cmd = msg.getWhat();
cmd.execute0(msg);
msg.callback(cmd.getClass().getTypeName());
pool.idle(cmd);
}
}
/**
* 消息调度处理
*
* @param msg 待处理的消息
* @param asyn true为异步,设为true时须调用initThreadPool方法初始化线程池
*/
@Override
public void sendMessage(final Message msg, final boolean asyn) {
if (msg == null) {
return;
}
final CommandPoolSortedSet poolSet = cmdPoolMap.get(msg.getWhat());
if (poolSet != null) {
if (!asyn) {
execCommands(poolSet, msg);
} else {
if (threadPool == null) {
throw new RuntimeException(String.format("执行异步sendMessage前请先调用 %s.initThreadPool方法初始化线程池", this.getClass().toString()));
}
threadPool.execute(() -> execCommands(poolSet, msg));
}
}
final List mediatorList = cmdMediatorMap.get(msg.getWhat());
if (mediatorList != null) {
for (Mediator mediator : mediatorList) {
if (!asyn) {
mediator.handleMessage0(msg);
msg.callback(mediator.getClass().getTypeName());
} else {
if (threadPool == null) {
throw new RuntimeException(String.format("执行异步sendMessage前请先调用 %s.initThreadPool方法初始化线程池", this.getClass().toString()));
}
threadPool.execute(() -> {
mediator.handleMessage0(msg);
msg.callback(mediator.getClass().getTypeName());
});
}
}
}
final Set listeners = listenerMap.get(msg.getWhat());
if (listeners != null) {
for (IListener listener : listeners) {
listener.onMessage(msg, this);
msg.callback(listener.getClass().getTypeName());
}
}
}
/**
* 同步消息调度处理
*
* @param msg 通知消息
*/
@Override
final public void sendMessage(Message msg) {
sendMessage(msg, false);
}
/**
* 发送到远程消息队列,并由消息队列消费端处理事件消息。
*
* {@link SyncResult} 同步获取结果将不受支持。
*
* 支持{@link AsynResult}或者异步回调获取远程事件执行结果。
*
* 保证事件的顺利执行完全由消息队列的运行情况而决定。
*
* @param msg 待发送的消息
*/
@Override
public void sendRemoteMessage(Message msg) {
if (this.remoteMessagePostman == null) {
throw new RuntimeException(String.format("执行sendRemoteMessage前请先调用 %s.initRemoteMessagePostman方法初始化", this.getClass().toString()));
}
Map msgResultMap = msg.resultMap;
Message mqMsg = new Message(msg.getWhat(), msg.getBody());
String id = NanoId.randomNanoId();
if (msgResultMap != null) {
msgResultMap.forEach((Object key, IResult result) -> {
if (result instanceof AsynResult) {
mqMsg.setResult((String) key, new RemoteAsynResult<>());
}
});
}
this.remoteMessagePostman.remoteMessageCache.add(id, msg);
RemoteMessage remoteMessage = new RemoteMessage(this.remoteMessagePostman.event_topic, id, mqMsg);
this.remoteMessagePostman.sendRemoteMessage(remoteMessage);
}
/**
* 终止任务调度
*
* @param name 任务名
*/
void cancelSchedule(String name) {
ScheduledFuture> future = scheduleFutureMap.remove(name);
if (future == null) return;
future.cancel(true);
}
/**
* 定时调度执行事件通知
*
* @param msg 事件
* @param scheduler 定时调度器
*/
@Override
final public void sendMessage(final Message msg, Scheduler scheduler) {
if (scheduleThreadPool == null) {
throw new RuntimeException(String.format("执行sendMessage定时调度前请先调用 %s.initScheduleThreadPool方法初始化线程池", this.getClass().toString()));
}
if (scheduler.facade != null && scheduler.msg != null) {
throw new RuntimeException(String.format("每次调用sendMessage进行事件调度时必须保证%s参数为新的且独立的对象", Scheduler.class.getTypeName()));
}
Object cmd = msg.what;
scheduler.name += String.format("_$%s$_%s", cmd.getClass().getTypeName(), cmd);
scheduler.facade = this;
scheduler.msg = msg;
long currMillSecs = System.currentTimeMillis();
if (scheduler.startTime <= 0) {
scheduler.startTime = currMillSecs;
}
scheduler.prevExecTime.set(scheduler.startTime);
long initDelay = scheduler.startTime >= currMillSecs ? scheduler.startTime - currMillSecs : 0;
long delay = scheduler.interval <= 0 ? 1 : scheduler.interval;
cancelSchedule(scheduler.name);
ScheduledFuture> future = scheduleThreadPool.scheduleWithFixedDelay(scheduler, initDelay, delay, TimeUnit.MILLISECONDS);
scheduleFutureMap.put(scheduler.name, future);
}
/**
* 取消调度
*
* @param cmd 事件名
* @param group 调度器组名
*/
@Override
final public void cancelSchedule(Object cmd, String group) {
String name = group;
name += String.format("_$%s$_%s", cmd.getClass().getTypeName(), cmd);
cancelSchedule(name);
}
/**
* 释放内存
*/
public void dispose() {
for (Object key : cmdPoolMap.keySet()) {
CommandPoolSortedSet cmdPoolSet = cmdPoolMap.get(key);
if (cmdPoolSet != null) {
for (CommandPool pool : cmdPoolSet) {
pool.clear();
}
cmdPoolSet.clear();
}
}
this.cmdPoolMap.clear();
for (Object key : cmdMediatorMap.keySet()) {
List list = cmdMediatorMap.get(key);
if (list != null) {
list.clear();
}
}
this.cmdMediatorMap.clear();
this.mediatorMap.clear();
this.proxyMap.clear();
this.listenerMap.clear();
this.threadPool = null;
for (String key : scheduleFutureMap.keySet()) {
this.cancelSchedule(key);
}
this.scheduleFutureMap.clear();
this.scheduleThreadPool = null;
}
}