Spring源码(五)-bean的加载(下)

前言

接的私活有点赶进度,加上周四搬工位,昨天看了演唱会,加上改bug一直没有抽出时间来写,今天估计补不上周四的了,周末也有事情,周四的下周一定不上。废话不说了,我们继续之前bean的加载下篇,bean的加载是spirng-ioc的核心,我自己理解的也不是特别好,有感兴趣的小伙伴欢迎一起聊聊。
QQ:616516146,Gmail:[email protected]

1、getBean()

这个方法有点长我们进行分段解析。

1.1、从缓存获取

//提取对应的beanName
final String beanName = transformedBeanName(name);
Object bean;

// Eagerly check singleton cache for manually registered singletons.
/**
 * 检查缓存中或者实例工厂中是否有对应实例
 * 为何会首先使用这段代码
 * 因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖
 * Spring创建Bean的原则是不等bean创建完成就会将创建Bean的ObjectFactory提早曝光
 * 也就是讲ObjectFactory加入到缓存中,一旦下一个bean创建的时候需要依赖上个bean则直接使用ObjectFactory
 */
//尝试从混成或者singletonFactories中的ObjectFactory中获取
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
    if (logger.isDebugEnabled()) {
        if (isSingletonCurrentlyInCreation(beanName)) {
            logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                    "' that is not fully initialized yet - a consequence of a circular reference");
        }
        else {
            logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
        }
    }

    bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}


这个方法首先从缓存中去获取,这个时候缓存中当然没有数据,因为此时是初始化,我们还没有将bean方到singletonObjects这个map中去,如下图代码。

1.1.1、getSingleton()
    @Nullable
    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) {
                        //调用预先设定的getObject方法
                        singletonObject = singletonFactory.getObject();
                        //记录在缓存中,earlySingletonObjects和singletonFactories互斥
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return (singletonObject != NULL_OBJECT ? singletonObject : null);
    }

1.2、获取beanFacotry

if (isPrototypeCurrentlyInCreation(beanName)) {
    throw new BeanCurrentlyInCreationException(beanName);
}

// Check if bean definition exists in this factory.
//如果beaDefinitionMap中也就是在所有已经加载的类中不包括beanName则尝试从parentBeanFactory中检测
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    // Not found -> check parent.
    String nameToLookup = originalBeanName(name);
    if (parentBeanFactory instanceof AbstractBeanFactory) {
        return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                nameToLookup, requiredType, args, typeCheckOnly);
    }
    else if (args != null) {
        //递归到BeanFactory中去寻找
        // Delegation to parent with explicit args.
        return (T) parentBeanFactory.getBean(nameToLookup, args);
    }
    else {
        // No args -> delegate to standard getBean method.
        return parentBeanFactory.getBean(nameToLookup, requiredType);
    }
}

这段代码首先获取该bean的父类,若有父类则用父类去实例化该bean,这里的parentBeanFactory为null,暂时不做考虑。接下来看第三部分。

1.3

//如果不是做类型检查则是创建bean,这里要进行记录
//第一部分
if (!typeCheckOnly) {
    markBeanAsCreated(beanName);
}
//第二部分
try {
    final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    checkMergedBeanDefinition(mbd, beanName, args);

    // Guarantee initialization of beans that the current bean depends on.
    String[] dependsOn = mbd.getDependsOn();
    //若存在依赖则需要递归实例化依赖的bean
    if (dependsOn != null) {
        for (String dep : dependsOn) {
            if (isDependent(beanName, dep)) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
            }
            registerDependentBean(dep, beanName);
            getBean(dep);
        }
    }
//第三部分
    // Create bean instance.
    //实例化依赖的bean之后可以实例化mbd本身了
    //单例模式的创建
    if (mbd.isSingleton()) {
        sharedInstance = getSingleton(beanName, () -> {
            try {
                /**
                 *核心创建bean
                 */
                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 = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }

  • 1、第一部分,标记目前的bean属于正在创建状态
  • 2、第二部分,根据beanName获取该bean在beanFactory中的beanDefinitionMap中beanDefinition,然后获取该bean所依赖的bean(此处是spring解决循环依赖的关键),如果依赖的bean还未创建,则先创建依赖的bean,依次递归调用(DI依赖注入的概念),如果找不到依赖,则忽略。
  • 3、若是单例,创建bean,调用CreateBean()方法,此处只考虑单例模式

接下来跟踪createBean()方法。此处调用的是AbstractAutowireCapableBeanFactory中的方法

1.4、createBean()

//第一部分
if (logger.isDebugEnabled()) {
    logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;

// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
/**
 * 锁定class,根据设置的class属性或者根据classname来解析class
 */
Class resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    mbdToUse = new RootBeanDefinition(mbd);
    mbdToUse.setBeanClass(resolvedClass);
}
//第二部分
//验证及准备覆盖的方法
try {
    mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
    throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
}
//第三部分
try {
    // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
    //给BeanPostProcessors一个机会来返回代理来代替真正的实例,前置处理器
    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    /**
     * 前置处理后返回结果不为空,直接返回结果,AOP功能就是基于这里判断的
     */
    if (bean != null) {
        return bean;
    }
}
catch (Throwable ex) {
    throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
            "BeanPostProcessor before instantiation of bean failed", ex);
}
//第四部分
try {
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    if (logger.isDebugEnabled()) {
        logger.debug("Finished creating instance of bean '" + beanName + "'");
    }
    return beanInstance;
}

  • 1、第一部分:确保该bean的class是真实存在的,也就是该bean是可以classload可以找到加载的,若不存在则放入beanDefination中
  • 2、第二部分:准备方法的重写
  • 3、第三部分:(重要)最后的return就是返回的bean,但看注释:Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.这边就很清晰了,我们以前在beanPostProcessor的章节讲过,beanPostProcessor是可以临时修改bean的,它的优先级高于正常实例化bean的(也就是第四部分实例化的方法)如果beanPostProcessor能返回,则直接返回了,这边代码下次分析,我们还是先分析主要流程:
  • 4、doCreateBean(beanName, mbd, args)这个方法,接下来看这个
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            //根据指定的bean使用对应的侧脸创建新的实例,如工厂方法,构造函数自动注入,简单初始化
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
        Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
        mbd.resolvedTargetType = beanType;

        if (beanType != null) {
            // Allow post-processors to modify the merged bean definition.
            synchronized (mbd.postProcessingLock) {
                if (!mbd.postProcessed) {
                    try {
                        applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                    }
                    catch (Throwable ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Post-processing of merged bean definition failed", ex);
                    }
                    mbd.postProcessed = true;
                }
            }
        }

这里首先初始化一个instanceWrapper,然后再看createBeanInstance()

    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        // Make sure bean class is actually resolved at this point.
        Class beanClass = resolveBeanClass(mbd, beanName);

        if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
        }

        Supplier instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName);
        }

        if (mbd.getFactoryMethodName() != null)  {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        // Shortcut when re-creating the same bean...
        boolean resolved = false;
        boolean autowireNecessary = false;
        if (args == null) {
            synchronized (mbd.constructorArgumentLock) {
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        if (resolved) {
            if (autowireNecessary) {
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                return instantiateBean(beanName, mbd);
            }
        }

        // Need to determine the constructor...
        Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        if (ctors != null ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
            return autowireConstructor(beanName, mbd, ctors, args);
        }

        // No special handling: simply use no-arg constructor.
        return instantiateBean(beanName, mbd);
    }

这块代码主要是再次对bean做安全检查并确定该bean有默认的构造函数,createBeanInstance()这个方法最后一行

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
    try {
        Object beanInstance;
        final BeanFactory parent = this;
        if (System.getSecurityManager() != null) {
            beanInstance = AccessController.doPrivileged((PrivilegedAction) () ->
                    getInstantiationStrategy().instantiate(mbd, beanName, parent),
                    getAccessControlContext());
        }
        else {
            beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
        }
        BeanWrapper bw = new BeanWrapperImpl(beanInstance);
        initBeanWrapper(bw);
        return bw;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
}


然后我们再回到doCreateBean()这个方法,在AbstractAutowireCapableBeanFactory

// Initialize the bean instance.
Object exposedObject = bean;
try {
    //对bean进行填充,将各个属性值注入,其中,可能存在依赖与其他bean的属性,则会递归初始依赖bean
    populateBean(beanName, mbd, instanceWrapper);// sunliang marked
    if (exposedObject != null) {
        //调用初始化方法,比如init-method
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
}

初始化bean,的确,现在bean已经实例化了,开始初始化该bean,进入initializeBean(...)这个方法

if (System.getSecurityManager() != null) {
    AccessController.doPrivileged((PrivilegedAction) () -> {
        invokeAwareMethods(beanName, bean);
        return null;
    }, getAccessControlContext());
}
else {
    invokeAwareMethods(beanName, bean);
}

接下来进入到invokeAwareMethods()方法

private void invokeAwareMethods(final String beanName, final Object bean) {
    if (bean instanceof Aware) {
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware) bean).setBeanName(beanName);
        }
        if (bean instanceof BeanClassLoaderAware) {
            ClassLoader bcl = getBeanClassLoader();
            if (bcl != null) {
                ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
            }
        }
        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
        }
    }
}

再回到initializeBean()方法中

try {
    invokeInitMethods(beanName, wrappedBean, mbd);
}

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
        throws Throwable {

    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        if (logger.isDebugEnabled()) {
            logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
        }
        if (System.getSecurityManager() != null) {
            try {
                AccessController.doPrivileged((PrivilegedExceptionAction) () -> {
                    ((InitializingBean) bean).afterPropertiesSet();
                    return null;
                }, getAccessControlContext());
            }
            catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        }
        else {
        //第一部分
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }

    if (mbd != null) {
        String initMethodName = mbd.getInitMethodName();
        if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                !mbd.isExternallyManagedInitMethod(initMethodName)) {
                //第二部分
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}


首先先判断该bean是否实现了InitializingBean,如果实现了先执行afterPropertiesSet这个方法,然后如果该bean又执行了init-method,到此我们的bean创建和加载算是基本完成,下一节分析一些具体详细点的实现。

你可能感兴趣的:(Spring源码(五)-bean的加载(下))