目录

一:触发方式:

二:源码解析

2.1 扫描注入点

2.2 属性赋值


一:触发方式:

1.Spring容器在每个Bean实例化之后,调用AutowireAnnotationBeanPostProcessor的postProcessMergedBeanDefinition方法进行扫描注入点

2.Spring在每个Bean实例化之后,扫描完注入点之后,调用populateBean进行Bean注入,调用postProcessPropertyValues方法

二:源码解析

2.1 扫描注入点

通过在属性、构造方法、set方法上添加@Autowire注解可以将Bean进行依赖注入。

package service;import org.springframework.beans.factory.annotation.Autowired;public class UserService1 {@Autowiredprivate  OrderService orderService;public void test(){System.out.println(orderService);}}

首先先查找注入点,在创建Bean时,实例化后,调用

AbstractAutowireCapableBeanFactory.javaprotected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {....if (!mbd.postProcessed) {try {//todo 在实例化后,对MergeBeanDefinition进行属性修改applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;}..}

进入applyMergedBeanDefinitionPostProcessors方法中,调用processor.postProcessMergedBeanDefinition(mbd,beanType,beanName);

 protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);}}

处理@Autowire注解的类时AutowiredAnnotationBeanPostProcessor

进入findAutowiringMetadata(beanName,beanType,null);

buildAutowiringMetadata(final Class<?> clazz) 方法中,循环遍历属性和循环遍历方法

,其中属性和方法不能是静态的 ,将field和required封装成一个AutowireFieldElement的一项,加入到currElements,最后合并成elements

以上就是依赖注入寻找注入点的过程,还没进行属性赋值

2.2 属性赋值

在Bean的实例化之后,进行循环依赖、属性填充、初始化、销毁bean。

进入到 populateBean(beanName, mbd, instanceWrapper);

主要根据postProcessProperties 进行属性注入

在这里找注入点、属性赋值。查找注入点上面分析过,下面分析属性赋值。

@Autowire注解加在field上的inject()方法在AutowiredFieldElement内部类中

第一次没有缓存进入到resolveFieldValue(field,bean,beanName)中,缓存针对于原型bean,因为单例bean只会创建一次,属性也是注入一次。

最终在DefaultListableBeanFactory.java中 将bean找到返回

1.首先处理@Value注解

2.判断是不是Map、List复杂Bean,其中还是调用findAutowireCandidates方法,根据类型去Spring容器中去找

Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,new MultiElementDescriptor(descriptor));

3.根据类型去Spring容器中找Bean,返回的key为beanName,value有可能是bean对象,有可能是bean class

Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);

4.如果matcingbeans.size >1 根据类型找到多个bean时,再根据name去找,调用

determineAutowireCandidate 方法,先去判断有没有加@primary注解 ,如果有则返回这个bean,然后再判断这个bean的优先级,再匹配descriptor的名字,要么是字段的名字,要么是set方法入参的名字。最终返回这个beanName,如果这些注解都没有加则返回null。

5.如果第四步返回的bull,并且没有配置@Autowire(required=false) 并且 beans不是复杂类型,则抛异常  expected single matching bean but found beanName

6.根据beanName,获取bean /bean class 返回

Spring @Autowire注解源码详解相关推荐

  1. 【JAVA秘籍心法篇-Spring】Spring XML解析源码详解

    [JAVA秘籍心法篇-Spring]Spring XML解析源码详解 所谓天下武功,无坚不摧,唯快不破.但有又太极拳法以快制慢,以柔克刚.武功外式有拳打脚踢,刀剑棍棒,又有内功易筋经九阳神功.所有外功 ...

  2. Spring事务源码详解

    一. 简介 事务: 事务是逻辑上的一组操作,要么都执行,要么都不执行,关于事务的基本知识可以看我的这篇文章:事务的基础知识 Spring事务: Spring 支持两种方式的事务管理:编程式事务管理.声 ...

  3. 封装成jar包_通用源码阅读指导mybatis源码详解:io包

    io包 io包即输入/输出包,负责完成 MyBatis中与输入/输出相关的操作. 说到输入/输出,首先想到的就是对磁盘文件的读写.在 MyBatis的工作中,与磁盘文件的交互主要是对 xml配置文件的 ...

  4. 【Live555】live555源码详解(九):ServerMediaSession、ServerMediaSubsession、live555MediaServer

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的三个类所在的位置: ServerMediaSession.ServerMediaSubsession.Dy ...

  5. 【Live555】live555源码详解系列笔记

    [Live555]liveMedia下载.配置.编译.安装.基本概念 [Live555]live555源码详解(一):BasicUsageEnvironment.UsageEnvironment [L ...

  6. 【Live555】live555源码详解(八):testRTSPClient

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的testRTSPClient实现的三个类所在的位置: ourRTSPClient.StreamClient ...

  7. 【Live555】live555源码详解(七):GenericMediaServer、RTSPServer、RTSPClient

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的三个类所在的位置: GenericMediaServer.RTSPServer.RTSPClient 14 ...

  8. 【Live555】live555源码详解(六):FramedSource、RTPSource、RTPSink

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的三个类所在的位置: FramedSource.RTPSource.RTPSink 11.FramedSou ...

  9. 【Live555】live555源码详解(五):MediaSource、MediaSink、MediaSession、MediaSubsession

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的四个类所在的位置: MediaSource.MediaSink.MediaSession.MediaSub ...

最新文章

  1. 用Linux构建高效FTP服务器(2)
  2. python知识点 07-11
  3. 独家专访 | 红布林(Plum​)庞博:万亿元二手时尚交易蓝海的生存法则
  4. android:persistent (非系统app失效)
  5. Listener refused the connection with the following error 错误解决(最大连接数)
  6. springboot+flowable第四节(设置监听事件)
  7. Linux USB驱动框架分析
  8. python-学生管理系统--3删除学生信息功能
  9. 禁止浏览器记录 文本框之前输入过的内容
  10. vue3 实现的砸金蛋
  11. java openoffic excel转html,Java利用OpenOffice進行將word,excel轉化成html解析到界面(上)...
  12. Android校招复习资料整理
  13. 模拟电路9(微变等效电路法对共射基本放大电路进行分析)
  14. bittorrent_面向初学者的BitTorrent:充分利用Internet连接
  15. 应届毕业生找Python工作遇到的难题,刚毕业没有工作经验该怎么办?
  16. 金属学复习【1】金属的晶体结构
  17. html如何制作美观搜索栏,css制作好看的搜索框
  18. 通过和resnet18和resnet50理解PyTorch的ResNet模块
  19. 如何在Python中获取图片分辨率?——Python实现获取图片分辨率的代码及详解。
  20. 基于百度英伟达EasyDL公开课的学习笔记

热门文章

  1. 营业执照正本与副本的区别
  2. 最好的数据恢复软件应该具备深度恢复技术
  3. 安卓实现天天动听音乐播放歌词悬浮哦(转)
  4. Android BitmapShader实现圆角、圆形ImageView
  5. 查询CNAPS 代码
  6. 分解变频电源的原理性
  7. macbook 关于微信突然打开白屏
  8. 【GNN】应用场景总结
  9. 微信测试账户的申请,以及配置失败问题的处理,最新
  10. android打包报错 AAPT: error: IDAT: incorrect data check. AAPT: error: file failed to compile.