ContainerImpl

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);
                }
            }
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值