Spring IOC源码-bean加载

1、装载bean的第一步,调用doGetBean(name,...)方法
(1)转换对应的beanName,参数里面的name未必是beanName,可能是别名或者factoryBean
(2)首先尝试从缓存中加载单例
(3)如果从缓存中拿到了bean,调用getObjectForBeanInstance 将bean实例化 
(4)原型模式依赖检查
(5)通过getParentBeanFactory获取parentBeanFactory
(6)获取RootBeanDefinition
(7)针对不同的scope进行bean的创建
(8)类型转换

 
2、从缓存中获取单例对象,其中,
singletonObjects是一个map,存储实例化后的对象
earlySingletonObjects也是一个map,存储实例化后的对象,与singletonObjects的区别是, 当一个单例的bean被放到这个map中以后,当bean还在创建中的时候就可以通过getbean获取到了,用来检测循环引用
singletonFactories:保存beanName和创建bean的工厂之间的映射关系
registeredSingletons:保存当前所有已经注册的bean


 

 
3、根据不同的scope创建bean, 以单例为例:getSingleton()方法的第一个参数是beanName, 第二个参数是一个接口:ObjectFactory,这个接口提供一个getObject方法在getSingleton中的singletonObject = singletonFactory.getObject();时候使用。
下面看getObject的时候都做了什么
getObject会使用AbstractBeanFactory类的抽象方法:
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, Object[] args)  throws BeanCreationException;
他的实现写在AbstractAutowireCapableBeanFactory里面,继承结构图如下:



 
 
4、createBean进去以后首先找到BeanDefinition,然后调用doCreateBean()创建真正的bean,doCreateBean中完成了以下几件事:
(1)如果需要创建的bean是单例,需要首先清除缓存
(2)实例化bean,调用createBeanInstance()方法,将beanDefinition转化为BeanWrapper
这个过程包含以下几个步骤
  • 如果存在工厂方法,则使用工厂方法进行初始化
  • 当一个类有多个构造函数的时候,每个构造函数都有不同的参数,需要根据参数锁定构造函数并进行初始化
  • 如果即不存在工厂方法,也不存在带有参数的构造方法,使用默认构造方法进行bean的实例、
(3)调用populateBean进行属性的填充
(4)调用registerDisposableBeanIfNecessary进行bean的注册
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
        // Instantiate the bean.
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args); //创建beanWrapper
        }
        final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
        Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
 
        // Allow post-processors to modify the merged bean definition.
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                mbd.postProcessed = true;
            }
        }
 
        // Eagerly cache singletons to be able to resolve circular references
        // even when triggered by lifecycle interfaces like BeanFactoryAware.
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            if (logger.isDebugEnabled()) {
                logger.debug("Eagerly caching bean '" + beanName +
                        "' to allow for resolving potential circular references");
            }
            addSingletonFactory(beanName, new ObjectFactory<Object>() {
                @Override
                public Object getObject() throws BeansException {
                    return getEarlyBeanReference(beanName, mbd, bean);
                }
            });
        }
 
        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            populateBean(beanName, mbd, instanceWrapper); //属性注入
            if (exposedObject != null) {
                exposedObject = initializeBean(beanName, exposedObject, mbd); //调用初始化方法
            }
        }
        catch (Throwable ex) {
            if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
                throw (BeanCreationException) ex;
            }
            else {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
            }
        }
......
 
        // Register bean as disposable.
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd); //注册bean
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }
 
        return exposedObject;
    }
5、使用createBeanInstance创建bean实例
获取beanName对应的class
  • 如果存在工厂方法,使用工厂方法执行bean的初始化策略
  • 解析构造函数并进行构造函数的实例化
里面比较重要的方法是
autowireConstructor(beanName, mbd, null, null);(调用带有参数的构造方法)和instantiateBean(beanName, mbd);(调用无参构造方法)
6、使用populateBean进行属性注入
该方法中最重要的是对autowireByName(beanName, mbd, bw, newPvs);和对autowireByType(beanName, mbd, bw, newPvs);方法的调用,
最后再使用applyPropertyValues(beanName, mbd, bw, pvs);  将所有的属性填充到BeanWrapper中
 
 
 
 
(4)getBean方法中无论是要创建那种类型的bean最终都是通过getObjectForBeanInstance(...)方法生成, 该方法是beanFactory与factoryBean的桥梁,在这个方法中调用BeanFactory通过 factoryBean去创建bean
 
protected Object getObjectForBeanInstance(
            Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
 
        // Don't let calling code try to dereference the factory if the bean isn't a factory.
       //如果bean不是一个FactoryBean则不做任何处理
        if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
            throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
        }
 
        // Now we have the bean instance, which may be a normal bean or a FactoryBean.
        // If it's a FactoryBean, we use it to create a bean instance, unless the
        // caller actually wants a reference to the factory.
        if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
            return beanInstance;
        }
 
        Object object = null;
        if (mbd == null) {
            object = getCachedObjectForFactoryBean(beanName);
        }
        if (object == null) {
            // Return bean instance from factory.
            FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
            // Caches object obtained from FactoryBean if it is a singleton.
            if (mbd == null && containsBeanDefinition(beanName)) {
                mbd = getMergedLocalBeanDefinition(beanName);
            }
            boolean synthetic = (mbd != null && mbd.isSynthetic());
            object = getObjectFromFactoryBean(factory, beanName, !synthetic);
        }
        return object;
    }
(3)getObjectFromFactoryBean
 
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
        if (factory.isSingleton() && containsSingleton(beanName)) {
            synchronized (getSingletonMutex()) {
                Object object = this.factoryBeanObjectCache.get(beanName);
                if (object == null) {
                    object = doGetObjectFromFactoryBean(factory, beanName);
                    // Only post-process and store if not put there already during getObject() call above
                    // (e.g. because of circular reference processing triggered by custom getBean calls)
                    Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                    if (alreadyThere != null) {
                        object = alreadyThere;
                    }
                    else {
                        if (object != null && shouldPostProcess) {
                            try {
                                object = postProcessObjectFromFactoryBean(object, beanName);
                            }
                            catch (Throwable ex) {
                                throw new BeanCreationException(beanName,
                                        "Post-processing of FactoryBean's singleton object failed", ex);
                            }
                        }
                        this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
                    }
                }
                return (object != NULL_OBJECT ? object : null);
            }
        }
        else {
            Object object = doGetObjectFromFactoryBean(factory, beanName);
            if (object != null && shouldPostProcess) {
                try {
                    object = postProcessObjectFromFactoryBean(object, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
                }
            }
            return object;
        }
    }
(4)doGetObjectFromFactoryBean
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
            throws BeanCreationException {
 
        Object object;
        try {
            if (System.getSecurityManager() != null) {
                AccessControlContext acc = getAccessControlContext();
                try {
                    object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                        @Override
                        public Object run() throws Exception {
                                return factory.getObject();
                            }
                        }, acc);
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                object = factory.getObject();
            }
        }
        catch (FactoryBeanNotInitializedException ex) {
            throw new BeanCurrentlyInCreationException(beanName, ex.toString());
        }
        catch (Throwable ex) {
            throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
        }
 
        // Do not accept a null value for a FactoryBean that's not fully
        // initialized yet: Many FactoryBeans just return null then.
        if (object == null && isSingletonCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(
                    beanName, "FactoryBean which is currently in creation returned null from getObject");
        }
        return object;
    }

猜你喜欢

转载自xiaoxiaoxuanao.iteye.com/blog/2315366