zoukankan      html  css  js  c++  java
  • 一个工作中碰到的小坑

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

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

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

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

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

              其实最终发现原因和这段代码没有关系,只是在仔细检查了打印内容的时候发现了不一样的地方,so。不过学习到了很多 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的结束
    */
  • 相关阅读:
    ora-01847:月份中日的值必须介于 1 和当月最后一日之间
    (转)ORACLE中关于外键缺少索引的探讨和总结
    (转) Oracle性能优化-读懂执行计划
    shutdown immediate 持久无法关闭数据库之解决方案
    Oracle11g adump目录下面.aud增长导致空间撑满无法删除导致CRS无法启动的解决方法
    linux几种常见的文件内容查找和替换命令
    unzip解压3G或者4G以上文件失败的解决方法
    IMP-00058: ORACLE error 1882 encountered
    AIX文件系统/var空间100%的问题
    html5手机网站需要加的那些meta/link标签,html5 meta全解(转)
  • 原文地址:https://www.cnblogs.com/spillage/p/14950987.html
Copyright © 2011-2022 走看看