昨晚在使用JUnit测试AOP实现时,出现一个问题。在JUnit使用@AutoWired注入某一个对象,Bean Factory里面有该接口的多个实现,Spring不报错,而始终注入的是一个实现类的实例。
这种只能分析一下Spring @AutoWired的实现原理来解决了。

1. 在JUnit测试用例实现下setter方法,使用setter进行注入
2. 在setter方法上添加断点
3. 断点跟踪调试

下面是分析过程:
------------

@AutoWired注解源码分析:

1. Spring为ITestServicce注入对象
Spring调用AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(Object, String, PropertyValues) line: 600

2. 获取注入的setter方法
3. 获取setter方法要注入的参数
4. Spring调用BeanFactory的resolveDependency分析ITestService的依赖
5. BeanFactory调用findAutowiredCandidates为com.itheima.service.TestQ查找ITestService的候选Bean
6. 找到三个候选人[testService2, testService, testServiceProxy]
7. BeanFactory调用determineAutowireCandidate/determinePrimaryCandidate来选择一个匹配的候选Bean(找@Primary标记的bean)
/**
* Return whether the bean definition for the given bean name has been
* marked as a primary bean.
* @param beanName the name of the bean
* @param beanInstance the corresponding bean instance (can be null)
* @return whether the given bean qualifies as primary
*/
8. BeanFactory调用determineHighestPriorityCandidate来选择一个优先级最高的候选Bean(Bean要实现Ordered接口)
/**
* Determine the candidate with the highest priority in the given set of beans. As
* defined by the {@link org.springframework.core.Ordered} interface, the lowest
* value has the highest priority.
* @param candidateBeans a Map of candidate names and candidate instances
* that match the required type
* @param requiredType the target dependency type to match against
* @return the name of the candidate with the highest priority,
* or {@code null} if none found
* @see #getPriority(Object)
*/
9. 根据field或者setter参数的名称进行匹配,如果名字匹配上了,就返回指定的对象,如果没找到则报错。
/**
* Determine the name of the wrapped parameter/field.
* @return the declared name (never {@code null})
*/

被@AutoWired修饰的field或者是setter,如果名字和某一个BeanFactory中的name/id一致,则即使有个实现,也会获取到对应那个名称的Bean。

根据源码分析,要解决代理无法注入的方法有三种:
1. 在代理的<bean>上添加primary="true"属性
2. 使用@Qualifier或者@Resource指定要注入的bean的名字

转载于:https://www.cnblogs.com/ilovezihan/p/7232076.html

Spring @AutoWired实现原理相关推荐

  1. Java微框架Spring Boot 运行原理深入解读

    本文节选自< JavaEE开发的颠覆者--Spring Boot实战 >一书.本书从Spring 基础.Spring MVC 基础讲起,从而无难度地引入Spring Boot 的学习.涵盖 ...

  2. @autowired注解原理_SpringBoot注解大全,收藏一波!!!

    一.注解(annotations)列表 二.注解(annotations)详解 三.JPA注解 四.springMVC相关注解 五.全局异常处理 <Java 2019 超神之路> < ...

  3. Spring异步调用原理及SpringAop拦截器链原理

    一.Spring异步调用底层原理 开启异步调用只需一个注解@EnableAsync @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTI ...

  4. spring Mvc 执行原理 及 xml注解配置说明 (六)

    Spring MVC 执行原理 在 Spring Mvc 访问过程里,每个请求都首先经过 许多的过滤器,经 DispatcherServlet 处理; 一个Spring MVC工程里,可以配置多个的 ...

  5. 【Spring】Spring底层核心原理解析

    本文内容索引: 1.Bean的生命周期底层原理 2.依赖注入底层原理 3.初始化底层原理 4.推断构造方法底层原理 5.AOP底层原理 6.Spring事务底层原理 ​但都只是大致流程,后续会针对每个 ...

  6. Spring底层核心原理

    Spring底层整体了解 Bean的生命周期底层原理 依赖注入底层原理 初始化底层原理 推断构造底层原理 AOP底层原理 Spring事务底层原理 Spring是如何创建一个对象的 Annotatio ...

  7. Spring源码学习(一)--Spring底层核心原理解析

    目录 Spring中是如何创建一个对象? Bean的创建过程 推断构造方法 AOP大致流程 Spring事务 最近在跟视频学习spring源码,将每节课记录下来,以后好来复习. 首先把Spring中核 ...

  8. spring 常用注解 原理 逻辑 代码演示

    01 spring 常用注解 原理 逻辑 代码演示 这是自己观看视频的笔记 文章目录 01 spring 常用注解 原理 逻辑 代码演示 一.组件注册 1.1-spring注解驱动开发 1.2-组件注 ...

  9. Java程序员进阶——Spring依赖注入原理分析

    Spring依赖注入原理分析 下面谈谈Spring是如何实现反转模式IOC或依赖注入模式DI: 平时,我们需要生成一个对象,使用new语法,如一个类为A public class A{public v ...

最新文章

  1. 正则表达式学习实例1
  2. 嵌入式开发板老化过程中显示温度与负载的关系脚本的用法
  3. 单机搭建Android开发环境(五)
  4. JAVA实现可设置背景的MDI窗口
  5. 使用Java 8 Lambda清理JUnit Throwable-Tests
  6. 如何让你变得魅力十足
  7. PHP文件下载过滤类
  8. ViewStub延迟加载
  9. 国赛助力:第三类边界条件热传导方程及基于三对角矩阵的数值计算MATLAB实现(2020A)
  10. 强烈推荐的GitHub浏览插件-Octotree
  11. 视频教程-思科路由器搭建终极实战-网络技术
  12. sql server 代理权限问题
  13. 微软商店安装包_闲着不如折腾,教你现在就尝鲜年底才发售的「微软双屏手机」...
  14. quartz2.2.3 spring整合遇到的错误,及quartz配置文件说明
  15. 【构建ML驱动的应用程序】第 5 章 :训练和评估模型
  16. 浅谈LCD液晶屏和LED屏,它们有什么不同之处
  17. linux shell ifs,Shell 的 IFS 变量
  18. ios swiftui_ios swiftui中的本地化
  19. JavaScript 入门
  20. 丘成桐大学生数学竞赛2014年分析与方程个人赛试题第一题另解

热门文章

  1. 开源视频平台:ViMP
  2. gdb php-fpm,用gdb分析段错误(Segmentation fault)
  3. Python for循环中使用index索引
  4. 【CCCC】L2-020 功夫传人 (25分),,模拟水题,多叉树的存储与遍历
  5. 【服务器】【阿里云】免费升级HTTP为HTTPS
  6. 【NOIP2016】【Luogu1909】买铅笔(模拟)
  7. 【网络流24题】【LOJ6000】搭配飞行员(二分图最大匹配,最大流Dinic)
  8. html按钮按下效果_html提交按钮标签代码是什么,怎么使用?(示例)
  9. RTSP/RTP/RTCP协议的区别
  10. Codeforces Round #179 (Div. 2): D. Greg and Graph(Floyd)