Spring spring

Spring中文网站 > Spring 框架安全 > Spring框架采用Java哪种机制进行依赖注入 Spring框架依赖注入方式有哪些
Spring框架采用Java哪种机制进行依赖注入 Spring框架依赖注入方式有哪些
发布时间:2026/06/30 15:10:58

品牌型号:联想ThinkPad X1

系统:Windows10家庭版

软件版本:Spring 5.3.7

做Java开发久了,会发现很多人用了好几年Spring,却说不清楚它底层到底是怎么把对象"塞进来"的。平时写个@Autowired,项目就跑起来了,也就没再深究。直到某次面试,被问到"Spring依赖注入用的是Java哪种机制",才发现自己脑子里一片空白,理解这个问题不只是为了应付面试,更是为了搞清楚Spring为什么这么设计、出了问题我们该怎么排查。反射、构造器、Setter……这些词单独拎出来没有几个Java程序员不认识的,但放到依赖注入的语境里,很多人就开始懵了。下面就给大家介绍一下Spring框架采用Java哪种机制进行依赖注入,Spring框架依赖注入方式有哪些的相关内容。

一、Spring框架采用Java哪种机制进行依赖注入

直接告诉大家这个问题的结果,就是用我们在JavaSE阶段学到的反射。但反射到底在这里扮演什么角色,Spring具体是怎么用它的,下面就给大家详细介绍一下:

Java反射允许程序在运行时动态获取类信息,并操作它完成对象实例化、字段访问、方法调用等操作。可以说编译器不确定的事,反射在运行时都能搞定,而Spring正是依赖这一点实现注入的。

反射
图1:反射

拿字段注入举例,我们在私有字段上写了@Autowired注解,Spring会通过Class.getDeclaredFields拿到所有字段,找到目标后调用field.setAccessible(true)暴力访问,再用field.set(实例, 依赖对象)完成赋值,即便字段被私有修饰,反射也可正常访问赋值。

暴力访问完成注入
图2:暴力访问完成注入

我们再看下构造器注入,它是通过getDeclaredConstructors获取构造方法,匹配参数类型后用constructor.newInstance(参数...)完成对象创建;Setter注入则是用method.invoke(实例, 依赖对象)调用对应方法,入口不同,但是底层走的却还是同一套反射逻辑。

构造器注入
图3:构造器注入

肯定有人要提到反射有性能开销,不过Spring会对已解析的类元数据做缓存,不会每次注入都重新反射一遍,所以实际项目中感知不明显。

二、Spring框架依赖注入方式有哪些

Spring支持构造器注入、Setter注入、字段注入,这三种注入方式都能用,但用哪种、什么场景用,还得说清楚。

像构造器注入是在类的构造方法里声明依赖,Spring实例化对象时同步完成注入。这种方式的优势是依赖在对象创建时就必须到位,不存在“对象造出来了但依赖还是空的”这种情况,对象一旦构造完成,状态就是完整的,Spring官方也倾向于推荐这种方式。

构造器注入
图4:构造器注入

Setter注入方式就是提供一个set方法,Spring在对象实例化之后再调用这个方法完成注入。相比构造器它更灵活,依赖可以是可选的,也可以在后续被替换。但代价是对象在构造完成到注入完成之间存在一段"不完整"的窗口期,如果使用不当,容易出现空指针。

setter注入
图5:Setter注入

字段注入就很简单了,直接在字段上加@Autowired,正因为方便,它在我们项目里用得很多,但问题也不少,例如字段是私有的,测试时没法直接赋值,只能依赖Spring容器或者反射才能注入,单元测试写起来麻烦,而且依赖关系藏在字段里,不像构造器那样一目了然。

字段注入
图6:字段注入

那在实际项目里应该怎么选?这里建议对于强依赖、不可缺少的用构造器注入。可选依赖、需要灵活替换的依赖使用Setter注入。字段注入虽然使用起来很方便,但存在不少隐患,建议尽量少用。

以上就是Spring框架采用Java哪种机制进行依赖注入,Spring框架依赖注入方式有哪些的全部内容了。Spring框架是我们Java开发中经常用的框架,它采用的是反射的机制进行依赖注入,虽然反射存在性能开销,但在实际项目中几乎感知不到影响。Spring框架注入方式有三种,字段注入、Setter方法注入还有构造器注入,使用的时候根据实际需求,但是字段注入尽量少用。

180 1563 6924