protected <T> T doGetSingleton(Class<T> targetClass) throws ReflectiveOperationException {
// 第一次请求时,找不对相应的service,后面的请求会直接从singletonCache中获取
Object ret = singletonCache.get(targetClass);
if (ret != null) {
return (T)ret;
}
ret = singletonTl.get().get(targetClass);
System.out.println(singletonTl.get());
if (ret != null) { // 发现循环注入
return (T)ret;
}
synchronized (this) {
ret = singletonCache.get(targetClass);
if (ret == null) {
try {
ret = createObject(targetClass);
// TODO 未理解
// singletonTl.get().put(targetClass, ret);
// 此处递归调用 实现循环注入
doInject(targetClass, ret);
singletonCache.put(targetClass, ret);
} finally {
// singletonTl.remove();
}
}
}
return (T)ret;
}
这个 protected ThreadLocal<HashMap<Class<?>, Object>> singletonTl = ThreadLocal.withInitial(() -> new HashMap<>());
该如何理解比较好?是不是用于AService 注入了BService和CService,同时BService也注入了CService,则将CService缓存在这个singletonTl 中,用ThreadLocal包裹是为了提高并发?
此处的 ThreadLocal 仅用于检测循环注入的发生
最极端的循环注入是:A 注入 B,B 注入 A
你使用这种最极端的情况单步调试一下 jfinal 的这段代码,自然就清楚其原理了