Spring源码分析——Bean的加载 Dear 丶 2022-12-26 04:44 220阅读 0赞 ## 背景 ## Spring版本:5.1.14.RELEASE 仔细阅读[依赖注入(Dependency Injection)框架是如何实现的][Dependency Injection]这篇博文后,我们大致知道了一个DI容器是如何创建bean的。总体来,bean的创建流程分为如下三步: ![20210510135933368.png][] 定义化:从xml文件中解析bean的定义(获得BeanDefinition实例),之后创建bean都是通过bean的定义去创建。 实例化:实例化的过程是一个创建Bean的过程,即调用Bean的构造函数,单例的Bean放入单例池中。 初始化:初始化的过程是一个赋值的过程,即调用Bean的setter,设置Bean的属性。 更为关键的是,在这三个阶段中,Spring给我们预留了很多扩展点去做自定义的工作。 ![20210510201950637.png][] 在Bean从创建到销毁的整个生命周期中会执行的方法: ![20210510144352322.png][] 有了以上基础知识后,本文解读Spring源码,从getBean()开始一路探讨容器是如何加载到bean的。 ## bean的加载 ## 追踪源码可以发现ApplicationContext.getBean()的内部实现是BeanFactory.getBean(),而BeanFactory.getBean()的内部实现是AbstractBeanFactory.getBean(),所有AbstractBeanFactory.getBean()方法最终都调用了AbstractBeanFactory.doGetBean()。 流程: ApplicationContext.getBean()—>BeanFactory.getBean()—>AbstractBeanFactory.getBean()—>AbstractBeanFactory.doGetBean() ![2021051019073492.png][] 核心就是要了解AbstractBeanFactory\#doGetBean()方法的的处理逻辑, 这个方法写得很长。 /** - Return an instance, which may be shared or independent, of the specified bean. */ @SuppressWarnings("unchecked") protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; //先尝试从缓存中或者ObjectFactory中获取 Object sharedInstance = getSingleton(beanName); 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 + "'"); } } //有时候并不是返回实例本身,而是返回对应的实例。主要处理实现了FactoryBean接口的bean //如果某个bean实现了FactoryBean接口,通过getBean方法来获取bean的时候,并不是返回自己的实例,而是返回其getObject()方法的返回值 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } // 缓存中不存在该bean的实例 else { //判断原型模式的bean是否已经处于创建过程中,避免循环依赖 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } //如果本BeanFactory找不到就尝试从父BeanFactory中查找 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) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // 确保当前bean依赖的bean的初始化 String[] dependsOn = mbd.getDependsOn(); 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 + "'"); } // 注册依赖的bean registerDependentBean(dep, beanName); try { //创建当前bean依赖的bean getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } //根据单例模式或原型模式创建bean if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } //创建其他作用域的bean else { String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' 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", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } // 检查所需的类型是否与实际bean实例的类型匹配,若不匹配做类型转换 if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException ex) { if (logger.isTraceEnabled()) { logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; } doGetBean()方法很长,其执行的大致流程如下: * transformedBeanName(name)将bean名称的前缀"&"去掉 * getSingleton(beanName)尝试从缓存中加载单例 * 如果bean实现了FactoryBean接口,作处理 * isPrototypeCurrentlyIncreation(beanName)原型模式的循环依赖检查 * 检测父BeanFactory * 依赖检测 * 根据不同的模式调用creatBean()方法创建bean实例 * 检查类型,如果需要则做类型转换 以上方法中,哪一步是重中之重一目了然。createBean()根据不同的模式创建bean,是实例化一个Bean的主要逻辑。 下面主要分析createBean()方法,该方法是AbstractBeanFactory的protected方法,由子类去实现。Debug跟踪发现该方法的实现在AbstractAutowireCapableBeanFactory类中。 /** * Central method of this class: creates a bean instance, * populates the bean instance, applies post-processors, etc. * @see #doCreateBean */ @Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isTraceEnabled()) { logger.trace("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; //解析指定BeanDefinition的Class,并将已经解析的Class存储在Beandefinition中以供后面使用 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // 对lookup-method和replace-method属性的处理(指定方法的覆盖) try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { //调用后置处理器返回代理bean,只针对InstantiationAwareBeanPostProcessor接口 //的postProcessBeforeInstantiation方法 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { //真正的创建bean Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } } createBean()方法执行的大致流程如下: * 解析指定BeanDefinition的Class,并将已经解析的Class存储在Beandefinition中 * 对lookup-method和replace-method属性的处理(指定方法的覆盖) * 调用后置处理器返回代理bean(只针对InstantiationAwareBeanPostProcessor的before) * 执行doCreateBean(),真正的创建bean **Bean的创建过程大部分是在doCreateBean()里面完成的**。 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; //如果RootBeanDefinition是单例的,则移除未完成的FactoryBean实例的缓存 if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } //获取BeanWrapper中封装的Object对象,其实就是bean对象的实例 final Object bean = instanceWrapper.getWrappedInstance(); //获取BeanWrapper中封装的bean的Class Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } synchronized (mbd.postProcessingLock) { //bean的生命周期之一,如果实现了MergedBeanDefinitionPostProcessor //会在这里调用postProcessMergedBeanDefinition方法 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; } } //提前缓存单例,以便能够解析循环引用 //即使是由诸如BeanFactoryAware之类的生命周期接口触发的。 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } //bean的属性填充 Object exposedObject = bean; try { //填充属性,处理@AutoWried populateBean(beanName, mbd, instanceWrapper); //bean的初始化方 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); } } //如果单例bean已经缓存了,则直接获取 if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } //如果不允许在循环引用的情况下使用setter注入原始bean实例 else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } //注册DisposableBean,如果配置了destroy-methoy,这里需要注册以便于在销毁的时候调用 try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; } 大致如下: * 如果RootBeanDefinition是单例的,则移除未完成的FactoryBean实例的缓存 * 实例化Bean,仅是调用构造器,还没做属性的注入 * 如果实现了MergedBeanDefinitionPostProcessor,调用postProcessMergedBeanDefinition方法 * populateBean()属性填充,处理@Autowired、@Resource等注解 * **自定义初始化bean,bean生命周期中各种init、Aware、BeanPostProcessor方法的调用都在这一步。调用顺序:Aware—>BeanPostProcessor的before—>@PostConstruct->init—>BeanPostProcessor的after** * 注册DisposableBean Bean实例创建过程汇总为下图: ![20201203112335723.png][] [Dependency Injection]: https://blog.csdn.net/fuzhongmin05/article/details/109572151 [20210510135933368.png]: /images/20221120/1390935e7bf941da81c27bb1557658af.png [20210510201950637.png]: /images/20221120/88d080cb8b734988962c17116fff0f8a.png [20210510144352322.png]: /images/20221120/ca21521b37f84e65ba02ea4ee827e7ff.png [2021051019073492.png]: /images/20221120/1c43eb8e71b94b3d9ae2f36c53e7c9e6.png [20201203112335723.png]: /images/20221120/aa6ecc98aaef4f86af89f13634412bc3.png
还没有评论,来说两句吧...