【面试必问】Spring支持注入null和空字符串吗?不懂别去面试了!



小米的故事:面试场上"翻车"的瞬间

先讲个小故事。

上个月我去面试一家AI初创公司,对方面试官是个大胡子的中年大哥,眼神犀利,一上来寒暄几句之后就抛来一个问题:

"你可以在Spring中注入一个 null 吗?或者注入一个空字符串呢?"

???

我当时脑袋一懵。

"这啥鬼问题,太简单了吧?"我心里想着,"当然可以啊,只要给个配置就好。"但我隐隐感觉有点不对劲,于是我开始结结巴巴地分析起来,什么默认值啦、@Value啦、Bean注入啦,整了个大概三分钟的回答。

大哥微微一笑,说:

"你说的不是错,但还是太表面了。你真的知道 Spring 是怎么处理这些注入的吗?"

......

那一刻,我知道,我掉坑里了。

于是,我决定回家把这问题彻底研究透。今天就跟大家一起复盘这个"看似简单但细思极恐"的问题。

问题重述:Spring 中能注入 null 和空字符串吗?

这是一道典型的"你以为你懂,其实不懂"的面试题。

我们来把问题拆解一下:

  • 能不能通过 Spring 注入一个 null?
  • 能不能通过 Spring 注入一个空字符串?
  • 注入方式不同,结果是否会不同?
  • @Value 注入 vs @Autowired 注入 vs XML配置,有差别吗?

我们一个个来,搞清楚这事。

Spring 中注入 null 的几种方式

1. 配置文件注入 null ------ 行不通!

如果你用这种写法:

然后代码里这样注入:

你猜 myValue 是 null 吗?

并不是!它是字符串 "null"!

因为在 application.properties 文件中,没有"真正的 null"这个概念,Spring 会把你写的 null 当成字符串 "null" 处理。也就是说你以为你注入了 null,实际上你注入了四个字符:n、u、l、l。

【小米吐槽】: 这个是我第一次翻车的地方,我当时还信誓旦旦地说"@Value 可以注入 null",现在想想,真是年轻......

2. @Value 注入 null 的"正确姿势"

想要真正注入 null,有两种方式:

方法一:使用 SpEL 表达式

这才是真正注入了一个 null!

Spring Expression Language(SpEL)是个宝藏,#{} 里的表达式是直接求值的,#{null} 的返回值就是 Java 中的 null。

方法二:使用条件判断返回 null

你甚至可以写 SpEL 表达式判断某个条件是否满足,不满足就返回 null:

注入空字符串的方式

相比 null,注入空字符串 "" 其实容易得多:

或者:

这两种方式都可以让 Spring 把 my.value 解析为 空字符串

然后:

此时 myValue 就真的是 "",也就是 Java 字符串中的空内容。

注意:Spring 不会把空字符串转换为 null,除非你用特殊处理。

@Autowired 注入 null 是什么体验?

现在我们换个场景,用 @Autowired 来注入 Bean,看能不能注入 null。

这时候,如果 Spring 容器里没有 OtherService 这个 Bean,会发生什么?

默认情况下,Spring 会抛出异常

因为 @Autowired 默认是 required=true,容器找不到依赖就会报错。但如果你设置了:

那就可以了!otherService 会是 null,Spring 不会抛异常。

所以,@Autowired(required = false) 是实现 null 注入的关键方式之一。

注入 null 的坑点和反直觉行为

这部分是干货,也是面试中最爱问的!

1. null != "null"

记住,字符串 "null" 和真正的 null 是完全不同的。

你在配置文件写:

结果你代码里拿到的是 "null",不是 null!

面试官很喜欢问这个陷阱问题。

2. @Value 默认值无法为 null?

Spring 提供了这种写法:

你想写成:

这不是 null,而是字符串 "null"。

想要默认值为 null,唯一办法就是 SpEL:

Spring 注入方式小总结表格

面试官想听到的标准回答

如果你遇到这个问题,建议你这样答:

在 Spring 中,如果使用 @Value 注入属性时,直接配置为 null 是无法得到真正的 null 的,反而会变成字符串 "null"。如果想注入真正的 null,应该使用 SpEL 表达式 @Value("#{null}")。而空字符串是可以通过配置文件正常注入的,比如 key= 或 key="" 都可以。

此外,如果使用 @Autowired 注入 Bean,默认是 required 的,容器中找不到 Bean 会报错。如果设置 required = false,那么没有 Bean 时字段会被注入 null。

你可以补充一句:

实际项目中很少主动注入 null,因为这违背了依赖注入的"确定性"原则,除非你明确需要。

面试官大概率点头+加分!

现实项目中的应用场景

你可能会问:"小米,这些东西真的用得到吗?"

当然用得上!

比如说我们做配置中心(Apollo、Nacos等)动态配置的时候,某些参数的"未设置状态"需要用 null 表示。这时候注入一个默认 null 就很有必要。

再比如你做权限判断、策略切换等,某些 Bean 是可选的,通过 @Autowired(required = false) 注入,就能灵活控制逻辑分支。

小米的一点感悟

回顾当初在面试现场答这道题翻车的我,再对比现在能写出一篇文章的小米,我特别想说:

有时候问题不在于你知道多少,而在于你能不能从基础问题里悟出原理、看出本质。

Spring 很强大,但它也是有规则有边界的,我们理解这些规则,才能在实战中游刃有余。

END

空字符串可以直接注入,null 需要用 SpEL 或特殊处理。

如果你觉得这篇文章对你有帮助,欢迎点赞、在看、转发给你的面试群!

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号"软件求生",获取更多技术干货!

相关推荐
CodeSheep15 分钟前
Stack Overflow,轰然倒下了!
前端·后端·程序员
GoGeekBaird23 分钟前
GoHumanLoopHub开源上线,开启Agent人际协作新方式
人工智能·后端·github
水痕0142 分钟前
gin结合minio来做文件存储
java·eureka·gin
Victor3561 小时前
Redis(8)如何安装Redis?
后端
寒士obj1 小时前
Spring事物
java·spring
Victor3561 小时前
Redis(9)如何启动和停止Redis服务?
后端
柯南二号2 小时前
【Java后端】Spring Boot 集成 MyBatis-Plus 全攻略
java·spring boot·mybatis
程序员爱钓鱼3 小时前
Go语言实战案例-创建模型并自动迁移
后端·google·go
javachen__3 小时前
SpringBoot整合P6Spy实现全链路SQL监控
spring boot·后端·sql