package com.opensymphony.xwork2.inject;
import com.opensymphony.xwork2.inject.util.ReferenceCache;
import java.lang.annotation.Annotation; import java.lang.reflect.AccessibleObject; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import java.io.Serializable;
class ContainerImpl implements Container {
final Map<Key<?>, InternalFactory<?>> factories; final Map<Class<?>, Set<String>> factoryNamesByType;
ContainerImpl(Map<Key<?>, InternalFactory<?>> factories) { this.factories = factories; Map<Class<?>, Set<String>> map = new HashMap<Class<?>, Set<String>>(); for (Key<?> key :factories.keySet()) { Set<String> names = map.get(key.getType()); if (names == null) { names = new HashSet<String>(); map.put(key.getType(), names); } names.add(key.getName()); } for (Entry<Class<?>, Set<String>> entry : map.entrySet()) { entry.setValue(Collections.unmodifiableSet(entry.getValue())); } this.factoryNamesByType = Collections.unmodifiableMap(map); }
@SuppressWarnings("unchecked")<T> InternalFactory<? extends T> getFactory(Key<T> key) { return (InternalFactory<T>) factories.get(key); }
/** * Field and method injectors. */ //injector.get(Test.class)就会去执行这些方法 //factoryNamesByType和factories是有了的 final Map<Class<?>, List<Injector>> injectors = new ReferenceCache<Class<?>, List<Injector>>() { protected List<Injector> create(Class<?> key) { List<Injector> injectors = new ArrayList<Injector>(); addInjectors(key, injectors); return injectors; } };
/** * Recursively adds injectors for fields and methods from the given class to * the given list. Injects parent classes before sub classes. * * 处理所有的不是static的,并含有@inject注释的属性和方法 * 并根据属性或者方法分别添加FieldInjector,MethodInjector,第三个参数为 * 注释中的value,并放在injectors * */ void addInjectors(Class clazz, List<Injector> injectors) { if (clazz == Object.class) { return; }
// Add injectors for superclass first. addInjectors(clazz.getSuperclass(), injectors);
// TODO (crazybob): Filter out overridden members. addInjectorsForFields(clazz.getDeclaredFields(), false, injectors); addInjectorsForMethods(clazz.getDeclaredMethods(), false, injectors); }
void injectStatics(List<Class<?>> staticInjections) { final List<Injector> injectors = new ArrayList<Injector>(); /* * 把staticInjections的所有类中含有@inject并且是static的属性和方法 * 并根据属性或者方法分别添加FieldInjector,MethodInjector,第三个参数为 * 注释中的value,并放在injectors * */for (Class<?> clazz : staticInjections) { addInjectorsForFields(clazz.getDeclaredFields(), true, injectors); addInjectorsForMethods(clazz.getDeclaredMethods(), true, injectors); } /* * callInContext方法就是执行ContextualCallable的call方法并把结果值返回 * * reference[0] = new InternalContext(this); return callable.call(reference[0]); * 在此处的context = new InteralContext(this); * */ callInContext(new ContextualCallable<Void>() { public Void call(InternalContext context) { for (Injector injector : injectors) { /* * 就让FieldInjector和MethodInjector来注入,因为是静态属性和方法,
所以第二 的一个参 数 * 为null * */ injector.inject(context, null); } return null; } }); }
void addInjectorsForMethods(Method[] methods, boolean statics, List<Injector> injectors) { addInjectorsForMembers(Arrays.asList(methods), statics, injectors, new InjectorFactory<Method>() { public Injector create(ContainerImpl container, Method method, String name) throws MissingDependencyException { return new MethodInjector(container, method, name); } }); }
void addInjectorsForFields(Field[] fields, boolean statics, List<Injector> injectors) { addInjectorsForMembers(Arrays.asList(fields), statics, injectors, new InjectorFactory<Field>() { public Injector create(ContainerImpl container, Field field, String name) throws MissingDependencyException { return new FieldInjector(container, field, name); } }); }
<M extends Member & AnnotatedElement> void addInjectorsForMembers( List<M> members, boolean statics /*false*/, List<Injector> injectors, InjectorFactory<M> injectorFactory) { for (M member : members) { if (isStatic(member) == statics) { Inject inject = member.getAnnotation(Inject.class); if (inject != null) { try { injectors.add(injectorFactory.create(this, member, inject.value())); } catch (MissingDependencyException e) { if (inject.required()) { throw new DependencyException(e); } } } } } }
interface InjectorFactory<M extends Member & AnnotatedElement> { Injector create(ContainerImpl container, M member, String name) throws MissingDependencyException; }
private boolean isStatic(Member member) { return Modifier.isStatic(member.getModifiers()); }
static class FieldInjector implements Injector {
final Field field; final InternalFactory<?> factory; final ExternalContext<?> externalContext;
public FieldInjector(ContainerImpl container /*this*/, Field field /*属性名*/, String name /*@inject中的value*/) throws MissingDependencyException { this.field = field; field.setAccessible(true);
Key<?> key = Key.newInstance(field.getType(), name); factory = container.getFactory(key); if (factory == null) { throw new MissingDependencyException("No mapping found for dependency " + key + "in " + field + "."); } this.externalContext = ExternalContext.newInstance( field, key, container); } /** inject(context,null); 在构造函数中初始化了externalContext,是为了factory.create(context) 调用中可 以 context.getExternalContext()方法来获得我其中的key值,再得到Key(里面 的是Fiel d和注入的值) 这里面用的容器都是一个,这里用到了ContainerImpl传进来的factories 这个地方不对啊factory = container.getFactory(key); 而key又一直不一样啊,因为name在变化啊 总之就是对此属性进行了重新赋值 */ public void inject(InternalContext context, Object o) { ExternalContext<?> previous = context.getExternalContext(); context.setExternalContext(externalContext); try { field.set(o, factory.create(context)); } catch (IllegalAccessException e) { throw new AssertionError(e); } finally { context.setExternalContext(previous); } } }
/** * Gets parameter injectors. * * @param member to which the parameters belong * @param annotations on the parameters * @param parameterTypes parameter types * @return injections */ <M extends AccessibleObject & Member> ParameterInjector<?>[] getParametersInjectors(M member, Annotation[][] annotations, Class[] parameterTypes, String defaultName /* 是member注入的value */) throws MissingDependencyException { List<ParameterInjector<?>> parameterInjectors = new ArrayList<ParameterInjector<?>>(); //得到每个参数的@Inject Iterator<Annotation[]> annotationsIterator = Arrays.asList(annotations).iterator(); for (Class<?> parameterType : parameterTypes) { Inject annotation = findInject(annotationsIterator.next()); String name = annotation == null ? defaultName : annotation.value(); Key<?> key = Key.newInstance(parameterType, name); parameterInjectors.add(createParameterInjector(key, member)); } return toArray(parameterInjectors); }
<T> ParameterInjector<T> createParameterInjector(Key<T> key, Member member) throws MissingDependencyException { InternalFactory<? extends T> factory = getFactory(key); if (factory == null) { throw new MissingDependencyException( "No mapping found for dependency " + key + " in " + member + "."); }
ExternalContext<T> externalContext = ExternalContext.newInstance(member, key, this); return new ParameterInjector<T>(externalContext, factory); }
@SuppressWarnings("unchecked")private ParameterInjector<?>[] toArray(List<ParameterInjector<?>> parameterInjections) { return parameterInjections.toArray(new ParameterInjector[ parameterInjections.size()]); }
/** * Finds the {@link Inject} annotation in an array of annotations. */ Inject findInject(Annotation[] annotations) { for (Annotation annotation : annotations) { if (annotation.annotationType() == Inject.class) { return Inject.class.cast(annotation); } } return null; }
static class MethodInjector implements Injector {
final Method method; final ParameterInjector<?>[] parameterInjectors; /* * MethodInjector构造函数对函数里面的参数进行注入 * */ public MethodInjector(ContainerImpl container, Method method, String name /* 是此method前面的值,比如: @Inject(value="woaiyan") public void test(@Inject(value="wo") String s){ } 则name就等于"woaiyan" */) throws MissingDependencyException { this.method = method; method.setAccessible(true);
Class<?> [] parameterTypes = method.getParameterTypes(); if (parameterTypes.length == 0) { /* * 如果只有@inject 而没有函数参数,当然应该抛出异常 * */throw new DependencyException(method + " has no parameters to inject."); } /* * 把每个参数的类型class和它前面的 @Inject的
value() 组成Key, method, 和th is 组合成ExteralContext * 然后再用factory = factories.get(Key) 得到InteralFactory, 来初始化ParameterInjector, 逐 个 * 加入数组. * * / parameterInjectors = container.getParametersInjectors( method, method.getParameterAnnotations(), parameterTypes, name); } /* * o = null,这种情况是静态方法 * */ public void inject(InternalContext context, Object o) { try { /* * getParameters 方法仍然象属性一样factory.create(context); * */method.invoke(o, getParameters(method, context, parameterInjectors)); } catch (Exception e) { throw new RuntimeException(e); } } } /* *
constructors.get(Test.class)就会去调create方法从而得到 * 一个new ConstructorInjector(ContainerImpl.this, class); * */ Map<Class<?>, ConstructorInjector> constructors = new ReferenceCache<Class<?>, ConstructorInjector>() { @SuppressWarnings("unchecked")protected ConstructorInjector<?> create(Class<?> implementation) { return new ConstructorInjector(ContainerImpl.this, implementation); } };
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; /* * * 去找implementation的构造函数,找到有@Inject的构造函数,但是如
果有两个@ Inject的 构造函数的话则抛出异常 * 否则返回默认的构造
函数 */constructor = findConstructorIn(implementation); constructor.setAccessible(true);
MissingDependencyException exception = null; Inject inject = null; ParameterInjector<?> [] parameters = null; try { //当没有@Inject注释的构造函数时,inject = null; inject = constructor.getAnnotation(Inject.class); //如果有@Inject的话.和Method差不多 parameters = constructParameterInjector(inject, container, constructor); } catch (MissingDependencyException e) { exception = e; } parameterInjectors = parameters;
if (exception != null) { if (inject != null && inject.required()) { throw new DependencyException(exception); } } //把属性方法的注入器也加进injectors injectors = container.injectors.get(implementation); }
ParameterInjector<?>[] constructParameterInjector(Inject inject, ContainerImpl container, Constructor<T> constructor) throws MissingDependencyException { return constructor.getParameterTypes().length == 0 ? null // default constructor. : container.getParametersInjectors( constructor, constructor.getParameterAnnotations(), constructor.getParameterTypes(), inject.value()); }
@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) { /* * 参数context容器是有了,ConstructionContext倒没有实例化,在这里进行实例 化,并返 回 * 实际上是执行了constructionContexts.put(this,constructionContext) * */ConstructionContext<T> constructionContext = context.getConstructionContext(this);
// We have a circular reference between constructors. Return a proxy. //如果正在建造,就创建一个代理,expectedType是接口 if (constructionContext.isConstructing()) { // TODO (crazybob):if we can 'tproxy 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(); } } }
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; }
T inject(Member member, InternalContext context) { ExternalContext<?> previous = context.getExternalContext(); context.setExternalContext(externalContext); try { return factory.create(context); } finally { context.setExternalContext(previous); } } }
private static Object[] getParameters(Member member, InternalContext context, ParameterInjector[] parameterInjectors) { if (parameterInjectors == null) { return null; }
Object[] parameters = new Object[parameterInjectors.length]; for (int i = 0; i < parameters.length; i++) { /* * 仍然是ExternalContext<?> previous = context.getExternalContext(); context.setExternalContext(externalContext); return factory.create(context); * */parameters[ i] = parameterInjectors[i].inject(member, context); } return parameters; } //注入Field和Method void inject(Object o,
InternalContext context) { List<Injector> injectors = this.injectors.get(o.getClass()); for (Injector injector : injectors) { injector.inject(context, o); } }
//注入整个对象并返回 <T> T inject(Class<T> implementation, InternalContext context) { try { ConstructorInjector<T> constructor = getConstructor(implementation); return implementation.cast(constructor.construct(context, implementation)); } catch (Exception e) { throw new RuntimeException(e); } } /* *
实际上是以type,name组成Key来找到InternalFactory * return getFactory(key).create(context); * */ @SuppressWarnings("unchecked")<T> T getInstance(Class<T> type, String name, InternalContext context) { ExternalContext<?> previous = context.getExternalContext(); Key<T> key = Key.newInstance(type, name); context.setExternalContext(ExternalContext.newInstance(null, key, this)); try { InternalFactory o = getFactory(key); if (o != null) { return getFactory(key).create(context); } else { return null; } } finally { context.setExternalContext(previous); } }
<T> T getInstance(Class<T> type, InternalContext context) { return getInstance(type, DEFAULT_NAME, context); }
public void inject(final Object o) { callInContext(new ContextualCallable<Void>() { public Void call(InternalContext context) { inject(o, context); return null; } }); }
public <T> T inject(final Class<T> implementation) { return callInContext(new ContextualCallable<T>() { public T call(InternalContext context) { return inject(implementation, context); } }); }
public <T> T getInstance(final Class<T> type, final String name) { return callInContext(new ContextualCallable<T>() { public T call(InternalContext context) { return getInstance(type, name, context); } }); }
public <T> T getInstance(final Class<T> type) { return callInContext(new ContextualCallable<T>() { public T call(InternalContext context) { return getInstance(type, context); } }); }
public Set<String> getInstanceNames(final Class<?> type) { return factoryNamesByType.get(type); } /* * 相当于localContext.set(new
InternalContext[1]); * */ 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. * * 这个方法就是调用接口ContextualCallable的call方法并返回对象. */ <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); }
/** * Gets a constructor function for a given implementation class. */ @SuppressWarnings("unchecked")<T> ConstructorInjector<T> getConstructor(Class<T> implementation) { return constructors.get(implementation); }
final ThreadLocal<Object> localScopeStrategy = new ThreadLocal<Object>();
public void setScopeStrategy(Scope.Strategy scopeStrategy) { this.localScopeStrategy.set(scopeStrategy); }
public void removeScopeStrategy() { this.localScopeStrategy.remove(); }
/** * 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); } } }