getSubject()是最常用的方法了。
public static Subject getSubject() {
Subject subject = ThreadContext.getSubject();
if (subject == null) {
subject = (new Subject.Builder()).buildSubject();
ThreadContext.bind(subject);
}
return subject;
}
来自线程引用ThreadContext,,看ThreadContext代码
public static final String SUBJECT_KEY = ThreadContext.class.getName() + "_SUBJECT_KEY";
private static final ThreadLocal<Map<Object, Object>> resources = new InheritableThreadLocalMap<Map<Object, Object>>();
public static Subject getSubject() {
return (Subject) get(SUBJECT_KEY);
}
public static Object get(Object key) {
if (log.isTraceEnabled()) {
String msg = "get() - in thread [" + Thread.currentThread().getName() + "]";
log.trace(msg);
}
Object value = getValue(key);
if ((value != null) && log.isTraceEnabled()) {
String msg = "Retrieved value of type [" + value.getClass().getName() + "] for key [" +
key + "] " + "bound to thread [" + Thread.currentThread().getName() + "]";
log.trace(msg);
}
return value;
}
private static Object getValue(Object key) {
Map<Object, Object> perThreadResources = resources.get();
return perThreadResources != null ? perThreadResources.get(key) : null;
}
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
最后来自resoucres,它是ThreadContxt的静态变量,是线程副本,resources.get()得到当前线程的线程副本,从线程副本中拿到以ThreadContxt实例为key对应的value值,是个泛型,这里泛型是一个Map<object,object>类型.
线程副本https://blog.csdn.net/u014203449/article/details/83241010
再从map中得到以常量SUBJECT_KEY 为key的value值subject对象。
因为不同线程保存的线程副本不同,所以map不同,subject也就不同。
那subject是谁保存在线程副本当中的呢,同一个用户不同的请求,线程是不同的,如何保证subejct能获取一致?
第一次创建subject时把session和subject绑定了关系,这篇介绍很详细
转载:http://www.360doc.com/content/15/1113/15/281812_512850806.shtml