这是一个自定义的系统上下文demo,如有不足和遗漏之处,欢迎指出交流~
package com.xxx.lcloud.common.context;
import com.alibaba.ttl.TransmittableThreadLocal;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
/**
* @ClassName: CustomContext
* @Desc: 自定义上下文
* @author: Gift
* @date: 2020年05月22日
*/
public class CustomContext{
// 存储当前上下文ID
private static final TransmittableThreadLocal<String> CURRENT_CTXID_LOCAL = new TransmittableThreadLocal<>();
// 上下文ID生成器
private static final AtomicLong CTXID_CREATER = new AtomicLong();
// 上下文池
private static final Map<String, CustomContextBean> CONTEXT_BEAN_POOL = new ConcurrentHashMap<>();
// 自定义Map缓存
private static Map<String, Map<String, Object>> CONTEXT_CACHE_MAP = new ConcurrentHashMap<>();
// 线程唯一标识与上下文ID的映射表
private static final Map<String, String> CTXID_INHERITED_TABLE = new ConcurrentHashMap<>();
public static CustomContextBean init() {
String ctxId = CURRENT_CTXID_LOCAL.get();
if (ctxId != null) {
return CONTEXT_BEAN_POOL.get(ctxId);
} else {
//这个对象作为我们在存储一些常用的值,如上下文中的流水号,或者贯穿整个业务流程的字段
CustomContextBean customContextBean = new CustomContextBean ();
ctxId = currentCtxID();
CURRENT_CTXID_LOCAL.set(ctxId);
CONTEXT_BEAN_POOL.put(ctxId, customContextBean);
CONTEXT_CACHE_MAP.put(ctxId, new ConcurrentHashMap<>());
return customContextBean ;
}
}
/**
* 获取当前上下文对象
*
* @return
*/
public static ThreadLocal<String> getContext() {
return CURRENT_CTXID_LOCAL;
}
/**
* 获取当前上下文业务字段Bean
*
* @return
*/
public static CustomContextBean getContextBean() {
return CONTEXT_BEAN_POOL.get(ctxId());
}
/**
* 获取当前上下文CTXID
* @return
*/
public static String currentCtxID() {
String ctxID = CURRENT_CTXID_LOCAL.get();
if (ctxID == null) {
ctxID = CTXID_INHERITED_TABLE.get(assembleSubThreadID());
if (ctxID == null) {
ctxID = String.valueOf(nextCtxID());
CURRENT_CTXID_LOCAL.set(ctxID);
}
}
return ctxID;
}
/**
* 组装子线程唯一标识
* @return
*/
private static String assembleSubThreadID() {
return String.valueOf(Thread.currentThread().getId());
}
/**
* 生成上下文ID
* @return
*/
private static long nextCtxID() {
long ctxID = CTXID_CREATER.incrementAndGet();
if (CTXID_CREATER.compareAndSet(Long.MAX_VALUE, 0)) {
LoggerUtil.info("上下文CTXID 即将超过Long.MAX_VALUE, 下一个上下文CTXID将从[1]开始!" ,ctxID ,Long.MAX_VALUE );
}
return ctxID;
}
/**
* 获取上下文缓存的map
*
* @return
*/
public static Map<String, Object> getContextCache() {
return CONTEXT_CACHE_MAP.get(ctxId());
}
/**
* 释放上下文空间
*/
public static void release() {
String cid = ctxId();
// 移除上下文通用Bean
CONTEXT_BEAN_POOL.remove(cid);
// 移除上下临时Map值
CONTEXT_CACHE_MAP.remove(cid);
// 移除线程变量
CURRENT_CTXID_LOCAL.remove();
}
/**
* 获取上下文Id
*
* @return
*/
public static String ctxId() {
String ctxId = CURRENT_CTXID_LOCAL.get();
if (ctxId == null) {
ctxId = CTXID_INHERITED_TABLE.get(Thread.currentThread().getName());
}
return ctxId;
}
/**
* 添加自定义缓存值
*
* @param key
* @param object
*/
public static void setCache(String key, Object object) {
Map<String, Object> cache = getContextCache();
if (cache != null) {
cache.put(key, object);
}
}
/**
* 获取自定义缓存值
*
* @param key
* @return
*/
public static Object getCache(String key) {
Map<String, Object> cache = getContextCache();
return cache == null ? null : getContextCache().get(key);
}