SpringBoot源码-bean的加载(下)

继续搞,兄弟,先别走~~
上一节讲到 doCreateBean()方法,上码:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException { BeanWrapper instanceWrapper = null; // 先从缓存取 if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } // 缓存取不到,创建 if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; }synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { // 将 @Autowired等标记的属性解析出来,后续用 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException("……"); } mbd.postProcessed = true; } }// 是否可以提前暴露使用 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("……"); } // 将bean放入缓存中 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } Object exposedObject = bean; try { // 注入属性 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(); } }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 actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(); } } } }// 销毁bean一些东西 try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException(); } return exposedObject; }

点开
Object earlySingletonReference = getSingleton(beanName, false);

可以看到
@Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { // 一级缓存,存的是完成初始化好的bean Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { // 二级缓存,存的是尚未填充属性的bean对象 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { synchronized (this.singletonObjects) { singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null) { // 三级缓存 ObjectFactory singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } } } return singletonObject; }

这个就是spring的三级缓存取bean了。
讲了半天,好像还是没触及bean的实例化,别哭,站起来继续搞!回到doCreateBean() 方法,看createBeanInstance()的实现细节,关键代码:
// 获取bean的class Class beanClass = resolveBeanClass(mbd, beanName); return instantiateBean(beanName, mbd);

进入 instantiateBean(beanName, mbd),看到关键代码:
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);

进入 这个instantiate(mbd, beanName, this),看到以下两行代码:
return BeanUtils.instantiateClass(constructorToUse); return instantiateWithMethodInjection(bd, beanName, owner);

先看前者,点击进去:
try { ReflectionUtils.makeAccessible(ctor); if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) { return KotlinDelegate.instantiateClass(ctor, args); } else { Class[] parameterTypes = ctor.getParameterTypes(); Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters"); Object[] argsWithDefaultValues = new Object[args.length]; for (int i = 0 ; i < args.length; i++) { if (args[i] == null) { Class parameterType = parameterTypes[i]; argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null); } else { argsWithDefaultValues[i] = args[i]; } } return ctor.newInstance(argsWithDefaultValues); } }

就是根据构造函数以及参数new一个对象。
【SpringBoot源码-bean的加载(下)】再来看后者 instantiateWithMethodInjection,核心代码
Class subclass = createEnhancedSubclass(this.beanDefinition); Object instance; if (ctor == null) { instance = BeanUtils.instantiateClass(subclass); } else { try { Constructor enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes()); instance = enhancedSubclassConstructor.newInstance(args); }

这就是实例化的地方,听说使用cglib,可以查查它的资料
以上是new出一个bean的实例,bean的加载还未完成,因为还有一些属性需要注入。回到doCreateBean()方法,填充属性语句:
populateBean(beanName, mbd, instanceWrapper);

点进去,关键代码:
int resolvedAutowireMode = mbd.getResolvedAutowireMode(); if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; }// 将依赖实际注入 applyPropertyValues(beanName, mbd, bw, pvs);

一者是根据名称注入,一者是根据类型注入,注入后,pvs持有这些注入的属性信息,然后applyPropertyValues 注入属性,点击该方法,进去,核心代码:
bw.setPropertyValues(new MutablePropertyValues(deepCopy));

点进去,一路追踪到:
for (PropertyValue pv : propertyValues) { try { setPropertyValue(pv); } }

这就是属性注入了,属性注入后,bean就可以使用了,后面还有一些个性化设置,这里不涉足了。
收工~~

    推荐阅读