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