首页 > 代码库 > spring bean的装载过程简略赏析
spring bean的装载过程简略赏析
spring一个bean的容器,它从这个最基本的功能进而扩展出AOP,transaction,cache,schedule,data等等,将业务与框架代码解耦,让我们可以将大部分精力投入到业务代码中,这是一个伟大的开源项目,带着这份感激与赞美之情,来看一spring最基本的功能--bean的装载:
我们知道,spring在1与2时使用xml等配置文件来配置bean的声明,而3以后,spring则引入注解,大大简化了bean的繁杂的配置,bean的装载部分并没有发生本质上的变化,只是稍稍做了一些改动。
如何读取bean,这部分在本篇不打算详细介绍。简单说明一下流程:spring获取bean信息(具体是配置文件还是注解按具体场景决定),将bean信息赋予BeanDefifition,这个类是关键,它承载了bean的所有信息。
在拿到BeanDefinition后,spring便开始装载之旅,首先看下AbstractAutowireCapableBeanFactory.java
看doCreateBean方法
// Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { 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); } }
主要看上面这部分代码,一个是populateBean,一个是initializeBean,这两个方法完成了bean的赋值与初始化。先看populateBean:
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the // state of the bean before properties are set. This can be used, for example, // to support styles of field injection. boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } if (!continueWithPropertyPopulation) { return; } if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } applyPropertyValues(beanName, mbd, bw, pvs);
使用spring,就一定会知道spring有一系列aware,比如(beanNameAware,beanFactoryAware,aplicationContextArware,enviromentAware等等)。这些aware使得代码与spring框架耦合,带来的好处就是能让代码使用spring框架提供的强大功能,在这里,调用了实现了InstantiationAwareBeanPostProcessor接口的实例中的postProcessAfterInstantiation方法,我们可以看到,这个方法的调用是发生在实例化之后但未给实例赋值的时候,spring通过这样的方式为我们留出了一系列接口,让我们能在bean生命周期的各个阶段参与进来,此外,也为spring自己提供了强大的扩展性,spring aop就是基于一系列的postBeanProcess来做处理的,这个后续会详细指出。
到此,我们发现并没有发生真正的赋值,真正的赋值逻辑在 applyPropertyValuesf方法中:
if (pvs instanceof MutablePropertyValues) { mpvs = (MutablePropertyValues) pvs; if (mpvs.isConverted()) { // Shortcut: use the pre-converted values as-is. try { 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); // Create a deep copy, resolving any references for values. List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size()); boolean resolveNecessary = false; for (PropertyValue pv : original) { if (pv.isConverted()) { deepCopy.add(pv); } else { String propertyName = pv.getName(); Object originalValue = pv.getValue(); Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); Object convertedValue = resolvedValue; boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName); if (convertible) { convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter); } // Possibly store converted value in merged bean definition, // in order to avoid re-conversion for every created bean instance. if (resolvedValue =http://www.mamicode.com/= 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)); } } } if (mpvs != null && !resolveNecessary) { mpvs.setConverted(); } // Set our (possibly massaged) deep copy. try { bw.setPropertyValues(new MutablePropertyValues(deepCopy)); } catch (BeansException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Error setting property values", ex); }
这里有一个BeanDefinitionValueResolver,这个类用来解析property里的value,如果是依赖其他bean则会到容器中找是否存在如果有则返回,没有则创建一个。spring又为每个对象的属性定义了一个数据结构:PropertyValue,这样做加大了容器对bean属性的修改的灵活性,上面的方法就是对每个属性进行处理然后通过beanWapper的setPropertyValues进行赋值。
这里注意一下,bean有singleton和prototype两种 ,对于prototype,spring采用了原型模式,使用对象的deepcopy。
至此,spring完成了对实例的赋值,然后就是调用initializeBean:
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { invokeAwareMethods(beanName, bean); return null; } }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
我们看到,在initializeBean方法中,一开始就调用了invokeAwareMethods:
private void invokeAwareMethods(final String beanName, final Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader()); } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }
这些aware发生在对象被赋值以后了,接下来,调用了applyBeanPostProcessorsBeforeInitialization方法:
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { result = beanProcessor.postProcessBeforeInitialization(result, beanName); if (result == null) { return result; } } return result; }
我们看到,这里开始调用所有注册了beanProcessor的postProcessBeforeInitialization方法,这个方法的实现类列表中,我们看到了aop的身影,aop就是从这里开始参与进来的。接着,开始初始化bean,调用invokeInitMethods方法,
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable { 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>() { 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); } } }
这里调用了实现了InitializingBean中的afterPropertySet方法,这个比较常用。
最后再调用applyBeanPostProcessorsAfterInitialization方法,同样上面一样,循环遍历调用注册了beanPostProcessor的方法,最后返回一个处理完成的bean实例,至此,一个完成的bean的装载过程已经完成。
以上是我个人理解,因技术尚有不足,理解有误地方还望大家指正,多多交流,谢谢! 转载请注明出处!
spring bean的装载过程简略赏析