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 的这段代码,自然就清楚其原理了