这一讲分析spring bean属性注入代码populateBean,源码分析如下

    /*** Populate the bean instance in the given BeanWrapper with the property values* from the bean definition.* 丰富bean实例属性*@parambeanName the name of the bean*@parammbd the bean definition for the bean*@parambw BeanWrapper with bean instance*/protected voidpopulateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {PropertyValues pvs=mbd.getPropertyValues();if (bw == null) {if (!pvs.isEmpty()) {throw newBeanCreationException(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 instanceofInstantiationAwareBeanPostProcessor) {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= newMutablePropertyValues(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);//设置bean属性if (hasInstAwareBpps ||needsDepCheck) {PropertyDescriptor[] filteredPds=filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);if(hasInstAwareBpps) {for(BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceofInstantiationAwareBeanPostProcessor) {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);}

debug过程中我们知道,总共有7个BeanPostProcessor

对于@Autowired,@Value注解注入的属性值,AutowiredAnnotationBeanPostProcessor会处理。我们进一步分析AutowiredAnnotationBeanPostProcessor注入属性的代码

    /*** Autowired属性注入*@authorcoshaho *@parampvs*@parampds   注入属性配置,方法中没有使用*@parambean  bean实例*@parambeanName*@return*@throwsBeanCreationException*/publicPropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)throwsBeanCreationException {//获取注入属性配置信息InjectionMetadata metadata =findAutowiringMetadata(beanName, bean.getClass(), pvs);try{//属性注入
metadata.inject(bean, beanName, pvs);}catch(BeanCreationException ex) {throwex;}catch(Throwable ex) {throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);}returnpvs;}public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throwsThrowable {//获取待注入的属性队列Collection<InjectedElement> checkedElements = this.checkedElements;Collection<InjectedElement> elementsToIterate =(checkedElements!= null ? checkedElements : this.injectedElements);if (!elementsToIterate.isEmpty()) {boolean debug =logger.isDebugEnabled();for(InjectedElement element : elementsToIterate) {if(debug) {logger.debug("Processing injected element of bean '" + beanName + "': " +element);}//属性注入
element.inject(target, beanName, pvs);}}}

InjectionMetadata是bean注入属性配置,InjectionElement是单个的注入属性配置,InjectionElement.inject则为单个属性注入方法。InjectionElement.inject则调用的DefaultListableBeanFactory.doResolveDependency方法获取属性值

@Overrideprotected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throwsThrowable {Field field= (Field) this.member;Object value;if (this.cached) {value= resolvedCachedArgument(beanName, this.cachedFieldValue);}else{//获取注入属性配置:属性名称,类名称DependencyDescriptor desc = new DependencyDescriptor(field, this.required);desc.setContainingClass(bean.getClass());Set<String> autowiredBeanNames = new LinkedHashSet<>(1);Assert.state(beanFactory!= null, "No BeanFactory available");TypeConverter typeConverter=beanFactory.getTypeConverter();try{//获取属性值value =beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);}catch(BeansException ex) {throw new UnsatisfiedDependencyException(null, beanName, newInjectionPoint(field), ex);}synchronized (this) {if (!this.cached) {if (value != null || this.required) {this.cachedFieldValue =desc;registerDependentBeans(beanName, autowiredBeanNames);if (autowiredBeanNames.size() == 1) {String autowiredBeanName=autowiredBeanNames.iterator().next();if(beanFactory.containsBean(autowiredBeanName)) {if(beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {this.cachedFieldValue = newShortcutDependencyDescriptor(desc, autowiredBeanName, field.getType());}}}}else{this.cachedFieldValue = null;}this.cached = true;}}}if (value != null) {ReflectionUtils.makeAccessible(field);//反射设置属性
field.set(bean, value);}}publicObject resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throwsBeansException {descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());if (Optional.class ==descriptor.getDependencyType()) {returncreateOptionalDependency(descriptor, requestingBeanName);}else if (ObjectFactory.class == descriptor.getDependencyType() ||ObjectProvider.class ==descriptor.getDependencyType()) {return newDependencyObjectProvider(descriptor, requestingBeanName);}else if (javaxInjectProviderClass ==descriptor.getDependencyType()) {return newJsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);}else{Object result=getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);if (result == null) {//获取注入值result =doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);}returnresult;}}

    publicObject doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throwsBeansException {//注入属性配置InjectionPoint previousInjectionPoint =ConstructorResolver.setCurrentInjectionPoint(descriptor);try{Object shortcut= descriptor.resolveShortcut(this);if (shortcut != null) {returnshortcut;}//注入属性类型Class<?> type =descriptor.getDependencyType();// 如果是Value注解,这里可以直接获取注解String值Object value=getAutowireCandidateResolver().getSuggestedValue(descriptor);if (value != null) {if (value instanceofString) {String strVal=resolveEmbeddedValue((String) value);BeanDefinition bd= (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);// Value可以是一个表达式,表达式需要进行计算value=evaluateBeanDefinitionString(strVal, bd);}TypeConverter converter= (typeConverter != null ?typeConverter : getTypeConverter());// 此处对Value进行类型转换return (descriptor.getField() != null ?converter.convertIfNecessary(value, type, descriptor.getField()) :converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));}Object multipleBeans=resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);if (multipleBeans != null) {returnmultipleBeans;}//获取{bean名称:bean类型} Map,bean名称默认为类名称Map<String, Object> matchingBeans =findAutowireCandidates(beanName, type, descriptor);if(matchingBeans.isEmpty()) {if(isRequired(descriptor)) {raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);}return null;}String autowiredBeanName;Object instanceCandidate;if (matchingBeans.size() > 1) {autowiredBeanName=determineAutowireCandidate(matchingBeans, descriptor);if (autowiredBeanName == null) {if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {returndescriptor.resolveNotUnique(type, matchingBeans);}else{//In case of an optional Collection/Map, silently ignore a non-unique case://possibly it was meant to be an empty collection of multiple regular beans//(before 4.3 in particular when we didn't even look for collection beans).return null;}}instanceCandidate=matchingBeans.get(autowiredBeanName);}else{//We have exactly one match.Map.Entry<String, Object> entry =matchingBeans.entrySet().iterator().next();autowiredBeanName=entry.getKey();instanceCandidate=entry.getValue();}if (autowiredBeanNames != null) {autowiredBeanNames.add(autowiredBeanName);}//关键方法,bean名称不为空,通过bean名称,bean类型获取注入beanif (instanceCandidate instanceofClass) {instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);}Object result=instanceCandidate;if (result instanceofNullBean) {if(isRequired(descriptor)) {raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);}result= null;}if (!ClassUtils.isAssignableValue(type, result)) {throw newBeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());}returnresult;}finally{ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);}}

这里descriptor.resolveCandidate正好调用了bean创建方法。需要注意的是,autowire注入默认采用bean名称注入,bean名称默认为类名,首字母并不小写

转载于:https://www.cnblogs.com/coshaho/p/7687396.html

Spring源码阅读(六)相关推荐

  1. Spring源码-AOP(六)-自动代理与DefaultAdvisorAutoProxyCreator

    2019独角兽企业重金招聘Python工程师标准>>> Spring AOP 源码解析系列,建议大家按顺序阅读,欢迎讨论 Spring源码-AOP(一)-代理模式 Spring源码- ...

  2. spring源码阅读(3)-- 容器启动之BeanFactoryPostProcessor

    接着上文<spring源码阅读(2)-- 容器启动之加载BeanDefinition>,当spring加载完所有BeanDefinition时,并不会马上去创建bean,而是先配置bean ...

  3. mybatis源码阅读(六) ---StatementHandler了解一下

    转载自  mybatis源码阅读(六) ---StatementHandler了解一下 StatementHandler类结构图与接口设计 BaseStatementHandler:一个抽象类,只是实 ...

  4. 【Spring 源码阅读】Spring IoC、AOP 原理小总结

    Spring IoC.AOP 原理小总结 前言 版本约定 正文 Spring BeanFactory 容器初始化过程 IoC 的过程 bean 完整的创建流程如下 AOP 的过程 Annotation ...

  5. Spring源码阅读(一)——整体结构

    Spring 总共大约有20个模块,由1300多个不同的文件构成. Spring源码阅读可以分为三个路线:IOC,AOP,外部组件. 个人主页:tuzhenyu's page 原文地址:Spring源 ...

  6. Spring源码阅读之bean对象的创建过程

    Spring源码阅读之bean对象的创建过程 ​ Spring是通过IOC容器来管理对象的,该容器不仅仅只是帮我们创建了对象那么简单,它负责了对象的整个生命周期-创建.装配.销毁.这种方式成为控制反转 ...

  7. Spring源码阅读 源码环境搭建(一)

    ring 源码阅读的搭建(一) 一 下载spring源码 进入官方网页:https://spring.io/projects/spring-framework 进入相关的github位置,下载zip包 ...

  8. spring 源码阅读入门

    spring和源码3.0.5下载 http://download.csdn.net/download/haluoyimo/7752753 http://pan.baidu.com/s/1qYnK784 ...

  9. spring源码阅读--aop实现原理分析

    aop实现原理简介 首先我们都知道aop的基本原理就是动态代理思想,在设计模式之代理模式中有介绍过这两种动态代理的使用与基本原理,再次不再叙述. 这里分析的是,在spring中是如何基于动态代理的思想 ...

  10. Spring源码:Spring源码阅读环境搭建

    本篇内容包括:Mac 环境下 gradle 的安装和配置.源码克隆.新建测试类,测试Spring源码 等内容! 第一步:Mac 环境下 gradle 的安装和配置 1.下载安装包 # 到 GitHub ...

最新文章

  1. postgres语法_SQL Create Table解释了MySQL和Postgres的语法示例
  2. WP_Image_Editor_Imagick 漏洞临时解决方法
  3. boost信号量 boost::interprocess::interprocess_semaphore的用法
  4. ✅书单推荐の自我管理篇✅
  5. BeetleX之FastHttpApi服务使用详解
  6. React 深度学习:ReactFiber
  7. [android] 手机卫士设置向导页面
  8. 基于 HTML5 WebGL 的 3D 智慧隧道漫游巡检
  9. centos php mcrypt_面试经常问你什么是PHP垃圾回收机制?
  10. 在linux环境下com.aspose.words将word文件转为pdf后乱码,window环境下不会
  11. mes管理系统php原码,MES系统_MES车间管理系统_轻量化定制方案
  12. mac java 安装教程_mac 安装jdk1.8 附详细教程
  13. OA常见问题和解决方案
  14. 语音识别中特征提取MFCC、FBANK、语谱图特征提取
  15. LinuxC语言简单实现图片加马赛克-标准IO实现
  16. 创造者的品味 转自apple4.us
  17. 【毕业设计】大数据淘宝用户行为数据分析与可视化 - flink
  18. 华为鸿蒙OS5摄概念机,华为P50Pro概念图:首发鸿蒙OS,后置5摄能让iPhone12甘拜下风吗...
  19. PHP 免费获取手机号码归属地
  20. vue生成html页面,前端VUE页面快速生成

热门文章

  1. php 如何做ftp传输,php如何实现ftp上传
  2. 企业网络推广方法教你如何精准避免网站过度优化问题?
  3. 网络推广专员浅析到2021年底至少3亿台华为设备将使用鸿蒙系统
  4. 网站被K的解决方案有哪些?
  5. 浅析如何才能提高网站的信息交互能力?
  6. 新站优化远比老站难的多!
  7. html制作滚动游戏,HTML标签marquee实现滚动效果的简单方法(必看)
  8. 主题图片_临床医学院“树树皆秋色,山山唯落晖”主题图片征集活动
  9. 理想的计算机职业作文100,我的理想作文100字(通用30篇)
  10. 开发日记-20190915 关键词 汇编语言王爽版 第十三章