深入理解Spring IOC(六)、 bean的填充以及初始化工作

780 阅读11分钟

之前的文章:

1、深入理解Spring IOC(一) 、统一资源的加载

2、深入理解Spring IOC(二) 、从xml到BeanDefinition

3、深入理解Spring IOC(三) 、refresh方法中实例化前的准备工作

4、深入理解Spring IOC(四)、 实例化开启

5、深入理解Spring IOC(五) 、 创建bean实例

如果你已经看到了这里并且把之前的都看明白了,那么恭喜你,最难的地方你已经搞定了。现在在整个spring ioc的流程中,对你来说应该不会再有太难的了,同时再去看spring的其他模块的源码,也相对会容易一些,尤其是其他框架和Spring整合的代码。如果没有看懂的也别着急,你可以把本篇看完,然后回过头去再去看之前的,源码也很少有人一遍就能看明白,我自己看这块的源码也是看了很多遍以及debug了很多遍才明白的。

真的需要你的一个赞来鼓励一下,因为写这种源码解析真的太太太太不容易了😢,谁写谁知道。

回到正题,我们上一篇主要说了doCreateBean中的createBeaninstance这个方法,这个方法为我们创建了未被填充的bean实例,本篇我们来看已经创建出来的bean实例是怎样被填充以及初始化的。

我们回到doCreateBean方法中,我再把这个方法代码贴一下,其中,1处上篇已经讲过,我们直接来看第2处

                                        代码块1
                                            
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
	
	// BeanWrapper是bean的包装类
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		// 从正在创建的factoryBean的缓存中移除(准确说其实是去拿,同时移除)
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		// 1. 如果到这里是null,则去创建一个包含着bean实例的instanceWrapper
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
	Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

	// 使用MergedBeanDefinitionPostProcessor修改RootBeanDefinition
	// 主要是处理@Autowired 、 @inject 、@value 标着的方法和属性
	// 从这里往后,spring 才知道是哪个方法或者是属性有这个注解
	// 这里的具体的代码解析不再贴出来(因为不是重点),在我第一篇的github上面你也可以自己下载源码来看,里面都有注释
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			mbd.postProcessed = true;
		}
	}

	// earlySingletonExposure是判断是否要提前曝光这个半成品的实例的,注意哈:现在的bean只是个半成品
	// 因为还没有进行属性填充,以及执行初始化方法等操作
	// mbd是单例 && 允许循环引用(默认true) && 当前bean是不是正在创建中
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		if (logger.isDebugEnabled()) {
			logger.debug("Eagerly caching bean '" + beanName +
					"' to allow for resolving potential circular references");
		}
		// 提前曝光这个beanName对应的ObjectFactory,用来解决循环引用
		addSingletonFactory(beanName, new ObjectFactory<Object>() {
			@Override
			public Object getObject() throws BeansException {
				// 2.使用SmartInstantiationAwareBeanPostProcessor返回早期bean的半成品时的引用
				// 如果没有SmartInstantiationAwareBeanPostProcessor,则直接返回bean
				// 这里返回的最终是bean本身
				return getEarlyBeanReference(beanName, mbd, bean);
			}
		});
	}

	// 初始化
	Object exposedObject = bean;
	try {
		// 3. 对bean进行属性填充
		populateBean(beanName, mbd, instanceWrapper);
		if (exposedObject != null) {
			// 4. 初始化操作
			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) {
				// 由于经过init之后的操作,earlySingletonReference和exposedObject可能不是一个实例,
				// 这里需要让他们指向一个实例,
				exposedObject = earlySingletonReference;
			// 不允许在循环依赖情况下注入原始bean && 当前bean被其他bean依赖
			}else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
				// 拿到当前bean依赖所有bean的数组
				String[] dependentBeans = getDependentBeans(beanName);
				Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
				for (String dependentBean : dependentBeans) {
					// 移除这些bean,因为这些bean依赖的bean是被增强过的bean
					if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
						// 移除失败的添加到actualDependentBeans
						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 {
		// 注册用于销毁的bean,
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	}catch (BeanDefinitionValidationException ex) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
	}

	return exposedObject;
}

代码块1中2处

                                        代码块2
                                        
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
	Object exposedObject = bean;
	
	// bean不是null && mbd不是合成 && 有InstantiationAwareBeanPostProcessor
	if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
	
		// 遍历执行BeanPostProcessor
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
				SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
				// 具体的处理逻辑位于AutowiredAnnotationBeanPostProcessor中,它继承了这个方法,最终返回的还是是bean本身,
				// 注意:如果有别的实现了SmartInstantiationAwareBeanPostProcessor就未必了
				exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
				if (exposedObject == null) {
					return exposedObject;
				}
			}
		}
	}
	return exposedObject;
}

此时我相信这里你肯定是可以看明白的

代码块1中3处

这个populateBean方法,即是处理属性注入的地方,@Autowired,@Resource,@Value,甚至是当你使用Dubbo框架的时候@Reference都是在这里处理注入的,我们一起看看这个方法:

                                        代码块3
                                        
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
	PropertyValues pvs = mbd.getPropertyValues();
	// 进行基本的校验,bw为null时
	if (bw == null) {
		// 如果有属性值,则抛异常
		if (!pvs.isEmpty()) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
		// 否则 结束方法
		}else {
			return;
		}
	}

	// 是否继续填充属性的标记
	boolean continueWithPropertyPopulation = true;
	// mbd是否为合成 && 是否存在InstantiationAwareBeanPostProcessor
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				// postProcessAfterInstantiation这个方法是在bean实例化后属性填充之前调用
				// 返回的是true,说明应该进行属性填充,false说明不应该
				if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					continueWithPropertyPopulation = false;
					break;
				}
			}
		}
	}
	// 如果不该继续填充了则直接返回
	if (!continueWithPropertyPopulation) {
		return;
	}
	// 这个是处理xml中autowire的值为byname 和 byType的逻辑
	// 可以看出来只有xml的才会走这里,注解的没有byName 和 byType这样的属性
	if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
			mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
		MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

		// 1.byName的处理
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
			autowireByName(beanName, mbd, bw, newPvs);
		}

		// 2.byType的处理
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			autowireByType(beanName, mbd, bw, newPvs);
		}
		pvs = newPvs;
	}

	// 是否有InstantiationAwareBeanPostProcessors
	boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
	// 是否需要依赖检查
	boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
	if (hasInstAwareBpps || needsDepCheck) {
		PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
		if (hasInstAwareBpps) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					// 用InstantiationAwareBeanPostProcessor的后置处理来进行属性的填充
					// 这里进行的是属性填充前最后一步的处理,@AutoWired就是在这里进行处理的
					// 也就是说这里会对@Autowired的属性进行初始化,然后加到pvs中来
					// 当然,@Resource也是在这里处理的,只是用的BeanPostProcessor不是一个
					// 注:@Autowired的处理逻辑在AutowiredAnnotationBeanPostProcessor中,而
					// @Resource的在CommonAnnotationBeanPostProcessor里
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvs == null) {
						return;
					}
				}
			}
		}
		if (needsDepCheck) {
			// 对filteredPds里面的属性进行依赖检查
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}
	}
	// 3.进行填充操作
	applyPropertyValues(beanName, mbd, bw, pvs);
}

这个代码块中的1、2个,是针对xml中bean标签的autowire属性的,虽然现在用的很少了,但是本着完整的原则,还是来看看它:

代码块3中1处

                                        代码块4

protected void autowireByName(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
	// 获取需要注入的属性的名称
	String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
	for (String propertyName : propertyNames) {
		// 如果现在beanFactory容器中有这个propertyName对应的bean或者是
		// 对应的beanDefinition
		if (containsBean(propertyName)) {
			// 则去初始化这个bean
			Object bean = getBean(propertyName);
			// 将所依赖的bean加入pvs容器中以备后续使用
			pvs.add(propertyName, bean);
			// 注册依赖关系
			registerDependentBean(propertyName, beanName);
			if (logger.isDebugEnabled()) {
				logger.debug("Added autowiring by name from bean name '" + beanName +
						"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
			}
		}
		else {
			if (logger.isTraceEnabled()) {
				logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
						"' by name: no matching bean found");
			}
		}
	}
}

代码块3中2处

                                        代码块5
                                        
protected void autowireByType(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

	// 拿自定义的TypeConverter,如果为空,则用bw做TypeConverter
	TypeConverter converter = getCustomTypeConverter();
	if (converter == null) {
		converter = bw;
	}

	Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
	// 拿到需要注入的属性的名称
	String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
	for (String propertyName : propertyNames) {
		try {
			// 拿到bw的对应这个propertyName的PropertyDescriptor
			PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
			// 如果pd是个Object类型的,则不注入这个。原因是如果是Object,你找到的参数即使类型不匹配
			// 也能注入成功。。
			if (!Object.class.equals(pd.getPropertyType())) {
				MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
				// Do not allow eager init for type matching in case of a prioritized post-processor.
				boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
				DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
				// 真正的解析过程
				Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
				// 把解析成功的参数放到pvs里
				if (autowiredArgument != null) {
					pvs.add(propertyName, autowiredArgument);
				}
				for (String autowiredBeanName : autowiredBeanNames) {
					registerDependentBean(autowiredBeanName, beanName);
					if (logger.isDebugEnabled()) {
						logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
								propertyName + "' to bean named '" + autowiredBeanName + "'");
					}
				}
				autowiredBeanNames.clear();
			}
		}
		catch (BeansException ex) {
			throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
		}
	}
}

代码块3中3处

到了3.3这里,spring已经知道了bean的哪个属性需要注入,并且注入的值已经拿到,我们来看看这里的代码:

                                        代码块6
                                      
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
	// 如果pvs为空过直接返回
	if (pvs == null || pvs.isEmpty()) {
		return;
	}

	MutablePropertyValues mpvs = null;
	List<PropertyValue> original;
	
	if (System.getSecurityManager() != null) {
		if (bw instanceof BeanWrapperImpl) {
			((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
		}
	}

	if (pvs instanceof MutablePropertyValues) {
		mpvs = (MutablePropertyValues) pvs;
		// 如果mpvs的属性值已经被转换成为对应的类型,则可以直接去设置
		if (mpvs.isConverted()) {
			try {
				// 这里也是为什么使用BeanWrapper而不是使用beanInstance的原因
				// 因为BeanWrapper实现了PropertyAccessor接口,可以直接给set值
				// 这块有兴趣的可以自行研究一下
				bw.setPropertyValues(mpvs);
				return;
			}catch (BeansException ex) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Error setting property values", ex);
			}
		}
		original = mpvs.getPropertyValueList();
	}else {
		// 获取原始的属性
		original = Arrays.asList(pvs.getPropertyValues());
	}

	TypeConverter converter = getCustomTypeConverter();
	if (converter == null) {
		converter = bw;
	}
	// 获取解析器
	BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

	// 对原始属性进行深拷贝,避免修改后引起的原始属性值修改
	// deepcopy是后边直接用作给bean填充属性的
	List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
	boolean resolveNecessary = false;
	for (PropertyValue pv : original) {
		// 如果某个属性被转换过则直接加入deepCopy
		if (pv.isConverted()) {
			deepCopy.add(pv);
		// 否则的话进行转换
		}else {
			// 拿到原始属性值和属性名称
			String propertyName = pv.getName();
			Object originalValue = pv.getValue();
			// 并进行解析,并进行必要的解析
			Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
			Object convertedValue = resolvedValue;
			// propertyName对应的属性是个可以写的 && 不能是嵌套属性或者下标属性
			boolean convertible = bw.isWritableProperty(propertyName) &&
					!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
			if (convertible) {
				convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
			}
			// 将转换过的值存起来避免重新转换
			if (resolvedValue == originalValue) {
				if (convertible) {
					pv.setConvertedValue(convertedValue);
				}
				deepCopy.add(pv);
			}else if (convertible && originalValue instanceof TypedStringValue &&
					!((TypedStringValue) originalValue).isDynamic() &&
					!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
				pv.setConvertedValue(convertedValue);
				deepCopy.add(pv);
			}else {
				resolveNecessary = true;
				deepCopy.add(new PropertyValue(pv, convertedValue));
			}
		}
	}
	// 将converted设置为true
	if (mpvs != null && !resolveNecessary) {
		mpvs.setConverted();
	}

	// 用deepCopy里的值来进行属性填充
	try {
		bw.setPropertyValues(new MutablePropertyValues(deepCopy));
	}catch (BeansException ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Error setting property values", ex);
	}
}

这下doCreateBean中对bean的填充也完了,其实对bean的工作都是在BeanPostProcessor中完成的,在populateBean这个方法中只是对BeanPostProcessor的方法进行了调用而已。我们继续看1.4处,这个方法主要是针对bean的初始化的。

代码块1中4处

                                        代码块7
                                      
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
		// 调用几个Aware接口
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				@Override
				public Object run() {
					// 1.调用aware
					invokeAwareMethods(beanName, bean);
					return null;
				}
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}
		
		// 2.调用所有的BeanPostProcessor的postProcessBeforeInitialization
		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			// 3.调用InitializingBean的方法和自定义初始化方法
			invokeInitMethods(beanName, wrappedBean, mbd);
		}catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}

		// 4.执行所有BeanPostProcessor的postProcessAfterInitialization方法
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		return wrappedBean;
	}

第1处主要是调用aware接口,aware接口我也会去写文章专门介绍,我们这会先来看这个方法做了什么:

代码块7中1处

                                        代码块8
                                      
private void invokeAwareMethods(final String beanName, final Object bean) {
	// 所谓的xxxAware,就是让这个bean和xxx产生关联
	if (bean instanceof Aware) {
		// 设置名称
		if (bean instanceof BeanNameAware) {
			((BeanNameAware) bean).setBeanName(beanName);
		}
		// 类加载器
		if (bean instanceof BeanClassLoaderAware) {
			((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
		}
		// 我们有时候使用BeanFactoryAware去拿BeanFactory,就是在这步设置的
		if (bean instanceof BeanFactoryAware) {
			((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
		}
	}
}

代码块7中2处

                                        代码块9
                                      
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {

	Object result = existingBean;
	// 调用所有的BeanPostProcessor的postProcessBeforeInitialization(前置处理)方法
	// 其中@PostConstruct就是在CommonAnnotationBeanPostProcessor中执行的
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		result = beanProcessor.postProcessBeforeInitialization(result, beanName);
		if (result == null) {
			return result;
		}
	}
	return result;
}

代码块7中3处

这个方法主要是执行初始化方法,主要执行@InitialBean中的初始化方法和自定义的初始化方法:

                                        代码块10
                                      
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
			throws Throwable {
	// 调用InitializingBean的afterPropertiesSet方法,还是特权调用和普通调用
	boolean isInitializingBean = (bean instanceof InitializingBean);
	if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
		if (logger.isDebugEnabled()) {
			logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
		}
		if (System.getSecurityManager() != null) {
			try {
				AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
					@Override
					public Object run() throws Exception {
						// 
						((InitializingBean) bean).afterPropertiesSet();
						return null;
					}
				}, getAccessControlContext());
			}
			catch (PrivilegedActionException pae) {
				throw pae.getException();
			}
		}
		else {
			((InitializingBean) bean).afterPropertiesSet();
		}
	}
	
	
	if (mbd != null) {
		String initMethodName = mbd.getInitMethodName();
		if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
				!mbd.isExternallyManagedInitMethod(initMethodName)) {
			// 调用自定义的初始化方法,主要是通过反射调用
			invokeCustomInitMethod(beanName, bean, mbd);
		}
	}
}

代码块7中4处

这个方法也是初始化的最后一步

                                        代码块11
                                      
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {
	// 执行所有BeanPostProcessor的postProcessAfterInitialization(后置处理)方法
	Object result = existingBean;
	// 遍历执行
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		result = beanProcessor.postProcessAfterInitialization(result, beanName);
		if (result == null) {
			return result;
		}
	}
	return result;
}

至此,xml中bean的加载解析我们已经讲完,下一篇,我们将对整个流程做个总结,以及扩充一些面试涉及到的点,以让你更好的理解bean加载的整个流程。