@Resource 注解的空值处理(默认行为与容器实现)
关于 @Resource
的空值处理,需要特别注意其默认行为与容器实现的差异:
1. 规范定义(JSR-250 标准)
- 默认允许空值
根据 Java 标准规范,@Resource
不强制要求依赖项必须存在。
当找不到匹配的 Bean 时,会注入null
而不会抛出异常。
2. Spring 容器的特殊实现
重要:Spring 对
@Resource
的处理覆盖了规范!
- Spring 实际默认行为:等效于
@Autowired(required=true)
- 找不到 Bean 时会抛出异常,而非注入
null
!
验证代码:
@Component
public class TestService {// 不存在的 Bean@Resourceprivate NonExistBean nonExistBean;
}
启动 Spring 时的错误:
No qualifying bean of type 'NonExistBean' found
3. 显式允许空值的写法
若需遵循规范行为(允许 null
),需通过 name
属性指定 Bean 并配合 @Nullable
:
@Resource(name = "optionalBean") // 明确指定 Bean 名称
@Nullable // 显式标记可空
private OptionalBean bean;
4. 不同容器的行为对比
容器类型 | @Resource 默认行为 | 找不到 Bean 时结果 |
---|---|---|
纯 JSR-250 容器 | 允许空值 | 注入 null |
Spring 容器 | 禁止空值(等效于 required=true) | 抛出 NoSuchBeanDefinitionException |
关键结论
-
在 Spring 中:
@Resource
默认不允许空值(与@Autowired
默认行为相同),找不到 Bean 会报错。 -
强制允许空值的方法:
@Resource(name = "beanName") // 指定精确名称 @Nullable // 声明可空 private SomeBean bean;
-
与
@Autowired
的对比:注解 Spring 默认行为 显式允许空值写法 @Resource
禁止空值(报错) @Resource(name = "x") + @Nullable
@Autowired
禁止空值(报错) @Autowired(required = false)
💡 本质原因:
Spring 通过CommonAnnotationBeanPostProcessor
处理@Resource
时,
将annotation.required
属性 硬编码为true
,覆盖了 JSR-250 规范。