8-spring源码3.2.18解读+spring技术内幕(IOC容器的依赖注入(反射+递归调用))

来源:互联网 发布:淘宝客cms源码 编辑:程序博客网 时间:2024/05/18 03:02

 

1、导读

以上对IOC容器的初始化过程做了详细的分析,这个初始化过程完成的主要工作是在IOC容器中建立BeanDefinition数据映射。再次过程中并没有对Bean依赖关系进行注入,接下来将分析一下IOC容器是怎么样对Bean的依赖关系进行注入的。

假设当前IOC容器已经载入了用户定义的Bean信息,开始分析依赖注入的原理。首先,注意到依赖注入的过程是用户第一次向IOC容器索要Bean时触发的,当然也有例外,也就是我们可以在BeanDefinition信息中通过控制lazy-init属性来让容器完成对Bean的预实例化。这个预实例化实际上也是一个完成依赖注入的过程,但它在初始化的过程中完成的。当用户想IOC容器索要Bean时,如BeanFactory中,有一个getBean接口的定义,这个接口的实现就是触发依赖注入发生的地方,下面我们将从DefaultListableBeanFactory的基类AbstractBeanFactory入手getBean的实现。

 

2、AbstractBeanFactory

 

//这里是对BeanFactory接口的实现,比如getBean接口方法

//这些getBean接口方法最终是通过调用doGetBean来实现的

public Object getBean(String name) throws BeansException {
    return this.doGetBean(name, (Class)null, (Object[])null, false);
}

public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
    return this.doGetBean(name, requiredType, (Object[])null, false);
}

public Object getBean(String name, Object... args) throws BeansException {
    return this.doGetBean(name, (Class)null, args, false);
}

public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
    return this.doGetBean(name, requiredType, args, false);
}

//这里是实际取得Bean的地方,也是触发依赖注入的地方
protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
    final String beanName = this.transformedBeanName(name);
   //先从缓存中取得Bean,处理那些已经被创建过的单例模式的Bean,对这种Bean的请求不需要重复的创建,直接返回即可

Object sharedInstance = this.getSingleton(beanName);
    Object bean;
    if(sharedInstance != null && args == null) {
        if(this.logger.isDebugEnabled()) {
            if(this.isSingletonCurrentlyInCreation(beanName)) {
                this.logger.debug("Returning eagerly cached instance of singleton bean \'" + beanName + "\' that is not fully initialized yet - a consequence of a circular reference");
            } else {
                this.logger.debug("Returning cached instance of singleton bean \'" + beanName + "\'");
            }
        }

   //这里的getObjectForBeanInstance完成的是FactoryBean的相关处理,以取得FactoryBean的生产结果。
        bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
    } else {
        if(this.isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

    //这里对IOC容器中的BeanDefinition是否存在进行检查,检查是否能在当前BeanFactory中取得需要的Bean,如果在当前的工厂中取不到,则到双亲BeanFactory中去取,如果双亲工厂取不到,那就顺着双亲BeanFactory链一直往上查找
        BeanFactory ex = this.getParentBeanFactory();
        if(ex != null && !this.containsBeanDefinition(beanName)) {
            String var24 = this.originalBeanName(name);
            if(args != null) {
                return ex.getBean(var24, args);
            }

            return ex.getBean(var24, requiredType);
        }

        if(!typeCheckOnly) {
            this.markBeanAsCreated(beanName);
        }

        try {

       //这里根据Bean的名字取得BeanDefinition
            final RootBeanDefinition ex1 = this.getMergedLocalBeanDefinition(beanName);
            this.checkMergedBeanDefinition(ex1, beanName, args);

       //获取当前Bean的所有依赖Bean,这样会触发getBean的递归调用,直到取到一个没有任何的依赖Bean为止
            String[] dependsOn = ex1.getDependsOn();
            String[] scopeName;
            if(dependsOn != null) {
                scopeName = dependsOn;
                int scope = dependsOn.length;

                for(int ex2 = 0; ex2 < scope; ++ex2) {
                    String dependsOnBean = scopeName[ex2];
                    this.getBean(dependsOnBean);
                    this.registerDependentBean(dependsOnBean, beanName);
                }
            }
//这里通过调用createBean方法创建Singleton bean的实例,这里有一个回调函数getObject,会在getSingleton中调用ObjectFactorycreateBean
            if(ex1.isSingleton()) {
                sharedInstance = this.getSingleton(beanName, new ObjectFactory() {
                    public Object getObject() throws BeansException {
                        try {
                            return AbstractBeanFactory.this.createBean(beanName, ex1, args);
                        } catch (BeansException var2) {
                            AbstractBeanFactory.this.destroySingleton(beanName);
                            throw var2;
                        }
                    }
                });
                bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, ex1);
            } else if(ex1.isPrototype()) {//这里是创建prototype bean的地方
                scopeName = null;

                Object var25;
                try {
                    this.beforePrototypeCreation(beanName);
                    var25 = this.createBean(beanName, ex1, args);
                } finally {
                    this.afterPrototypeCreation(beanName);
                }

                bean = this.getObjectForBeanInstance(var25, name, beanName, ex1);
            } else {
                String var26 = ex1.getScope();
                Scope var27 = (Scope)this.scopes.get(var26);
                if(var27 == null) {
                    throw new IllegalStateException("No Scope registered for scope \'" + var26 + "\'");
                }

                try {
                    Object var28 = var27.get(beanName, new ObjectFactory() {
                        public Object getObject() throws BeansException {
                            AbstractBeanFactory.this.beforePrototypeCreation(beanName);

                            Object var1;
                            try {
                                var1 = AbstractBeanFactory.this.createBean(beanName, ex1, args);
                            } finally {
                                AbstractBeanFactory.this.afterPrototypeCreation(beanName);
                            }

                            return var1;
                        }
                    });
                    bean = this.getObjectForBeanInstance(var28, name, beanName, ex1);
                } catch (IllegalStateException var21) {
                    throw new BeanCreationException(beanName, "Scope \'" + var26 + "\' is not active for the current thread; " + "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var21);
                }
            }
        } catch (BeansException var23) {
            this.cleanupAfterBeanCreationFailure(beanName);
            throw var23;
        }
    }
   //这里包含了对Bean类型检查,如果没有问题,则返回这个新创建的bean,这个bean已经包含了依赖关系的bean
    if(requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
        try {
            return this.getTypeConverter().convertIfNecessary(bean, requiredType);
        } catch (TypeMismatchException var22) {
            if(this.logger.isDebugEnabled()) {
                this.logger.debug("Failed to convert bean \'" + name + "\' to required type [" + ClassUtils.getQualifiedName(requiredType) + "]", var22);
            }

            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    } else {
        return bean;
    }
}

阅读全文
0 0