IOC CreateBean

时间:2022-07-27
本文章向大家介绍IOC CreateBean,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

createBean方法

createBean该抽象方法的默认实现是在类 AbstractAutowireCapableBeanFactory 中实现,代码如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

// AbstractAutowireCapableBeanFactory.java 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; // <1> 确保此时的 bean 已经被解析了 // 如果获取的class 属性不为null,则克隆该 BeanDefinition // 主要是因为该动态解析的 class 无法保存到到共享的 BeanDefinition Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } try { // <2> 验证和准备覆盖方法 mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // <3> 实例化的前置处理 // 给 BeanPostProcessors 一个机会用来返回一个代理类而不是真正的类实例 // AOP 的功能就是基于这里 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 { // <4> 创建 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); } }

上面方法处理的流程如下

  1. <1> 处,解析 bean 类型。
  2. <2>处,验证和准备覆盖方法,处理 lookup-method 和 replace-method 配置。这两个配置存放在 BeanDefinition 中的 methodOverrides 属性中,在bean实例化的时候如果检测到存在methodOverrides属性,会动态地为当前bean生成代理,并使用对应的拦截器为bean做增强处理。
  3. <3>处,实例化的前置处理。
  4. <4>处,若上一步处理返回的 bean 为空,则调用 doCreateBean 创建 bean 实例。 下面会对<3><4>处做一些详细的分析,感兴趣的小伙伴可以看看。

2.1 实例化的前置处理

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

// AbstractAutowireCapableBeanFactory.java protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { 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() 两个方法,before 为实例化前的后处理器应用,after 为实例化后的后处理器应用。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { // InstantiationAwareBeanPostProcessor 一般在 Spring 框架内部使用,不建议用户直接使用 if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // bean 初始化前置处理 Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; } public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { // bean 初始化后置处理 result = beanProcessor.postProcessAfterInitialization(result, beanName); if (result == null) { return result; } } return result; }

在 resolveBeforeInstantiation 方法中,当前置处理方法返回的 bean 不为空时,后置处理才会被执行。前置处理器是 InstantiationAwareBeanPostProcessor 类型的,该种类型的处理器一般用在 Spring 框架内部,比如 AOP 模块中的AbstractAutoProxyCreator抽象类间接实现了这个接口中的 postProcessBeforeInstantiation方法,所以 AOP 可以在这个方法中生成为目标类的代理对象。这部分还没有详细去了解,属于TODO。

2.2 调用 doCreateBean 方法创建 bean

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123

// AbstractAutowireCapableBeanFactory.java protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // BeanWrapper 是对 Bean 的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装 bean 的属性描述器 BeanWrapper instanceWrapper = null; // <1> 单例模型,则从未完成的 FactoryBean 缓存中删除 if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } // <2> 使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化 if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } // 包装的实例对象 final Object bean = instanceWrapper.getWrappedInstance(); // 包装的实例对象的类型 Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // <3> 判断是否有后置处理 // 如果有后置处理,则允许后置处理修改 BeanDefinition synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { // 后置处理修改 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; } } // <4> 解决单例模式的循环依赖 // earlySingletonExposure=单例 && 是否允许循环依赖 && 是否存于创建状态中。 boolean earlySingletonExposure = (mbd.isSingleton() // 单例模式 && this.allowCircularReferences // 运行循环依赖 && isSingletonCurrentlyInCreation(beanName)); // 当前单例 bean 是否正在被创建 if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } // 提前将创建的 bean 实例加入到 singletonFactories 中 // 这里是为了后期避免循环依赖 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // 开始初始化 bean 实例对象 Object exposedObject = bean; try { // <5> 对 bean 进行填充,将各个属性值注入,其中,可能存在依赖于其他 bean 的属性 // 则会递归初始依赖 bean populateBean(beanName, mbd, instanceWrapper); // <6> 调用初始化方法 /* * 进行余下的初始化工作,详细如下: * 1. 判断 bean 是否实现了 BeanNameAware、BeanFactoryAware、 * BeanClassLoaderAware 等接口,并执行接口方法 * 2. 应用 bean 初始化前置操作 * 3. 如果 bean 实现了 InitializingBean 接口,则执行 afterPropertiesSet * 方法。如果用户配置了 init-method,则调用相关方法执行自定义初始化逻辑 * 4. 应用 bean 初始化后置操作 * * 另外,AOP 相关逻辑也会在该方法中织入切面逻辑,此时的 exposedObject 就变成了 * 一个代理对象了 */ 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); } } // <7> 循环依赖处理 if (earlySingletonExposure) { // 获取 earlySingletonReference Object earlySingletonReference = getSingleton(beanName, false); // 只有在存在循环依赖的情况下,earlySingletonReference 才不会为空 if (earlySingletonReference != null) { // 如果 exposedObject 没有在初始化方法中被改变,也就是没有被增强 if (exposedObject == bean) { exposedObject = earlySingletonReference; // 处理依赖 } 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."); } } } } // 注册销毁逻辑 try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }

整体的思路如下:

  1. <1> 处,从缓存中获取 BeanWrapper 实现类对象,并清理相关记录。
  2. <2> 处,创建 bean 实例,并将实例包裹在 BeanWrapper 实现类对象中返回。createBeanInstance 中包含三种创建 bean 实例的方式:
    • 通过工厂方法创建 bean 实例
    • 通过构造方法自动注入(autowire by constructor)的方式创建 bean 实例
    • 通过无参构造方法方法创建 bean 实例

    若 bean 的配置信息中配置了 lookup-method 和 replace-method,则会使用 CGLIB 增强 bean 实例。

  3. <3>处,应用 MergedBeanDefinitionPostProcessor 后置处理器相关逻辑。
  4. <4>处,根据条件决定是否提前暴露 bean 的早期引用(early reference),用于处理循环依赖问题。
  5. <5>处,调用 populateBean 方法向 bean 实例中填充属性。
  6. <6>处,调用 initializeBean 方法完成余下的初始化工作。
  7. <7>处,循环依赖处理。
  8. <8>处,注册销毁逻辑。