zoukankan      html  css  js  c++  java
  • 通过SecurityUtils获取Subject详解

    获取Subject

    使用shiro获取Subject的方法:

                Subject subject = SecurityUtils.getSubject();
    
    

    为什么,不管在哪通过SecurityUtils获取的Subject 都是同一个呢?
    而且Subject 里面还有用户的信息.

    猜想

    首先,能在各个地方获取Subject 只有一种办法,就是通过ThreadLocal类来实现,那么SecurityUtils肯定维护了一个ThreadLocal.

    源码分析

    首先看getSubject方法:
    在这里插入图片描述
    点到ThreadContext类:
    在这里插入图片描述
    说明是ThreadContext类维护了一个ThreadLocal;

    ThreadContext是什么时候跟Subject绑定的呢?

    我们发现有个方法:bind(Subject subject),
    看谁掉了这个方法:
    在这里插入图片描述
    在这里插入图片描述
    是SubjectCallable里面就开始绑定了,我们只要看是谁新建了SubjectCallable这个类就好了,发现在Subject里面执行execute的时候新建的,同时将subject也就是this传进去了.
    在这里插入图片描述
    现在明了了,上篇讲到subject创建详解
    里面有一张图:
    在这里插入图片描述
    在创建了subject的时候就通过execute来执行过滤器链的方法,这时候将创建好的subject跟ThreadContext进行了绑定,所以我们在任何地方都可以通过SecurityUtils.getSubject()来获取Subject.

    猜想ThreadLocal是跟当前线程绑定的,如果我springmvc里面使用异步方法执行,在异步处理过程中能获取到subject吗?

    是可以的,我们看ThreadContext里的的ThreadLocal具体实现就知道了:
    在这里插入图片描述
    主要功劳就是InheritableThreadLocal实现,这个实现大概做的事情就是如果父线程里面使用ThreadLocal了,然后在父线程里面又创建子线程,这是会将父线程的ThreadLocal拷贝到子线程里面,所以在异步线程里面是可以获取到subject的.
    这时候就会想如果是异步线程池呢,这一块比较复杂,因为
    InheritableThreadLocal实现的时候,如果是异步线程池,在一开始设置了ThreadLocal,他是有缓存的,详情见:解决父子线程ThreadLocal中的缓存问题

    验证:

    在这里插入图片描述

    世界上所有的不公平都是由于当事人能力不足造成的.
  • 相关阅读:
    P1093 奖学金
    华容道
    回文数
    P1654 OSU!
    Noip P1063 能量项链
    Noip 寻宝
    NOIP 2009 普及组 第三题 细胞分裂
    拦截器
    OGNL
    Struts2 配置详解
  • 原文地址:https://www.cnblogs.com/javayida/p/13346781.html
Copyright © 2011-2022 走看看