当前位置: 首页 > news >正文

SpringBoot (走读源码)静态方法中调用spring注入的对象,注入对象为null?

大家都开始玩springboot了, 其实肯定已经知道 平常写代码,如果在静态方法里面调用 spring ioc容器里面的bean,是不允许的。

就像这样,在写代码的时候就告诉你不能这么写:

 

 然后我们根据提示,改成这样写哈哈哈哈, 可以了(静态拿静态,没毛病):

 

然后我们真正去调用,会发现报错:

 取出来的tradeService 是null :

为什么?  怎么办 ?

怎么办我不展开说其实很多方案,可以把这个tardeService直接拿出来。


我这一篇文章想给大家讲讲是为什么 ?

我觉得大部分人可能都不会去关注这个东西。


静态方法提前加载啊, 肯定拿不到bean的实例啦 ,这么理解确实没有错。
 

我抛出一个问题:

 

如果给你去实现,我就要你静态方法加载的时候,去取实例,你去封装一下spring框架,

你能不能实现 ?

答案是: 必然可以的。

所以我现在要揭开 为什么不能的真面目了

源码:

AutowiredAnnotationBeanPostProcessor 的 buildAutowiringMetadata 函数,看到那个isStatic方法了么?

 没错,其实就是spring框架这里拦截判断如果是static,直接return,不再注入,所以后面我们拿到null了。

可能这么一句话说,看不懂源码的初学者可能不太信。

OK,那我现在就通过debug方式,魔改一下这个判断。

①首先我把debug打好,卡在前面:

②来了,主角来了:

③ 动手:
 

可以看到 isStatic()的源码, 

 

 也就是说如果 field.getModifiers() 改成0,就能绕过这个静态检测 。

就这么做,直接改成0:
 

ps: 评论区有兄弟对这个改debug的值感兴趣,我补一张操作图,平时dubug调试的时候,看个人使用习惯,也可以这样去调试一些业务场景。

 

可以看到成功绕过了,绕过后立刻改回来还原原来的值 10:
 

如果被拦截是有日志打印的:

 现在我们绕过之后:

现在我们再来调用一下看看效果,不再是null了:


看到这里,大家都知道为啥了、 就是 spring 的作者在设计上的考虑,这个isStatic就是真凶。

深思

从做开源框架的角度上去考虑, 是不是什么都做,是好框架?

那么spring容器的职责、初衷是什么?

(当然,现在这一小段分析都是我个人的想法,可能不够成熟。)


IOC的初衷,是用来管理 bean的实例的。

如果说一个属性是 static修饰, 那么这个静态成员其实不是实例的, 它是类的。


不是我们的饭, 我们能吃,但是能够吃么? 该吃么? 什么时候会去吃?


别说光看这个问题了,不管工作上,生活中,我们是不是都应该想一想。

如果你有看法,欢迎留言。

相关文章:

  • HashMap 使用的时候指定容量?你真的用明白了吗?(值得一阅)
  • 用这个免费CDN,治愈WordPress网站加载缓慢的大难题
  • 搞什么啊? URI 和 URL 到现在还不清楚?
  • Springboot 根据数据库表自动生成实体类和Mapper,只需三步
  • SpringBoot 导出多个Excel文件,压缩成.zip格式下载
  • Springboot 指定自定义模板导出Excel文件
  • Mysql 我随手造200W条数据,给你们讲讲分页优化。
  • 【云原生】风云暗涌的时代,DBA们的利刃出鞘了
  • 以后面试官问你 为啥不建议使用Select *,请你大声回答他!
  • Springboot 导入导出Excel ,一对多关系,复合表格、合并单元格数据
  • 怎么清晰地理解、表达 IaaS 、 PaaS 、 SaaS ?
  • UML类图的六大关系,最佳学习理解方式
  • Springboot 整合 Socket 实战案例 ,实现 单点发送、广播群发,1对1,1对多
  • Springboot Mybatis 、JPA 调用存储过程,实战教程
  • 写代码的七八九十宗罪,多图、胆小慎入!
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • Android框架之Volley
  • cookie和session
  • github指令
  • node入门
  • Objective-C 中关联引用的概念
  • Python 基础起步 (十) 什么叫函数?
  • QQ浏览器x5内核的兼容性问题
  • Spring Cloud Feign的两种使用姿势
  • Swift 中的尾递归和蹦床
  • Twitter赢在开放,三年创造奇迹
  • ubuntu 下nginx安装 并支持https协议
  • 阿里云应用高可用服务公测发布
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 深度解析利用ES6进行Promise封装总结
  • 为什么要用IPython/Jupyter?
  • 为视图添加丝滑的水波纹
  • 物联网链路协议
  • 携程小程序初体验
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (过滤器)Filter和(监听器)listener
  • .NET Core MongoDB数据仓储和工作单元模式封装
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .net开发时的诡异问题,button的onclick事件无效
  • .Net中的设计模式——Factory Method模式
  • /var/spool/postfix/maildrop 下有大量文件
  • @entity 不限字节长度的类型_一文读懂Redis常见对象类型的底层数据结构
  • @RequestMapping 的作用是什么?
  • [100天算法】-不同路径 III(day 73)
  • [145] 二叉树的后序遍历 js
  • [20171101]rman to destination.txt
  • [20171102]视图v$session中process字段含义
  • [ACTF2020 新生赛]Include
  • [AIGC] 如何建立和优化你的工作流?
  • [Android]Tool-Systrace
  • [Angular] 笔记 9:list/detail 页面以及@Output