踩坑了!使用 @Autowired 注入成功,GetBean 方法却获取不到?!
本文首发于个人微信公众号:Coder小黑
踩坑了?!
之前推文已经讲过 当@Transactional遇到@CacheEvict,你的代码是不是有bug! 现在要在事务提交之后清除缓存。在Spring4.2 之后,可以使用@TransactionalEventListener选择在事务提交之后再消费对应的事件。

为了方便发送事件,偷懒使用了静态方法:

其中,SpringUtil.getBean()方法的内部实现为:

满心欢喜写完代码,一运行,直接报错,报错信息为 IoC 容器中不存在ApplicationEventPublisher。
怎么解决?解决的方案也很简单:使用@Autowired注入ApplicationEventPublisher,调用其publishEvent方法。
深入思考
可是,为什么ApplicationEventPublisher可以通过@Autowired进行注入,却不能使用BeanFactory#getBean方法来获取呢?
画外音:千万不要只限于解决问题,多思考,知其然并知其所以然。
看过 Spring 源码的小伙伴不知道还记不记得,在refresh()方法中,会调用prepareBeanFactory,在该方法中,注册了可解析依赖项。

从源码中可以知道,一些特殊实例对象是存放在DefaultListableBeanFactory#resolvableDependencies变量中的,在容器启动时,如果发现需要注入这些特定的实例对象,就直接在该变量中获取,自然也就不能通过BeanFactory#getBean方法来获取了。
DEMO
写个 demo 程序来尝试使用一下resolvableDependencies。

测试结果和ApplicationEventPublisher一样,可以在 Bean 中通过@Autowired的方式来注入MySpecificBean,但却无法通过BeanFactory#getBean方法来获取。

写在最后
很多人都说要看源码,但是看源码的目的是什么?看源码,不是为了面试吹牛,也不是为了重复造轮子。看源码是为了深入了解这个框架的底层原理,为了以后遇到问题不会懵,可以解决百度无法解决的问题。我们可以学习优秀源码的设计思想,学习如何取一个好的类名、好的方法名,如何使用设计模式等等。
最后,小黑才疏学浅,文中不足之处还望你不吝斧正,感谢你的阅读~
欢迎关注公众号,公众号全是个人原创文章,而且内容更多哦:

踩坑了!使用 @Autowired 注入成功,GetBean 方法却获取不到?!的更多相关文章
- 解决 spring boot 线程中使用@Autowired注入Bean的方法,报java.lang.NullPointerException异常
		
问题描述 在开发中,因某些业务逻辑执行时间太长,我们常使用线程来实现.常规服务实现类中,使用 @Autowired 来注入Bean,来调用其中的方法.但如果在线程类中使用@Autowired注入的Be ...
 - Vue + TypeScript + Element 搭建简洁时尚的博客网站及踩坑记
		
前言 本文讲解如何在 Vue 项目中使用 TypeScript 来搭建并开发项目,并在此过程中踩过的坑 . TypeScript 具有类型系统,且是 JavaScript 的超集,TypeScript ...
 - MyBatis踩坑之SQLProvider转义字符被删除问题
		
目录 踩坑背景 问题描述 原因追踪 解决方案 方法一 方法二 踩坑背景 项目架构:Spring Boot + MyBatis + MySQL. 使用MyBatis作为ORM框架,jdbc驱动使用的是m ...
 - ApplicationContext之getBean方法详解
		
转自:http://www.sohu.com/a/115194552_466964 我们知道可以通过ApplicationContext的getBean方法来获取Spring容器中已初始化的bean. ...
 - Spring之BeanFactory:解析getBean()方法
		
初探getBean()方法 在使用Spring的时候可以通过如下方式调用getBean方法来获取某个Bean: User user = context.getBean(User.class); Abs ...
 - IDEA下Maven项目搭建踩坑记----3.最长的bug,最简单的错误。同一类中,部分函数的@AutoWired注入的对象失效
		
这个错误绝对是我写到现在为止最傻X的一个错误,先上图 问题: 出了一个特别长的错误,大致的意思就是mapper.xml文件注入Dao层的时候失败. 解决: 查看一下错误的位置→ 找到Dao层 找到错误 ...
 - 你真的了解字典(Dictionary)吗?  C# Memory Cache 踩坑记录  .net 泛型  结构化CSS设计思维  WinForm POST上传与后台接收  高效实用的.NET开源项目  .net 笔试面试总结(3)  .net 笔试面试总结(2)  依赖注入  C# RSA 加密  C#与Java AES 加密解密
		
你真的了解字典(Dictionary)吗? 从一道亲身经历的面试题说起 半年前,我参加我现在所在公司的面试,面试官给了一道题,说有一个Y形的链表,知道起始节点,找出交叉节点.为了便于描述,我把上面 ...
 - 新人踩坑的一天——springboot注入mapper时出现java.lang.NullPointerException: null
		
来公司的第二周接到了定时任务的开发需求:每天早上十点发送用户报表邮件 .校招新人菜鸟没做过这玩意有些懵(尴尬)于是决定分步写,从excel导出->邮件发送->定时器实现->mappe ...
 - Ubuntu16.04编译安装tensorflow,2018最新血泪踩坑之后的全面总结!绝对成功!【转】
		
本文转载自:https://blog.csdn.net/pzh11001/article/details/79683133 大家好,我是 (深度学习硬件DIY总群)(719577294)群主: ...
 
随机推荐
- git回退之git reset
			
参考 https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%87%8D%E7%BD%AE%E6%8F%AD%E5%AF%86 https: ...
 - tensorflow中的学习率调整策略
			
通常为了模型能更好的收敛,随着训练的进行,希望能够减小学习率,以使得模型能够更好地收敛,找到loss最低的那个点. tensorflow中提供了多种学习率的调整方式.在https://www.tens ...
 - Vue项目性能优化整理
			
以下方式基于 @vue/cli 快速搭建的交互式项目脚手架 1. 路由懒加载 当打包构建应用时,JavaScript 包会变得非常大,影响页面加载.如果我们能把不同路由对应的组件分割成不同的代码块,然 ...
 - phpStudy中MySQL版本升级到5.7.17方法
			
本文主要给大家介绍了关于phpStudy中升级MySQL版本到5.7.17的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起看看吧.希望能帮 ...
 - 类加载器 - ClassLoader详解
			
获得ClassLoader的途径 获得当前类的ClassLoader clazz.getClassLoader() 获得当前线程上下文的ClassLoader Thread.currentThread ...
 - Redis的内存淘汰策略
			
Redis占用内存大小 我们知道Redis是基于内存的key-value数据库,因为系统的内存大小有限,所以我们在使用Redis的时候可以配置Redis能使用的最大的内存大小. 1.通过配置文件配置 ...
 - oracle中两个服务器连接中sys密码修改问题
			
问题描述:orcl服务器要连接orclstd 想要sqlplus sys/410526@orclstd as sysdba 连接orclstd数据库,但是发现啥意思密码不对,就对sys密码进行重新设置 ...
 - 读完此文让你了解各个queue的原理
			
队列是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作.通俗来讲,就是一个队列中,早来的排在前面,后来的就在队尾,而这个队列大多只有一个出口和入口的单项队列.Queue的重要 ...
 - 使用RNN进行imdb影评情感识别--use RNN to sentiment analysis
			
原创帖子,转载请说明出处 一.RNN神经网络结构 RNN隐藏层神经元的连接方式和普通神经网路的连接方式有一个非常明显的区别,就是同一层的神经元的输出也成为了这一层神经元的输入.当然同一时刻的输出是不可 ...
 - 【NHOI2018】扫雷完成图
			
[题目描述] 扫雷游戏完成后会显示一幅图,图中标示了每个格子的地雷情况.现在,一个 n * n 方阵中有 k 个地雷,请你输出它的扫雷完成图. [输入数据] 输入共 k+1 行: 第 1 行为 2 个 ...