在上篇博客中有一个核心方法没有讲到 createBean()
,该方法的如下:
1 2
| protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException;
|
该方法定义在AbstractBeanFactory中。其含义是根据给定的BeanDefinition和args实例化一个bean对象,如果该BeanDefinition存在父类,则该BeanDefinition已经合并了父类的属性。所有Bean实例的创建都会委托给该方法实现。
方法接受三个参数:
- beanName:bean 的名字
- mbd:已经合并了父类属性的(如果有的话)BeanDefinition
- args:用于构造函数或者工厂方法创建bean实例对象的参数
该抽象方法的默认实现是在类 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
| protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException { RootBeanDefinition mbdToUse = mbd;
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) { 。。。。省略异常 } try { Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) { return bean; } } catch (Throwable ex) { 。。。。省略异常 } try { Object beanInstance = doCreateBean(beanName, mbdToUse, args); return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { 省略异常 } }
|
过程如下:
- 根据设置的class属性或者根据className来解析class
- 处理 override 属性进行标记及验证
- Bean初始化扩展点的处理,类如后面要说的aop,就会在这里直接初始化一个bean,这后面的操作就不需要进行
- 创建 bean
解析指定BeanDefinition的class
1
| Class<?> resolvedClass = resolveBeanClass(mbd, beanName)
|
这个方法主要是解析BeanDefinition的class 类,并将已经解析的Class存储在beandefinition中以供后面使用。如果解析的Class对象不为空,则会将该 BeanDefinition 进行克隆至mbdToUse,这样做的主要目的是为动态解析的 Class是无法保存到共享的BeanDefinition 中,这一步我是没看懂。
处理override属性
大家还记得 lookup-method 和 replace-method 这两个配置功能,在前面博客中已经详细分析了这两个标签的用法和解析过程,知道解析过程其实就是讲这两个配置存放在 BeanDefinition 中的 methodOverrides 属性中,我们知道在 bean 实例化的过程中如果检测到存在methodOverrides,则会动态地位为当前bean生成代理并使用对应的拦截器为bean做增强处理。具体的实现我们后续分析,现在先看 mbdToUse.prepareMethodOverrides()
都干了些什么事,如下:
1 2 3 4 5 6 7 8 9 10 11
| public void prepareMethodOverrides() throws BeanDefinitionValidationException { if (hasMethodOverrides()) { Set<MethodOverride> overrides = getMethodOverrides().getOverrides(); synchronized (overrides) { for (MethodOverride mo : overrides) { prepareMethodOverride(mo); } } } }
|
如果存在methodOverrides则获取所有的MethodOverride ,然后通过迭代的方法调用 prepareMethodOverride()
来进行预处理,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException { int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName()); if (count == 0) { throw new BeanDefinitionValidationException( "Invalid method override: no method with name '" + mo.getMethodName() + "' on class [" + getBeanClassName() + "]"); } else if (count == 1) { mo.setOverloaded(false); } }
|
根据方法名称从Class对象中获取该方法个数,如果为0 则抛出异常,如果为1则设置该重载方法没有被重载。若一个类中存在多个重载方法,则在方法调用的时候还需要根据参数类型来判断到底重载的是哪个方法。在设置重载的时候其实这里做了一个小小优化,那就是当count == 1
时,设置 overloaded = false
,这样表示该方法没有重载,这样在后续调用的时候便可以直接找到方法而不需要进行方法参数的校验。其实 mbdToUse.prepareMethodOverrides()
并没有做什么实质性的工作,只是对 methodOverrides 属性做了一些简单的校验而已。
实例化的前置处理
resolveBeforeInstantiation()
的作用是给InstantiationAwareBeanPostProcessor后置处理器返回一个代理对象的机会,这个后置处理器是BeanPostProcessor的一个子类,只是这里做了特殊的处理。其实在调用该方法之前Spring 一直都没有创建 bean ,那么这里返回一个 bean 的代理类有什么作用呢?作用体现在后面的 if
判断:
1 2 3
| if (bean != null) { return bean; }
|
如果代理对象不为空,则直接返回代理对象,这一步骤有非常重要的作用,Spring 后续实现 AOP 就是基于这个地方判断的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 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 为实例化后的后处理器应用,由于本文的主题是创建 bean,关于Bean的增强处理后续会单独出博文来做详细说明。
创建 bean
如果没有代理对象,就只能走常规的路线进行 bean 的创建了,该过程有 doCreateBean()
实现,如下:
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
| protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)throws BeanCreationException { BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); }
if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; }
synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { 。。。省略异常 } mbd.postProcessed = true; } } boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); }
Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { 。。。省略异常 } }
if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { 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()) { 。。。省略异常 } } } } try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { 省略异常 } return exposedObject; }
|
整体的思路:
- 如果是单例模式,则移除factoryBeanInstanceCache缓存,同时返回 BeanWrapper 实例对象,当然如果存在。
- 如果缓存中没有BeanWrapper或者不是单例模式,则调用
createBeanInstance()
实例化bean,主要是将 BeanDefinition 转换为 BeanWrapper
- 如果存在工厂方法,则使用工厂方法进行初始化
- 一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化
- 如果既不存在工厂函数也不存在带有参数的构造器函数则使用默认的构造函数进行bean的实例化
- MergedBeanDefinitionPostProcessor 的应用,Autowired注解正式通过此方法实现注入类型解析
- 单例模式的循环依赖处理(后面会重点说到)
- 调用
populateBean()
进行属性填充。将所有属性填充至 bean 的实例中
- 调用
initializeBean()
初始化 bean,也就是init-method
- 依赖检查,在Spring中只解决单例的循环依赖,这一步判断是否有循环依赖,如果抛出异常
- 注册 DisposableBean,如果配置了destroy-method。这里需要注册以便于在销毁的时候进行调用。
doCreateBean()
完成 bean 的创建和初始化工作,内容太多,这里就只列出整体思路,下文开始将该方法进行拆分进行详细讲解,分布从以下几个方面进行阐述:
createBeanInstance()
实例化 bean
populateBean()
属性填充
- 循环依赖的处理
initializeBean()
初始化 bean