com.opensymphony.xwork2.inject.util.ReferenceCache
com.opensymphony.xwork2.inject.util.ReferenceMap
前者继承自后者。
public class ReferenceMap implements Map, Serializable {
private static final long serialVersionUID = 0;
transient ConcurrentMap
三个实例变量中,ReferenceType牵扯到什么弱引用,软引用咱们暂时不管。
public abstract class ReferenceCache extends ReferenceMap {
private static final long serialVersionUID = 0;
transient ConcurrentMap
关于ThreadLocal的知识,大家可以参阅拙作
public V get(final Object key) {
ensureNotNull(key);
return internalGet((K) key);
}
ensureNotNull看名字就知道是干什么的了。
V internalGet(K key) {
Object valueReference = delegate.get(makeKeyReferenceAware(key));//标识1
return valueReference == null
? null
: (V) dereferenceValue(valueReference);
}
关于makeKeyReferenceAware是干什么的,我只能说和强引用(STRONG)、弱引用(WEAK)、软引用(SOFT),最后一种幽灵引用(PHANTON)相关,它们有什么区别,我不清楚。不过我觉得这里不是重点。
@Override public V get(final Object key) {
V value = super.get(key); //标识2
return (value == null)
? internalCreate((K) key) //标识9
: value;
}
标识2处最终调用的是ReferenceMap的internalGet方法,第一回肯定为null,我们看internalCreate方法。
V internalCreate(K key) {
try {
FutureTask futureTask = new FutureTask(
new CallableCreate(key));
// use a reference so we get the same equality semantics.
Object keyReference = referenceKey(key); //referenceKey方法大家就当没看见
Future future = futures.putIfAbsent(keyReference, futureTask); //标识4
if (future == null) {
// winning thread.
try {
//localFuture在这里到底扮演什么角色
//到现在我也没有看明白
if (localFuture.get() != null) {
throw new IllegalStateException(
"Nested creations within the same cache are not allowed.");
}
localFuture.set(futureTask);
futureTask.run(); //标识3
V value = futureTask.get(); //标识5
putStrategy().execute(this, //标识7
keyReference, referenceValue(keyReference, value));
return value;
} finally {
localFuture.remove();
futures.remove(keyReference);
}
} else {
// wait for winning thread.
return future.get();
}//省略catch
}
}
另外多说一句废话
对于线程来说,直接调用run方法就没有线程的效果,就相当于函数调用,而对futureTask而言,调用run方法就是启动线程并调用call方法。
标识4处调用了ConcurrentHashMap的putIfAbsent。 if (!map.containsKey(key))
return map.put(key, value);
else
return map.get(key);
看一个小例子
public class ConcurrentHashMapTest {
public static void main(String[] args) {
ConcurrentHashMap chm=new ConcurrentHashMap();
People p=new People();
System.out.println(chm.putIfAbsent(p, "1"));
System.out.println(chm.putIfAbsent(p, "2"));
System.out.println(chm.get(p));
}
}
class People{
String name;
String age;
}
运行结果为
class CallableCreate implements Callable {
K key;
public CallableCreate(K key) {
this.key = key;
}
public V call() {
// try one more time (a previous future could have come and gone.)
V value = internalGet(key); //在父类的delegate里面找
if (value != null) {
return value;
}
// create value.
value = create(key); //标识6
if (value == null) {
throw new NullPointerException(
"create(K) returned null for: " + key);
}
return value;
}
}
internalGet被定义在ReferenceMap中。上文已经说过。就是在delegate里面找。
ok,到现在我们就得引入本文标题中的Injector了。
final Map, List> injectors =
new ReferenceCache, List>() {
@Override
protected List create( Class> key ) {
List injectors = new ArrayList();
addInjectors(key, injectors);
return injectors;
}
};
OK creat里返回的是存在与这个key(其实就是一个类)上面的所有注入器。
void inject( Object o, InternalContext context ) {
List injectors = this.injectors.get(o.getClass());
for ( Injector injector : injectors ) {
injector.inject(context, o);
}
}
putStrategy().execute(this,keyReference, referenceValue(keyReference, value));
protected interface Strategy {
public Object execute(ReferenceMap map, Object keyReference,
Object valueReference);
}
protected Strategy putStrategy() {
return PutStrategy.PUT; //直接放
}
protected Strategy putIfAbsentStrategy() {
return PutStrategy.PUT_IF_ABSENT; //不存在时才放
}
protected Strategy replaceStrategy() {
return PutStrategy.REPLACE; //替换
}
//枚举类 存放数据有三种方式 PUT PUT_IF_ABSENT REPLACE
private enum PutStrategy implements Strategy {
PUT {
public Object execute(ReferenceMap map, Object keyReference,
Object valueReference) {
return map.delegate.put(keyReference, valueReference);
}
},
REPLACE {
public Object execute(ReferenceMap map, Object keyReference,
Object valueReference) {
return map.delegate.replace(keyReference, valueReference);
}
},
PUT_IF_ABSENT {
public Object execute(ReferenceMap map, Object keyReference,
Object valueReference) {
return map.delegate.putIfAbsent(keyReference, valueReference);
}
};
};
map.delegate.put(keyReference, valueReference);
map就是ReferenceMap。
Future future = futures.putIfAbsent(keyReference, futureTask);
future什么时候不等于null?
这篇文章,只能说是引大家入门而已。
感谢glt