跳到正文
Kale的数字花园
目录 文章
/2 分钟/4 阅读/0 评论

UTIL

1.线程域工具类

import com.alibaba.ttl.TransmittableThreadLocal;
import lombok.experimental.UtilityClass;
import org.springframework.lang.Nullable;

import java.util.*;
import java.util.function.Supplier;

/**
 * ThreadLocal 工具类,通过在ThreadLocal存储map信息,来实现在ThreadLocal中维护多个信息
 * * <br>e.g.<code>
 * * ThreadLocalUtil.set("key",value);<br>
 * * ThreadLocalUtil.get("key");<br>
 * * ThreadLocalUtil.remove("key");<br>
 * * ThreadLocalUtil.getAndRemove("key");<br>
 * * ThreadLocalUtil.get("key",()-&gt;defaultValue);<br>
 * * ThreadLocalUtil.clear();<br>
 * * </code>
 *
 * @param <T> 对象
 */
@UtilityClass
@SuppressWarnings("unchecked")
public class ThreadLocalUtil<T> {

	private final ThreadLocal<Map<String, Object>> THREAD_LOCAL = TransmittableThreadLocal.withInitial(HashMap::new);

	/**
	 * @return 获取threadLocal
	 */
	public Map<String, Object> getThreadLocal() {
		return THREAD_LOCAL.get();
	}

	/**
	 * @return threadLocal中的全部值
	 */
	public Map<String, Object> getAll() {
		return new HashMap<>(THREAD_LOCAL.get());
	}

	public <T> T get(String key) {
		return (T) THREAD_LOCAL.get().get(key);
	}

	public <T> T get(String key, T defaultValue) {
		Map<String, Object> map = THREAD_LOCAL.get();
		return map.get(key) == null ? defaultValue : (T) map.get(key);
	}


	/**
	 * 设置一个值到ThreadLocal
	 *
	 * @param key   键
	 * @param value 值
	 * @param <T>   值的类型
	 * @return 被放入的值
	 * @see Map#put(Object, Object)
	 */
	public static <T> T set(String key, T value) {
		THREAD_LOCAL.get().put(key, value);
		return value;
	}

	/**
	 * 设置一个值到ThreadLocal
	 *
	 * @param keyValueMap Map
	 * @see Map#putAll(Map)
	 */
	public void set(Map<String, Object> keyValueMap) {
		THREAD_LOCAL.get().putAll(keyValueMap);
	}

	/**
	 * 删除所有值
	 */
	public void remove() {
		THREAD_LOCAL.remove();
	}

	/**
	 * 根据前缀匹配值
	 *
	 * @param prefix 前缀
	 * @param <T>    泛型对象
	 * @return 泛型对象
	 */
	public <T> Map<String, T> fetchVarsByPrefix(String prefix) {
		Map<String, T> vars = new HashMap<>();
		if (prefix == null) {
			return vars;
		}
		Map<String, T> map = (Map<String, T>) THREAD_LOCAL.get();
		Set<Map.Entry<String, T>> set = map.entrySet();
		for (Map.Entry<String, T> entry : set) {
			String key = entry.getKey();
			if (key != null) {
				if (key.startsWith(prefix)) {
					vars.put(key, (T) entry.getValue());
				}
			}
		}
		return vars;
	}

	/**
	 * 删除参数对应的值
	 *
	 * @param key 键
	 * @see Map#remove(Object)
	 */
	public <T> T remove(String key) {
		return (T) THREAD_LOCAL.get().remove(key);
	}

	/**
	 * 清除指定前缀的值
	 *
	 * @param prefix 前缀
	 */
	public void clear(String prefix) {
		if (prefix == null) {
			return;
		}
		Map<String, Object> map = THREAD_LOCAL.get();
		Set<Map.Entry<String, Object>> set = map.entrySet();
		List<String> removeKeys = new ArrayList<>();

		for (Map.Entry<String, Object> entry : set) {
			String key = entry.getKey();
			if (key != null) {
				if (key.startsWith(prefix)) {
					removeKeys.add(key);
				}
			}
		}
		for (String key : removeKeys) {
			map.remove(key);
		}
	}

	/**
	 * 从ThreadLocal中获取值,并指定一个当值不存在的提供者
	 *
	 * @see Supplier
	 */
	@Nullable
	public <T> T getIfAbsent(String key, Supplier<T> supplierOnNull) {
		return ((T) THREAD_LOCAL.get().computeIfAbsent(key, k -> supplierOnNull.get()));
	}

	/**
	 * 获取一个值后然后删除掉
	 *
	 * @param key 键
	 * @param <T> 值类型
	 * @return 值, 不存在则返回null
	 * @see this#get(String)
	 * @see this#remove(String)
	 */
	public <T> T getAndRemove(String key) {
		try {
			return get(key);
		} finally {
			remove(key);
		}
	}

}

2.线程域工具类

/**
 * @Description : 跨模块存取数据线程域
 */
public final class ThreadLocalUtils {

    /**sellerId**/
    public static final ThreadLocal<String> SELLER_ID_TL = ThreadLocal.withInitial(() -> "");

    /**wdappid**/
    public static final ThreadLocal<String> WD_APP_ID_TL = ThreadLocal.withInitial(() -> "");

    /**sessionkey**/
    public static final ThreadLocal<String> SESSION_KEY_TL = ThreadLocal.withInitial(() -> "");

    /**vendor**/
    public static final ThreadLocal<String> VENDOR_TL = ThreadLocal.withInitial(() -> "");

    /**操作人**/
    public static final ThreadLocal<String> OPERATE_USER_TL = ThreadLocal.withInitial(() -> "");

    /**操作人 IP**/
    public static final ThreadLocal<String> OPERATE_IP_TL = ThreadLocal.withInitial(() -> "");

    /**特殊变量 红树林**/
    public static final ThreadLocal<Boolean> ERROR_ORDER = ThreadLocal.withInitial(() -> true);
    /**
    *每个用到ThreadLocal变量的线程 再执行完都要调用这个方法 在 返回前端的try catch 的finally里也需要调用该方法
    *目的是为了防止线程复用导致 变量串了,所以用完后需要移除变量
    * @return void
    */

    public static void finallyRemoveAllThreadLocal(){
        SELLER_ID_TL.remove();
        WD_APP_ID_TL.remove();
        SESSION_KEY_TL.remove();
        VENDOR_TL.remove();
        OPERATE_USER_TL.remove();
        OPERATE_IP_TL.remove();
        ERROR_ORDER.remove();
    }
}

评论需要登录。生产环境使用 GitHub 登录,本地可前往 登录页 使用开发登录。

还没有评论,来抢沙发。