之前的文章:
2、深入理解Spring IOC(二) 、从xml到BeanDefinition
3、深入理解Spring IOC(三) 、refresh方法中实例化前的准备工作
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加载的整个流程。