码迷,mamicode.com
首页 > 其他好文 > 详细

一个工作中碰到的小坑

时间:2021-06-30 17:41:03      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:catch   不同的   apc   lse   抽象   arrays   table   ceo   OLE   

记录一个小坑,开发压测平台的时候碰到的。

背景:现在在开发压测平台,抽象类一些常用拦截器作为 starter ,供所有 module 使用(目前我们有7个) 。starter 中使用的一些 entity, 使用了 Threadlocal ,用于保存用户信息和部门信息

问题:在 module 依赖了 starter 后,读不到保存在 Threadlocal 里的用户信息,如 roleID,businessName。

过程: 拦截器和业务代码里都加了以下打印 ThreadlocalMap 的代码来看看原因。

          最后 double check 了一下,因为定义保存在 Threadlocal 里的 entity 类,存在不同的报名,被编译器认为是两个不同的类,所以是取不到的,破案。

          这个和打印 Threadlocal 的代码没什么关系,不过学习到了很多 Threadlocal 的知识,学习一下。

          记录下来,作为警示。

 

以下是代码:

/**
* 我是打印ThreadLocalMap的分割线
*
*/

try {
//获取当前线程对象
Thread thread = Thread.currentThread();
//获取Thread中的threadLocals对象
Field threadLocals = Thread.class.getDeclaredField("threadLocals");
threadLocals.setAccessible(true);
//ThreadLocalMap是ThreadLocal中的一个内部类,并且访问权限是default
// 这里获取的是ThreadLocal.ThreadLocalMap
Object threadLocalMap = threadLocals.get(thread);

//这里要这样获取ThreadLocal.ThreadLocalMap
Class threadLocalMapClazz = Class.forName("java.lang.ThreadLocal$ThreadLocalMap");
//获取ThreadLocalMap中的Entry对象
Field tableField = threadLocalMapClazz.getDeclaredField("table");
tableField.setAccessible(true);
//获取ThreadLocalMap中的Entry
Object[] objects = (Object[]) tableField.get(threadLocalMap);

//获取ThreadLocalMap中的Entry
Class entryClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap$Entry");
//获取ThreadLocalMap中的Entry中的value字段
Field entryValueField = entryClass.getDeclaredField("value");
entryValueField.setAccessible(true);
//Entry继承了WeakReference,WeakReference继承了Reference
Field referEnceField = Reference.class.getDeclaredField("referent");
referEnceField.setAccessible(true);

Arrays.stream(objects).filter(obj -> obj != null).forEach((obj) -> {
try {
Object value = entryValueField.get(obj);
if (value != null) {
if (value instanceof Reference) {
Reference ref = (Reference) value;
log.info(ref.getClass().getName() + "------>" + ref.get());
} else {
log.info("------>" + value.getClass());
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
});
} catch (Exception e) {
e.printStackTrace();
}


/**
* 我是打印ThreadLocalMap的结束
*/

一个工作中碰到的小坑

标签:catch   不同的   apc   lse   抽象   arrays   table   ceo   OLE   

原文地址:https://www.cnblogs.com/spillage/p/14950987.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!