struts2_源碼學習_Container

續 Dispatcher(1) 

(PS:我終於搞明白 一點了 T-T  參考文章:https://www.cnblogs.com/huashui/p/3191886.html

目錄

Container接口

對象的注入依賴

對象注入的實例

獲取對象實例 


Container接口

package com.opensymphony.xwork2.inject;

public interface Container extends Serializable {
    //默認對象識別標誌
    String DEFAULT_NAME = "default";
    //進行對象的依賴注入操作。o爲被注入對象的對象。意思就是完成o中@inject操作
    void inject(Object var1);
    //創建一個類的實例並進行對象的依賴注入操作
    <T> T inject(Class<T> var1);
    //通過type和name獲得實例
    <T> T getInstance(Class<T> var1, String var2);
    //通過type和默認的name獲得對象
    <T> T getInstance(Class<T> var1);
    //根據type獲取與這個type所對應的容器中的所有註冊過的name。
    Set<String> getInstanceNames(Class<?> var1);
    //設置當前線程的作用範圍的策略。
    void setScopeStrategy(Strategy var1);
    //刪除當前線程的作用範圍的策略。
    void removeScopeStrategy();
}

從Container的源代碼可以看出,容器的作用有以下三點:

①,獲取對象實例。

②,對象的依賴注入。

③,處理對象的作用範圍策略。

其中最重要的是第一點和第二點。那麼,我們可以通過Container來獲取對象的實例,具體來說,哪些實例我們可以獲取到呢?

其實我們獲取的是xml配置文件中的bean節點的對象和constant節點的參數。

我們來看官方文檔對bean節點的解釋:

從官方的解釋可以看出,bean是被框架的容器創建的,並且被容器注入到框架內部對象中去。

其實從命名就可以看出來,inject就是注入的意思。當我們把某個對象實例作爲參數傳入到inject方法中時,框架會掃描該對象內部聲明有@Inject註解的字段,方法,構造函數或者是方法參數,並將它們注入容器中的管理對象。

因此,所謂struts2的依賴注入其實就是在需要被注入的字段,方法,構造函數或者方法參數上加上@Inject註解就可以了。

對象的注入依賴

具體進入ContainerImpl這個類看看,具體的實現我們就不細說了,看看關於injector和@inject主要的幾個方法和字段,弄明白爲什麼。(這對我來說已經很吃力了。)

package com.opensymphony.xwork2.inject;

class ContainerImpl implements Container {
    //Key存儲的是<bean>中對應的type和name,InternalFactory可以理解爲工廠
    final Map<Key<?>, InternalFactory<?>> factories;
    //存儲tpye-names的映射
    final Map<Class<?>, Set<String>> factoryNamesByType;
    //注入器,可以注意到使用了ReferenceCache作爲緩存。具體的create方法之後說明
    final Map<Class<?>, List<ContainerImpl.Injector>> injectors = new ReferenceCache<Class<?>, List<ContainerImpl.Injector>>() {
        protected List<ContainerImpl.Injector> create(Class<?> key) {
            List<ContainerImpl.Injector> injectors = new ArrayList();
            ContainerImpl.this.addInjectors(key, injectors);
            return injectors;
        }
    };
    //構造方法上的注入器
    Map<Class<?>, ContainerImpl.ConstructorInjector> constructors = new ReferenceCache<Class<?>, ContainerImpl.ConstructorInjector>() {
        protected ContainerImpl.ConstructorInjector<?> create(Class<?> implementation) {
            return new ContainerImpl.ConstructorInjector(ContainerImpl.this, implementation);
        }
    };
    //ThreadLocal保證線程安全 一個是object數組、一個是object對象
    ThreadLocal<Object[]> localContext = new ThreadLocal<Object[]>() {
        protected Object[] initialValue() {
            return new Object[1];
        }
    };

    //構造函數,主要工作見註釋
    ContainerImpl(Map<Key<?>, InternalFactory<?>> factories) {
        this.factories = factories;
        Map<Class<?>, Set<String>> map = new HashMap();

        Iterator i$;
        Key key;
        Object names;
        //合併相同type不同name的類
        for(i$ = factories.keySet().iterator(); i$.hasNext(); ((Set)names).add(key.getName())) {
            key = (Key)i$.next();
            names = (Set)map.get(key.getType());
            if (names == null) {
                names = new HashSet();
                map.put(key.getType(), names);
            }
        }

        i$ = map.entrySet().iterator();

        while(i$.hasNext()) {
            Entry<Class<?>, Set<String>> entry = (Entry)i$.next();
            //不可更改的集合
            entry.setValue(Collections.unmodifiableSet((Set)entry.getValue()));
        }
        //不可更改的k-v
        this.factoryNamesByType = Collections.unmodifiableMap(map);
    }

    //添加註入器,遞歸調用,最終要調用到addInjectorsForMembers(..)
    void addInjectors(Class clazz, List<ContainerImpl.Injector> injectors) {
        if (clazz != Object.class) {
            this.addInjectors(clazz.getSuperclass(), injectors);
            //字段的注入器,即@inject註解作用的字段
            this.addInjectorsForFields(clazz.getDeclaredFields(), false, injectors);
            this.addInjectorsForMethods(clazz.getDeclaredMethods(), false, injectors);
        }
    }
 
    //方法上的@inject注入器
    void addInjectorsForMethods(Method[] methods, boolean statics, List<ContainerImpl.Injector> injectors) {
        //最終調用的放法
        this.addInjectorsForMembers(Arrays.asList(methods), statics, injectors, new ContainerImpl.InjectorFactory<Method>() {
            public ContainerImpl.Injector create(ContainerImpl container, Method method, String name) throws ContainerImpl.MissingDependencyException {
                return new ContainerImpl.MethodInjector(container, method, name);
            }
        });
    }
    //字段上的@inject注入器
    void addInjectorsForFields(Field[] fields, boolean statics, List<ContainerImpl.Injector> injectors) {
        this.addInjectorsForMembers(Arrays.asList(fields), statics, injectors, new ContainerImpl.InjectorFactory<Field>() {
            public ContainerImpl.Injector create(ContainerImpl container, Field field, String name) throws ContainerImpl.MissingDependencyException {
                return new ContainerImpl.FieldInjector(container, field, name);
            }
        });
    }
    //添加註入器成員,加入injectors中
    <M extends Member & AnnotatedElement> void addInjectorsForMembers(List<M> members, boolean statics, List<ContainerImpl.Injector> injectors, ContainerImpl.InjectorFactory<M> injectorFactory) {
        Iterator i$ = members.iterator();

        while(true) {
            Member member;
            Inject inject;
            do {
                do {
                    if (!i$.hasNext()) {
                        return;
                    }

                    member = (Member)i$.next();
                } while(this.isStatic(member) != statics);

                inject = (Inject)((AnnotatedElement)member).getAnnotation(Inject.class);
            } while(inject == null);

            try {
                injectors.add(injectorFactory.create(this, member, inject.value()));
            } catch (ContainerImpl.MissingDependencyException var9) {
                if (inject.required()) {
                    throw new DependencyException(var9);
                }
            }
        }
    }

    //獲得方法參數的注入器
    <M extends AccessibleObject & Member> ContainerImpl.ParameterInjector<?>[] getParametersInjectors(M member, Annotation[][] annotations, Class[] parameterTypes, String defaultName) throws ContainerImpl.MissingDependencyException {
        
    }
    //生成方法參數的注入器
    <T> ContainerImpl.ParameterInjector<T> createParameterInjector(Key<T> key, Member member) throws ContainerImpl.MissingDependencyException {
        
    }

    //獲得被注入對象的實例,依次調用了ParameterInjector類的inject方法,注意到它並沒實現Injector接口
    private static Object[] getParameters(Member member, InternalContext context, ContainerImpl.ParameterInjector[] parameterInjectors) {
        if (parameterInjectors == null) {
            return null;
        } else {
            Object[] parameters = new Object[parameterInjectors.length];

            for(int i = 0; i < parameters.length; ++i) {
                //需要注入的方法參數的值
                parameters[i] = parameterInjectors[i].inject(member, context);
            }

            return parameters;
        }

    }
    //完成對象o的依賴注入操作的對外接口
    public void inject(final Object o) {
        this.callInContext(new ContainerImpl.ContextualCallable<Void>() {
            public Void call(InternalContext context) {
                //內部實現的具體方法
                ContainerImpl.this.inject(o, context);
                return null;
            }
        });
    }
    //內部實現的具體方法
    void inject(Object o, InternalContext context) {
        //獲得注入對象o相同class的注入器
        List<ContainerImpl.Injector> injectors = (List)this.injectors.get(o.getClass());
        Iterator i$ = injectors.iterator();
        //將該對象o通過注入器注入
        while(i$.hasNext()) {
            ContainerImpl.Injector injector = (ContainerImpl.Injector)i$.next();
            //這裏我們可以看看具體的injector注入器類的inject方法
            injector.inject(context, o);
        }

    }
    //創建一個類的實例並進行對象的依賴注入操作,這裏就和構造函數有關了
    public <T> T inject(final Class<T> implementation) {
        return this.callInContext(new ContainerImpl.ContextualCallable<T>() {
            public T call(InternalContext context) {
                return ContainerImpl.this.inject(implementation, context);
            }
        });
    }
    //內部實現
    <T> T inject(Class<T> implementation, InternalContext context) {
        try {
            //獲得該class的構造器
            ContainerImpl.ConstructorInjector<T> constructor = this.getConstructor(implementation);
            return implementation.cast(constructor.construct(context, implementation));
        } catch (Exception var4) {
            throw new RuntimeException(var4);
        }
    }
    //這個類我還不太清楚什麼作用,請求的上下文?
    <T> T callInContext(ContainerImpl.ContextualCallable<T> callable) {
        Object[] reference = (Object[])this.localContext.get();
        if (reference[0] == null) {
            reference[0] = new InternalContext(this);

            Object var3;
            try {
                //一般會執行這一句
                var3 = callable.call((InternalContext)reference[0]);
            } finally {
                reference[0] = null;
                this.localContext.remove();
            }

            return var3;
        } else {
            return callable.call((InternalContext)reference[0]);
        }
    }
    //注入器統一的接口
    interface Injector extends Serializable {
        void inject(InternalContext var1, Object var2);
    }

    interface ContextualCallable<T> {
        T call(InternalContext var1);
    }
    //字段注入器
    static class FieldInjector implements ContainerImpl.Injector {}

    //方法注入器
    static class MethodInjector implements ContainerImpl.Injector {}

    //參數注入器
    static class ParameterInjector<T> {}

    //構造方法注入器
    static class ConstructorInjector<T> {}
    
    interface InjectorFactory<M extends Member & AnnotatedElement> {
        ContainerImpl.Injector create(ContainerImpl var1, M var2, String var3) throws ContainerImpl.MissingDependencyException;
    }
}

 以上的代碼雖然做了註解,但是我在關於構造方法上的注入器的具體實現還是不太明白,特別是construct(...)方法,暫時放放,總結一下大概是如何實現的:

字段注入器:關鍵的類就是:ContainerImpl.FieldInjector,一個FieldInjector保存的就是一個需要注入(被@inject註解)的字段信息,這裏就是反射應用的最好體現了,一切操作都是在程序運行過程完成的。inject()方法完成了對了字段的注入操作。

//字段注入器
    static class FieldInjector implements ContainerImpl.Injector {
        //保存了該字段
        final Field field;
        //字段工廠
        final InternalFactory<?> factory;
        final ExternalContext<?> externalContext;

        public FieldInjector(ContainerImpl container, Field field, String name) throws ContainerImpl.MissingDependencyException {
            this.field = field;
            //修改可見性
            if (!field.isAccessible()) {
                SecurityManager sm = System.getSecurityManager();

                try {
                    if (sm != null) {
                        sm.checkPermission(new ReflectPermission("suppressAccessChecks"));
                    }

                    field.setAccessible(true);
                } catch (AccessControlException var6) {
                    throw new DependencyException("Security manager in use, could not access field: " + field.getDeclaringClass().getName() + "(" + field.getName() + ")", var6);
                }
            }
            //保存信息
            Key<?> key = Key.newInstance(field.getType(), name);
            this.factory = container.getFactory(key);
            if (this.factory == null) {
                throw new ContainerImpl.MissingDependencyException("No mapping found for dependency " + key + " in " + field + ".");
            } else {
                this.externalContext = ExternalContext.newInstance(field, key, container);
            }
        }
        //字段注入可能比較好理解
        public void inject(InternalContext context, Object o) {
            ExternalContext<?> previous = context.getExternalContext();
            context.setExternalContext(this.externalContext);
            //將對象注入給field的
            try {
                this.field.set(o, this.factory.create(context));
            } catch (IllegalAccessException var8) {
                throw new AssertionError(var8);
            } finally {
                context.setExternalContext(previous);
            }

        }
    }

方法注入器,關注到的ContainerImpl.MethodInjector,一個MethodInjector保存一個方法以及方法上需要注入的參數(參數注入器)。主要的inject()方法調用對象o的method,並將參數注入,其中getParameters()是獲得需要注入的參數的值

    //方法注入器
    static class MethodInjector implements ContainerImpl.Injector {
        //保存了該方法
        final Method method;
        //方法的參數,主要是要注入參數
        final ContainerImpl.ParameterInjector<?>[] parameterInjectors;

        public MethodInjector(ContainerImpl container, Method method, String name) throws ContainerImpl.MissingDependencyException {
            this.method = method;
            if (!method.isAccessible()) {
                SecurityManager sm = System.getSecurityManager();

                try {
                    if (sm != null) {
                        sm.checkPermission(new ReflectPermission("suppressAccessChecks"));
                    }

                    method.setAccessible(true);
                } catch (AccessControlException var6) {
                    throw new DependencyException("Security manager in use, could not access method: " + name + "(" + method.getName() + ")", var6);
                }
            }
            //獲得方法參數
            Class<?>[] parameterTypes = method.getParameterTypes();
            if (parameterTypes.length == 0) {
                throw new DependencyException(method + " has no parameters to inject.");
            } else {
                //獲得方法參數的注入器
                this.parameterInjectors = container.getParametersInjectors(method, method.getParameterAnnotations(), parameterTypes, name);
            }
        }

        public void inject(InternalContext context, Object o) {
            try {
                //調用對象o的method,並將參數注入,所以getParameters獲得需要注入的參數的實例
                //相當於o.method(ContainerImpl.getParameters(this.method, context, this.parameterInjectors))
                this.method.invoke(o, ContainerImpl.getParameters(this.method, context, this.parameterInjectors));
            } catch (Exception var4) {
                throw new RuntimeException(var4);
            }
        }
    }

 參數注入器:保存的參數的信息。注意到的是這個ParameterInjector並沒有實現Injector接口,它的inject()方法發生在:

    private static Object[] getParameters(Member member, InternalContext context, ContainerImpl.ParameterInjector[] parameterInjectors) {
        if (parameterInjectors == null) {
            return null;
        } else {
            Object[] parameters = new Object[parameterInjectors.length];
            //獲得需要注入的參數的實例,依次調用了ParameterInjector類的inject方法,注意到它並沒實現Injector接口
            for(int i = 0; i < parameters.length; ++i) {
                parameters[i] = parameterInjectors[i].inject(member, context);
            }

            return parameters;
        }
    }

而getParameters()方法發生在方法注入器的inject()和構造器注入器的construct()中,傳入的member分別是method(Method)和construct(Construct)。所以總結下來inject()返回了注入參數的實例

    //參數注入器
    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(this.externalContext);

            Object var4;
            try {
                //生成注入參數的實例
                var4 = this.factory.create(context);
            } finally {
                context.setExternalContext(previous);
            }

            return var4;
        }
    }

 構造器注入器:這個ConstructorInjector也沒有實現Injector接口。主要的方法就是 findConstructorIn(...)找到帶@inject註解的構造器,constructorParameterInjector(...)返回需要注入參數的參數注入器。關於construct(...)我們需要從它的作用地方推測一下:

    <T> T inject(Class<T> implementation, InternalContext context) {
        try {
            ContainerImpl.ConstructorInjector<T> constructor = this.getConstructor(implementation);
            return implementation.cast(constructor.construct(context, implementation));
        } catch (Exception var4) {
            throw new RuntimeException(var4);
        }
    }

前面代碼我們提到的這個方法的作用(見註釋),我們先看一下第一句:getConstruct(implementation)

    <T> ContainerImpl.ConstructorInjector<T> getConstructor(Class<T> implementation) {
        return (ContainerImpl.ConstructorInjector)this.constructors.get(implementation);
    }

    Map<Class<?>, ContainerImpl.ConstructorInjector> constructors = new ReferenceCache<Class<?>, ContainerImpl.ConstructorInjector>() {
        protected ContainerImpl.ConstructorInjector<?> create(Class<?> implementation) {
            return new ContainerImpl.ConstructorInjector(ContainerImpl.this, implementation);
        }
    };

這裏會涉及到關於ReferenceCache和它的父類ReferenceMap的相關知識,我們在只說明一下get操作的結果:當獲取不到相應的注入器時,就會帶到了create()方法,於是調用到了ConstructorInjector的構造器。那麼類似於方法構造器,這裏就會生成完整的一個構造注入器。


注意:下面語句也是同樣的道理。

    //內部實現的具體方法
    void inject(Object o, InternalContext context) {
...
        List<ContainerImpl.Injector> injectors = (List)this.injectors.get(o.getClass());
...
    }

return implementation.cast(constructor.construct(context, implementation));

 這一句應該就是完成對象的創建和依賴部分的注入了。 

 
    //構造方法注入器
    static class ConstructorInjector<T> {
        //class
        final Class<T> implementation;
        final List<ContainerImpl.Injector> injectors;
        //構造方法
        final Constructor<T> constructor;
        //參數注入器
        final ContainerImpl.ParameterInjector<?>[] parameterInjectors;
        //
        ConstructorInjector(ContainerImpl container, Class<T> implementation) {
            this.implementation = implementation;
            //找到帶@inject註解的構造器
            this.constructor = this.findConstructorIn(implementation);
            //修改可達性
            if (!this.constructor.isAccessible()) {
                SecurityManager sm = System.getSecurityManager();

                try {
                    if (sm != null) {
                        sm.checkPermission(new ReflectPermission("suppressAccessChecks"));
                    }

                    this.constructor.setAccessible(true);
                } catch (AccessControlException var8) {
                    throw new DependencyException("Security manager in use, could not access constructor: " + implementation.getName() + "(" + this.constructor.getName() + ")", var8);
                }
            }

            ContainerImpl.MissingDependencyException exception = null;
            Inject inject = null;
            ContainerImpl.ParameterInjector[] parameters = null;

            try {
                //獲取需要注入的參數
                inject = (Inject)this.constructor.getAnnotation(Inject.class);
                parameters = this.constructParameterInjector(inject, container, this.constructor);
            } catch (ContainerImpl.MissingDependencyException var7) {
                exception = var7;
            }

            this.parameterInjectors = parameters;
            if (exception != null && inject != null && inject.required()) {
                throw new DependencyException(exception);
            } else {
                this.injectors = (List)container.injectors.get(implementation);
            }
        }
        //找到@inject的參數
        ContainerImpl.ParameterInjector<?>[] constructParameterInjector(Inject inject, ContainerImpl container, Constructor<T> constructor) throws ContainerImpl.MissingDependencyException {
            return constructor.getParameterTypes().length == 0 ? null : container.getParametersInjectors(constructor, constructor.getParameterAnnotations(), constructor.getParameterTypes(), inject.value());
        }
        //找到帶註解@inject的構造器
        private Constructor<T> findConstructorIn(Class<T> implementation) {
            Constructor<T> found = null;
            Constructor<T>[] declaredConstructors = (Constructor[])implementation.getDeclaredConstructors();
            Constructor[] arr$ = declaredConstructors;
            int len$ = declaredConstructors.length;

            for(int i$ = 0; i$ < len$; ++i$) {
                Constructor<T> constructor = arr$[i$];
                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;
            } else {
                try {
                    return implementation.getDeclaredConstructor();
                } catch (NoSuchMethodException var8) {
                    throw new DependencyException("Could not find a suitable constructor in " + implementation.getName() + ".");
                }
            }
        }

    Object construct(InternalContext context, Class<? super T> expectedType) {
            ConstructionContext<T> constructionContext =         context.getConstructionContext(this);
            if (constructionContext.isConstructing()) {
                return constructionContext.createProxy(expectedType);
            } else {
                T t = constructionContext.getCurrentReference();
                if (t != null) {
                    return t;
                } else {
                    try {
                        constructionContext.startConstruction();

                        try {
                            Object[] parameters = ContainerImpl.getParameters(this.constructor, context, this.parameterInjectors);
                            //構造對象
                            t = this.constructor.newInstance(parameters);
                            constructionContext.setProxyDelegates(t);
                        } finally {
                            constructionContext.finishConstruction();
                        }

                        constructionContext.setCurrentReference(t);
                        Iterator i$ = this.injectors.iterator();
                        //完成依賴部分的注入
                        while(i$.hasNext()) {
                            ContainerImpl.Injector injector = (ContainerImpl.Injector)i$.next();
                            injector.inject(context, t);
                        }

                        Object var18 = t;
                        return var18;
                    } catch (IllegalAccessException | InvocationTargetException | InstantiationException var15) {
                        throw new RuntimeException(var15);
                    } finally {
                        constructionContext.removeCurrentReference();
                    }
                }
            }
        }
    }

對象注入的實例

//發生在DefaultConfiguration.reloadContainer()
//假設注入的對象是StrutsXmlConfigurationProvider

this.container.inject(containerProvider);

我們直接跳到起作用的方法中:

//其中o就是StrutsXmlConfigurationProvider
//暫時忽略context

    void inject(Object o, InternalContext context) {
        //這裏會獲得StrutsXmlConfigurationProvider中的注入器,也就是需要注入的地方,查看父類我們會發現兩個方法如下
        List<ContainerImpl.Injector> injectors = (List)this.injectors.get(o.getClass());
        Iterator i$ = injectors.iterator();

        while(i$.hasNext()) {
            //依次注入,這兩個是方法上的注入器
            ContainerImpl.Injector injector = (ContainerImpl.Injector)i$.next();
            injector.inject(context, o);
        }

    }

XmlConfigurationProvider

    @Inject
    public void setObjectFactory(ObjectFactory objectFactory) {
        this.objectFactory = objectFactory;
    }

    @Inject
    public void setFileManagerFactory(FileManagerFactory fileManagerFactory) {
        this.fileManager = fileManagerFactory.getFileManager();
    }

 那麼接下來應該會依次調用兩個方法的注入器:injector.inject(context,o)

MethodInjector.inject
        
        public void inject(InternalContext context, Object o) {
            try {
                //調用兩個方法
                this.method.invoke(o, ContainerImpl.getParameters(this.method, context, this.parameterInjectors));
            } catch (Exception var4) {
                throw new RuntimeException(var4);
            }
        }

 這裏就相當於,getParameters()就是獲得實例對象

o.setObjectFactory(ContainerImpl.getParameters(this.method, context, this.parameterInjectors))

那麼接下來的就不多贅述了,我們可以直接看ParamtersInjector.inject(),它會去create一個實例以供注入。

        T inject(Member member, InternalContext context) {
            ExternalContext<?> previous = context.getExternalContext();
            context.setExternalContext(this.externalContext);

            Object var4;
            try {
                //生成實例
                var4 = this.factory.create(context);
            } finally {
                context.setExternalContext(previous);
            }

            return var4;
        }

 

獲取對象實例 

這個似乎沒有什麼需要細說的地方,主要步驟就是通過type和name獲取內部工廠,然後生成對象。涉及到factories可以參考factories

    <T> InternalFactory<? extends T> getFactory(Key<T> key) {
        return (InternalFactory)this.factories.get(key);
    }

    <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((Member)null, key, this));

        Object var7;
        try {
            InternalFactory o = this.getFactory(key);
            if (o != null) {
                var7 = this.getFactory(key).create(context);
                return var7;
            }

            var7 = null;
        } finally {
            context.setExternalContext(previous);
        }

        return var7;
    }

    <T> T getInstance(Class<T> type, InternalContext context) {
        return this.getInstance(type, "default", context);
    }

關於Container的內容就暫時到這吧。還有存在很多不足的地方,希望慢慢也能快點理解改正。

下一篇:Dispatcher(2)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章