jfinal源码-循环注入

	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包裹是为了提高并发?

评论区

JFinal

2019-06-03 10:01

A 注入 B,B 注入 C , C 再注入 A ,这样就形成了循环注入,jfinal 对这种情况是完美处理,没多注入一层,也没少注入一层

此处的 ThreadLocal 仅用于检测循环注入的发生

最极端的循环注入是:A 注入 B,B 注入 A

你使用这种最极端的情况单步调试一下 jfinal 的这段代码,自然就清楚其原理了

maxwade

2019-06-03 17:15

@JFinal 明白了,感谢。除非没仔细的情况下才会写出循环注入的代码

JFinal

2019-06-03 19:11

@maxwade jfinal 作为严肃认真的框架,必须考虑各种极端情况

maxwade

2019-06-05 08:26

@JFinal 那个ThreadLocal 包裹下HashMap, Object>有什么具体的作用吗?知道是线程内共享变量的意思。就像AdminAuthInterceptor中这样,
public static Account getThreadLocalAccount() {
return threadLocal.get();
}
然后在AdminAuthKit中使用这个。

JFinal

2019-06-05 09:41

@maxwade 这个你要再复习一下 java 基础,有关 ThreadLocal 的用法

复习完以后,再单步调式这段代码才可以理解。 看源码是静态的,不知道其动态行为,单步调试可以看到动态行为

热门反馈

扫码入社