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

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

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


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


image.png


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


image.png


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


image.png 


取出来的tradeService 是null :


image.png


为什么?  怎么办 ?



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


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


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

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


我抛出一个问题:


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


你能不能实现 ?


答案是: 必然可以的。


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



源码:


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


image.png


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


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


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


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


image.png


②来了,主角来了:


image.png


③ 动手:


可以看到 isStatic()的源码,


 image.png


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


就这么做,直接改成0:


 image.png


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


image.png


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


image.png


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


image.png


现在我们绕过之后:


image.png


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


image.pngimage.png


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


深思



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


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


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


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


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


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


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


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

相关文章
|
前端开发 Java 物联网
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
867 70
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
1611 0
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
813 7
|
存储 监控 数据可视化
SaaS云计算技术的智慧工地源码,基于Java+Spring Cloud框架开发
智慧工地源码基于微服务+Java+Spring Cloud +UniApp +MySql架构,利用传感器、监控摄像头、AI、大数据等技术,实现施工现场的实时监测、数据分析与智能决策。平台涵盖人员、车辆、视频监控、施工质量、设备、环境和能耗管理七大维度,提供可视化管理、智能化报警、移动智能办公及分布计算存储等功能,全面提升工地的安全性、效率和质量。
464 0
|
JavaScript Java 关系型数据库
基于springboot的项目管理系统
本文探讨项目管理系统在现代企业中的应用与实现,分析其研究背景、意义及现状,阐述基于SSM、Java、MySQL和Vue等技术构建系统的关键方法,展现其在提升管理效率、协同水平与风险管控方面的价值。
基于springboot的儿童家长教育能力提升学习系统
本系统聚焦儿童家长教育能力提升,针对家庭教育中理念混乱、时间不足、个性化服务缺失等问题,构建科学、系统、个性化的在线学习平台。融合Spring Boot、Vue等先进技术,整合优质教育资源,提供高效便捷的学习路径,助力家长掌握科学育儿方法,促进儿童全面健康发展,推动家庭和谐与社会进步。
|
JavaScript Java 关系型数据库
基于springboot的古树名木保护管理系统
本研究针对古树保护面临的严峻挑战,构建基于Java、Vue、MySQL与Spring Boot技术的信息化管理系统,实现古树资源的动态监测、数据管理与科学保护,推动生态、文化与经济可持续发展。
2025基于springboot的校车预定全流程管理系统
针对传统校车管理效率低、信息不透明等问题,本研究设计并实现了一套校车预定全流程管理系统。系统采用Spring Boot、Java、Vue和MySQL等技术,实现校车信息管理、在线预定、实时监控等功能,提升学校管理效率,保障学生出行安全,推动教育信息化发展。