// ContainerImpl 中定义的静态内部类
/**
* Injects a field or method in a given object.
*/
interface Injector extends Serializable {
void inject(InternalContext context, Object o);
}
static class MissingDependencyException extends Exception {
MissingDependencyException(String message) {
super(message);
}
}
// 一些Injector 的实现类
static class FieldInjector implements Injector {
final Field field;
final InternalFactory<?> factory;
final ExternalContext<?> externalContext;
public FieldInjector(ContainerImpl container, Field field, String name)
throws MissingDependencyException {
this.field = field;
field.setAccessible(true);// 此处貌似都是有必要的
//不使用构造函数是因为 Key类中构造函数定义为private
Key<?> key = Key.newInstance(field.getType(), name);
factory = container.getFactory(key);//注意传入ContainerImpl呀!
if (factory == null) {
throw new MissingDependencyException(
"No mapping found for dependency " + key + " in " + field + ".");
}
//不使用构造函数不知道为何了?????
this.externalContext = ExternalContext.newInstance(field, key, container);
}
// 此处是核心关键调用的方法
public void inject(InternalContext context, Object o) {
ExternalContext<?> previous = context.getExternalContext();
context.setExternalContext(externalContext);
try {
// 将指定对象变量上(o)此 Field 对象表示的字段设置为指定的新值(param2)。
field.set(o, factory.create(context));
} catch (IllegalAccessException e) {
throw new AssertionError(e);
} finally {
// 此处谁能告诉我是干什么的?
context.setExternalContext(previous);
}
}
}
//
static class ParameterInjector<T> {
final ExternalContext<T> externalContext;
final InternalFactory<? extends T> factory;
public ParameterInjector(ExternalContext<T> externalContext,
InternalFactory<? extends T> factory) {
this.externalContext = externalContext;
this.factory = factory;
}
//member 反映有关单个成员(字段或方法)或构造方法的标识信息。
T inject(Member member, InternalContext context) {
ExternalContext<?> previous = context.getExternalContext();
context.setExternalContext(externalContext);
try {
return factory.create(context);
} finally { // 此处又来了
context.setExternalContext(previous);
}
}
}
static class ConstructorInjector<T> {
final Class<T> implementation;
final List<Injector> injectors;
final Constructor<T> constructor;
final ParameterInjector<?>[] parameterInjectors;
ConstructorInjector(ContainerImpl container, Class<T> implementation) {
this.implementation = implementation;
//内部类提供的内部方法
constructor = findConstructorIn(implementation);
constructor.setAccessible(true); //也来了
try {
Inject inject = constructor.getAnnotation(Inject.class);
parameterInjectors = inject == null
? null // default constructor.
: container.getParametersInjectors(
constructor,
constructor.getParameterAnnotations(),
constructor.getParameterTypes(),
inject.value()
);
} catch (MissingDependencyException e) {
throw new DependencyException(e);
}
injectors = container.injectors.get(implementation);
}
//内部类中提供的方法
@SuppressWarnings("unchecked")
private Constructor<T> findConstructorIn(Class<T> implementation) {
Constructor<T> found = null;
Constructor<T>[] declaredConstructors = (Constructor<T>[]) implementation.getDeclaredConstructors();
for(Constructor<T> constructor : declaredConstructors) {
if (constructor.getAnnotation(Inject.class) != null) {
if (found != null) {
throw new DependencyException("More than one constructor annotated"
+ " with @Inject found in " + implementation + ".");
}
found = constructor;
}
}
if (found != null) {
return found;
}
// If no annotated constructor is found, look for a no-arg constructor
// instead.
try {
return implementation.getDeclaredConstructor();
} catch (NoSuchMethodException e) {
throw new DependencyException("Could not find a suitable constructor"
+ " in " + implementation.getName() + ".");
}
}
/**
* Construct an instance. Returns {@code Object} instead of {@code T}
* because it may return a proxy.
*/
Object construct(InternalContext context, Class<? super T> expectedType) {
ConstructionContext<T> constructionContext =
context.getConstructionContext(this);
// We have a circular reference between constructors. Return a proxy.
if (constructionContext.isConstructing()) {
// TODO (crazybob): if we can't proxy this object, can we proxy the
// other object?
return constructionContext.createProxy(expectedType);
}
// If we're re-entering this factory while injecting fields or methods,
// return the same instance. This prevents infinite loops.
T t = constructionContext.getCurrentReference();
if (t != null) {
return t;
}
try {
// First time through...
constructionContext.startConstruction();
try {
Object[] parameters =
getParameters(constructor, context, parameterInjectors);
t = constructor.newInstance(parameters);
constructionContext.setProxyDelegates(t);
} finally {
constructionContext.finishConstruction();
}
// Store reference. If an injector re-enters this factory, they'll
// get the same reference.
constructionContext.setCurrentReference(t);
// Inject fields and methods.
for (Injector injector : injectors) {
injector.inject(context, t);
}
return t;
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} finally {
constructionContext.removeCurrentReference();
}
}
}
// Container接口实现类中需要 重要的变量定义和方法定义
ThreadLocal<Object[]> localContext = new ThreadLocal<Object[]>() {
protected InternalContext[] initialValue() {
return new InternalContext[1];
}
};
/**
* Looks up thread local context. Creates (and removes) a new context if
* necessary.
*/
<T> T callInContext(ContextualCallable<T> callable) {
InternalContext[] reference = (InternalContext[]) localContext.get();
if (reference[0] == null) {
reference[0] = new InternalContext(this);
try {
return callable.call(reference[0]);
} finally {
// Only remove the context if this call created it.
reference[0] = null;
}
} else {
// Someone else will clean up this context.
return callable.call(reference[0]);
}
}
// 注意此处的接口定义
interface ContextualCallable<T> {
T call(InternalContext context);
}