createBean方法详解
前言:
createBean是创建Bean的主要方法
该方法位于:AbstractBeanFactory的doGetBean方法中的createBean调用、
createBean方法流程图:
createBean源码解析:
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;//该参数是从AbstractBeanFactory的doGetBean传递过来的父子容器合并BeanDefinition // 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. //判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { //克隆一份BeanDefinition,用来设置上加载出来的class对象 //之所以后续用该副本操作,是因为不希望将解析的class绑定到缓存里的BeanDefinition //因为class有可能是每次都需要动态解析出来的 mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. //校验和准备Bean中的方法覆盖 try { mbdToUse.prepareMethodOverrides();//如果是0个则抛异常,如果是1个也就没有重载的必要 } 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. //如果Bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建Bean的代理对象 //resolveBeforeInstantiation只是针对有自定义的targetsource, //因为自定义的targetsource不是spring的bena,那么肯定不需要进行后续的一系列的实例化,初始化。 //所以可以在resolveBeforeInstantiation直接进行proxy Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { //如果这里有处理器在bean创建的之前 给出了代理bean,则无需执行后续的逻辑, // 直接返回用户给出的bean 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) { // A previously detected exception with proper bean creation context already, // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }
createBean方法大致流程:
(1)判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载(如果可以,克隆一份BeanDefinition)
之所以使用副本进行后续的操作和创建,是不希望去修改到容器缓存里的BeanDefinition
(2)用BeanDefinition副本调用prepareMethodOverrides()方法,进行校验Bean和准备Bean中的方法覆盖(处理方法覆盖)
(3)⭐处理Bean配置的初始化前后的处理器(前置:该方法里头会调用所有的Bean处理器,如果处理器中有调换了bean的,则返回bean,如果没有则返回null)
(4)⭐调用doCreateBean()方法,该方法是创建Bean的入口
doCreateBean方法流程图:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. //bean实例包装类 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { //从未完成创建的包装Bean缓存中清理并获取相关中的包装Bean实例,毕竟是单例,只能存一份 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //创建bean的时候,这里创建bean的实例有三种方法 //1.工厂方法创建 //2.构造方法的方式注入 //3.无参构造方法注入 instanceWrapper = createBeanInstance(beanName, mbd, args);//******** } //获取被包装的Bean,后续对bean的改动相对于对Wrapper的改动,反之依然 final Object bean = instanceWrapper.getWrappedInstance(); //获取实例化对象的类型 Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. //调用BeanDefinition属性合并完成后的BeanPostProcessor后置处理器 synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { //@Autowired、@Value标记的属性在这里获取 //应用合并后的BeanDefinition后置处理器 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. //向容器中缓存单例模式的Bean对象,以防循环引用 //判断是否是早期引用的bean,如果是,则允许其提前暴露引用 // 这里判断的逻辑主要有三个∶ //1.是否为单例 //2 是否允许循环引用 //3.是否是在创建中的bean 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"); } //这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用 //将还没完全配置好的bean存入到三级缓存中供其他bean使用(暴露引用) addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); //这里的getEarlyBeanReference()方法,并不是在此调用,而是声明好了方法 //具体的调用在Spring的AbstractBeanFactory的doGetBean的第三行调用 // DefaultSingletonBeanRegistry类的getSingleton方法中,调用 // singletonFactory.getObject()(单例工厂的getObject方法返回实例对象) } // Initialize the bean instance. //Bean对象的初始化,依赖注入在此触发 //这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean Object exposedObject = bean;//暴露的对象 try { //填充bean实例的属性 populateBean(beanName, mbd, instanceWrapper); //初始化bean,过程如下: //1.判断是否实现了BeanNameAware,BeanClassLoaderAware,BeanFactoryAware方法, //如果有,则设置相关的属性 //2.调用bean初始化前的前置(BeanPostProcessor)操作 //3.执行初始化的方法 //如果有InitializingBean,则调用afterPropertiesSet //如果有InitMethod,则调用初始方法 //4.调用bean初始化的后置(BeanPostProcessor)操作 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); } } //若允许循环依赖,则解决相关的循环依赖 //earlySingletonExposure是前面代码判断出来的是否:暴露引用bean if (earlySingletonExposure) { //获取指定名称的已注册的单例模式Bean对象 //这里的getSingleton()从三层缓存中依次去获取,由于 //先前我们已经将对象存入到三级缓存中,所有这里在三级缓存获取得到 //然后缓存中的对象被放到了二级缓存中,三级中移除了 Object earlySingletonReference = getSingleton(beanName, false);// if (earlySingletonReference != null) { //如果经过initializeBean执行后返回的bean还是同一个(不是代理对象实例,即没有被增强) if (exposedObject == bean) { //确保根据名称获取到的 exposedObject = earlySingletonReference; } //如果上面的if没通过,则表明引用的bean和注入的bean不一致,则需要看看依赖于此Bean的先前是否已经 //allowRawInjectionDespiteWrapping标注是否允许此Bean的原始类型被注入到其他Bean里面, //即使自己最终会被包装(代理) //dependentBeanMap记录着每个依赖于此Bean的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); } } //因为Bean创建后其所依赖的Bean一定是已经创建的 //actualDependentBeans不为空则表示当前Bean创建后其依赖的Bean却没有全部创建完,也就是说 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."); } } } }
doCreateBean方法大致流程:
(1)判断BeanDefinition是不是单例的,如果是单例的,从未完成创建的包装Bean缓存中清理并获取相关中的包装Bean实例,毕竟是单例,只能存一份
(2)判断第一步中获到的包装Bean实例如果是空的,调用createBeanInstance()方法创建bean,这里创建bean的实例有三种方法
(1)尝试获取BeanDefinition里面的Class对象
(2)检查是否有权通过反射创建private的Class
(3)如果bean使用的是java自带的函数式接口Supplier(工厂方法),则调用里头的get创建返回bean实例
(4)如果BeanDefinition里面有定义Spring的工厂方法如(factory-method),则调用factory-method创建返回实例
(5)查询BeanDefinition中有没有缓存好的构造函数或者工厂方法,有则调用创建返回实例
(6)判断是否使用(带惨构造函数装配)如果都不是最终调用无参构造函数创建返回实例
(3)获取被包装的Bean,后续对bean的改动相对于对Wrapper的改动,反之依然,获取实例化对象的类型并放入BeanDefinition中
(4)对BeanDefinition的后置处理器上锁操作,判断BeanDefinition没有使用后置处理器,后调用applyMergedBeanDefinitionPostProcessors()方法应用合并后的BeanDefinition后置处
理器(@Autowired、@Value标记的属性在这里获取) applyMergedBeanDefinitionPostProcessors内部跟绝大部分后置处理器一样采用了责任链模式,循环遍历所有后置处理器,
IF实现了MergedBeanDefinitionPostProcessor接口的 后置处理器便调用postProcessMergedBeanDefinition方法这里我们重点关注:AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition()
(1)进入AutowiredAnnotationBeanPostProcessor类,首先我们可以看到该类的无参构造方法中对@Autowired、@Value注解添加到了该类的成员变量里。
(2)我们查看postProcessMergedBeanDefinition()方法
(A)首先第一行调用了findAutowiringMetadata()方法(寻找被注解标记的元数据)
(1)用类名作为cacheKey(缓存建名)
(2)使用cacheKey在缓存容器中查找是否有相关缓存
(3)如果缓存容器中没有metadata(元数据)|| metadata的class和给定的clazz不符合则重新获取到构建好的metadata实例并放入到缓存容器中(双重锁机制)
(B)用前面查找到的metadata调用checkConfigMembers方法,需要Spring用默认策略放到的InjectedElements(注入元素表)
(5)判断是否是早期引用的bean,如果是,则允许其提前暴露引用(单例、允许循环引用、创建中的bean)
doCreateBean简述:
获取赋值BeanWrapper(bean实例包装类) ---》 调用前面合并好的BeanPostProcess(后置处理器) ---》 如果是单例模式的bean,缓存进容器中。 ---》 填充Bean实例的属性 ---》初始化Bean实例(初始化前后会调用BeanPostProcessor操作) --》 IF:(允许暴露引用的bean) 从三层缓存中获取bean,随后解决依赖问题 --》 注册Bean的逻辑销毁 ---》返回Bean实例