前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深度解析 Spring Bean 的加载

深度解析 Spring Bean 的加载

作者头像
用户1516716
发布2019-08-23 16:45:44
3400
发布2019-08-23 16:45:44
举报
文章被收录于专栏:A周立SpringCloudA周立SpringCloud

点击上方"IT牧场",选择"设为星标"技术干货每日送达!

1、getBean()

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

1.1、从缓存获取
代码语言:javascript
复制
//提取对应的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()
代码语言:javascript
复制
@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
代码语言:javascript
复制
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
代码语言:javascript
复制
//如果不是做类型检查则是创建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()
代码语言:javascript
复制
//第一部分
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()

代码语言:javascript
复制
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()这个方法最后一行

代码语言:javascript
复制
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
    try {
        Object beanInstance;
        final BeanFactory parent = this;
        if (System.getSecurityManager() != null) {
            beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
                    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

代码语言:javascript
复制
// 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(…)这个方法

代码语言:javascript
复制
if (System.getSecurityManager() != null) {
    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
        invokeAwareMethods(beanName, bean);
        return null;
    }, getAccessControlContext());
}
else {
    invokeAwareMethods(beanName, bean);
}

接下来进入到invokeAwareMethods()方法

代码语言:javascript
复制
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()方法中

代码语言:javascript
复制
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<Object>) () -> {
                    ((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创建和加载算是基本完成,下一节分析一些具体详细点的实现。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT牧场 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 点击上方"IT牧场",选择"设为星标"技术干货每日送达!
  • 1、getBean()
    • 1.1、从缓存获取
      • 1.1.1、getSingleton()
    • 1.2、获取BEANFACOTRY
      • 1.3
        • 1.4、CREATEBEAN()
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档