美文网首页
Spring IOC的深入理解(五)

Spring IOC的深入理解(五)

作者: chengcongyue | 来源:发表于2019-04-15 16:28 被阅读0次

引言

在执行ac.getBean("car")的过程中,spring如何加载bean的?

FactoryBean

public interface FactoryBean<T>
{
//......
}

当配置文件<bean>中的class的类是FactoryBean接口的实现类时,getBean返回的就不是对应的类,而是这个实现类调用get
Object()方法所返回的对象,相当于是getObject()代理了getBean()类

从缓存中获取单例类

单例在spring中只会创建一次,后续获取bean直接从单例缓存中获取,首先尝试从缓存中加载,后序在尝试从SingletonFactories中获取.
Spring创建bean的原则就是在创建一个bean时候,不等bean创建完成就将ObjectFactory提早曝光到缓存中.下次有bean依赖到这个已经创建的bean的时候,就直接使用ObjectFactory

Object sharedInstance = getSingleton(beanName);
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }

首先查看缓存中是否有实例,如果有就获取
如果没有的话,全局加锁,在从earlySingletonObjects中获取,如果还是获取不到,就从singletonFactories中获取BeanName对应的ObjectFactory,然后调用这个singletonFactory来创建singletonObject,然后放到earlySingletonObjects中去,然后从singletonFactories清除掉这个beanName.
其中有大量的map,我们来进行梳理一下:

  • singletonObjects bean和BeanName的关系如果其中有bean,就可以直接创建
  • singletonFactories BeanName和Bean工厂之间的关系
  • earlySingletonObjects BeanName和bean,主要是用来做循环检验的

这个时候我们就获取到了beanName对应的bean了

从bean的实例中获取对象

如果缓存不为空的话,我们就已经获取到实例了,记住这个时候我们是从缓存中获取的实例,然后我们继续回到最开始的方法

if (sharedInstance != null && args == null) {
            if (logger.isTraceEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                            "' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
我们进入到这个方法中
这个代码大概的意思就是,尝试从缓存中获取加载bean,如果加载失败,我们就可以明确的知道是Factorybean类型的,然后调用getObjectFromFactoryBean这个方法,其中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((PrivilegedExceptionAction<Object>) factory::getObject, acc);
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                object = factory.getObject();
            }
        }

object = factory.getObject();之后回到上一层代码,会调用如下的一段代码

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            Object current = processor.postProcessAfterInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

这个就是后处理器的使用,在后面我们会详细的介绍

创建单例

    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            // Explicitly remove instance from singleton cache: It might have been put there
                            // eagerly by the creation process, to allow for circular reference resolution.
                            // Also remove any beans that received a temporary reference to the bean.
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });

上面讲的是从缓冲中获取单例bean,然后从bean的实例中获取对象.接下来就是如果缓存中没有bean,我们该怎么办,我们进入到这个重载的getSingleton中

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
        synchronized (this.singletonObjects) {
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName,
                            "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                            "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                }
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                }
                catch (IllegalStateException ex) {
                    // Has the singleton object implicitly appeared in the meantime ->
                    // if yes, proceed with it since the exception indicates that state.
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        throw ex;
                    }
                }
                catch (BeanCreationException ex) {
                    if (recordSuppressedExceptions) {
                        for (Exception suppressedException : this.suppressedExceptions) {
                            ex.addRelatedCause(suppressedException);
                        }
                    }
                    throw ex;
                }
                finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }
                    afterSingletonCreation(beanName);
                }
                if (newSingleton) {
                    addSingleton(beanName, singletonObject);
                }
            }
            return singletonObject;
        }
    }

其中singletonObject = singletonFactory.getObject();是初始化bean的,我们来看看在它之前都做了些什么?检查和记录
beforeSingletonCreation(beanName);和 afterSingletonCreation(beanName);都是用来记录加载状态的,最后将缓存假加入到缓存中,并删除一些缓存记录.
我们已经了解了bean的逻辑架构,真正的bean加载过程是在传入的匿名内部类中实现的

sharedInstance = getSingleton(beanName, () -> {
                        try {
                            return createBean(beanName, mbd, args);
                        }

我们来深入了解createBean方法.
首先是解析Class,然后是对override方法进行标记和验证

Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
try {
            mbdToUse.prepareMethodOverrides();
        }
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            // Make sure bean class is actually resolved at this point.
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                Class<?> targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }

applyBeanPostProcessorsBeforeInstantiation和applyBeanPostProcessorsAfterInitialization是对getSingleton方法中的后处理的调用,
bean在实例化前会有一个后处理器的调用,将AbstractBeanDefinition转化成BeanWrapper,经过处理这有可能是一个经过处理的bean,而后处理的过程,就是将bean注册的过程,当bean再次使用时,就不必在进行创建了

创建bean

然后我们进入到doCreateBean方法中,这里是常规的bean操作.
如果是单例,首先需要清除缓存.实例化bean,将BeanDefinition转换为BeanWrapper.使用工厂方法,使用构造方法,使用默认构造方法

相关文章

网友评论

      本文标题:Spring IOC的深入理解(五)

      本文链接:https://www.haomeiwen.com/subject/seguwqtx.html