专栏名称: ImportNew
伯乐在线旗下账号,专注Java技术分享,包括Java基础技术、进阶技能、架构设计和Java技术领域动态等。
目录
相关文章推荐
Java编程精选  ·  患者带着DeepSeek来看病,医学博主自嘲 ... ·  3 天前  
Java编程精选  ·  巧用 SpringEvent 解决 ... ·  2 天前  
芋道源码  ·  目前对Grok 3分析最为透彻的一篇文章 ·  2 天前  
51好读  ›  专栏  ›  ImportNew

Spring 源码分析 : 非懒加载的单例 Bean 初始化过程 ( 下 ) ( 1 )

ImportNew  · 公众号  · Java  · 2017-04-24 14:30

正文

(点击 上方公众号 ,可快速关注)


来源:五月的仓颉,

www.cnblogs.com/xrq730/p/6363055.html

如有好文章投稿,请点击 → 这里了解详情


doCreateBean方法


上文《 Spring源码分析:非懒加载的单例Bean初始化过程(上) 》,分析了单例的Bean初始化流程,并跟踪代码进入了主流程,看到了Bean是如何被实例化出来的。先贴一下AbstractAutowireCapableBeanFactory的doCreateBean方法代码:


protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {

// Instantiate the bean.

BeanWrapper instanceWrapper = null;

if (mbd.isSingleton()) {

instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);

}

if (instanceWrapper == null) {

instanceWrapper = createBeanInstance(beanName, mbd, args);

}

final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);

Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

// Allow post-processors to modify the merged bean definition.

synchronized (mbd.postProcessingLock) {

if (!mbd.postProcessed) {

applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

mbd.postProcessed = true;

}

}

// Eagerly cache singletons to be able to resolve circular references

// even when triggered by lifecycle interfaces like BeanFactoryAware.

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");

}

addSingletonFactory(beanName, new ObjectFactory() {

public Object getObject() throws BeansException {

return getEarlyBeanReference(beanName, mbd, bean);

}

});

}

// 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);

}

}

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(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.");

}

}

}

}

// Register bean as disposable.

try {

registerDisposableBeanIfNecessary(beanName, bean, mbd);

}

catch (BeanDefinitionValidationException ex) {

throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);

}

return exposedObject;

}


下面继续分析初始化一个Bean的流程,不太重要的流程就跳过了。


属性注入


属性注入的代码比较好找,可以看一下40行,取名为populateBean,即填充Bean的意思,看一下代码实现:


protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {

PropertyValues pvs = mbd.getPropertyValues();

if (bw == null) {

if (!pvs.isEmpty()) {

throw new BeanCreationException(

mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");

}

else {

// Skip property population phase for null instance.

return;

}

}

// 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);

}


这段代码层次有点深,跟一下74行的applyPropertyValues方法,最后那个pvs的实现类为MutablePropertyValues,里面持有一个List ,每一个PropertyValue包含了此Bean属性的属性名与属性值。74行的代码实现为:


protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {

if (pvs == null || pvs.isEmpty()) {

return;

}

MutablePropertyValues mpvs = null;

List original;

if (System.getSecurityManager()!= null) {

if (bw instanceof BeanWrapperImpl) {

((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());

}

}

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 deepCopy = new ArrayList (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 == 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);

}

}


之后在第41行~第76行做了一次深拷贝(只是名字叫做深拷贝而已,其实就是遍历PropertyValue然后一个一个赋值到一个新的List而不是Java语义上的Clone,这里使用深拷贝是为了解析Values值中的所有引用),将PropertyValue一个一个赋值到一个新的List里面去,起名为deepCopy。最后执行83行进行复制,bw即BeanWrapper,持有Bean实例的一个Bean包装类,看一下代码实现:


public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)

throws BeansException {

List propertyAccessExceptions = null;

List propertyValues = (pvs instanceof MutablePropertyValues ?

((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));

for (PropertyValue pv : propertyValues) {

try {

// This method may throw any BeansException, which won't be caught







请到「今天看啥」查看全文