主页 > 互联网  > 

【Spring属性注入】构造器注入vs字段注入

【Spring属性注入】构造器注入vs字段注入
1. 最佳实践:构造器注入 vs 字段注入

在 Spring 中,构造器注入(Constructor Injection) 是官方推荐的最佳实践,而 字段注入(Field Injection) 或 @Resource 通常不推荐,原因如下:

对比项构造器注入 (@RequiredArgsConstructor)字段注入 (@Resource)依赖不可变性✅ 依赖为 final,不可变,线程安全❌ 依赖可变,可能被意外修改单元测试友好性✅ 可直接通过构造器传入 Mock 对象❌ 需要反射或 Spring 容器,测试复杂循环依赖检测✅ 编译时即可发现循环依赖❌ 运行时才能发现循环依赖代码可读性✅ 明确声明所有必需依赖❌ 依赖隐藏在字段中,难以识别Spring 官方推荐✅ 官方推荐❌ 不推荐

结论:优先使用 构造器注入(即 @RequiredArgsConstructor + private final)。


2. 为何 @RequiredArgsConstructor 需要 new?

问题出在 接口无法直接实例化。以下是具体原因:

错误场景分析: @RequiredArgsConstructor public class MyService { private final IJCmsMediaImageRelevanceService mediaImageRelevanceService; // 错误:尝试 new 接口 public void someMethod() { IJCmsMediaImageRelevanceService service = new IJCmsMediaImageRelevanceService(); // ❌ 编译错误 } } 接口无法实例化:IJCmsMediaImageRelevanceService 是一个接口,不能直接 new。Spring 依赖管理:@RequiredArgsConstructor 生成的构造器需要 Spring 自动注入接口的实现类(即 Bean)。如果 Spring 容器中没有该接口的实现类,会导致注入失败。 为什么 @Resource 看似可以 “new”? @Resource 是字段注入,它的依赖解析由 Spring 容器在运行时完成。你看到的 “可以 new” 是误解,实际是 Spring 自动代理了接口并注入实现类。如果在非 Spring 环境中手动 new 一个依赖 @Resource 的类,字段注入会失败,因为 Spring 未介入。
3. 正确解决依赖注入问题 步骤 1:确保接口有实现类并被 Spring 管理 // 接口 public interface IJCmsMediaImageRelevanceService { // 方法定义 } // 实现类 @Service // 关键:标记为 Spring Bean public class JCmsMediaImageRelevanceServiceImpl implements IJCmsMediaImageRelevanceService { // 实现方法 } 步骤 2:使用构造器注入 @RequiredArgsConstructor public class MyService { private final IJCmsMediaImageRelevanceService mediaImageRelevanceService; // ✅ Spring 自动注入实现类 // 无需手动 new,Spring 会自动注入 JCmsMediaImageRelevanceServiceImpl 实例 } 步骤 3:验证 Spring 配置 确保实现类所在的包被 Spring 扫描到:@SpringBootApplication @ComponentScan("com.yourpackage.implementations") // 指定扫描路径 public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
关键总结: 优先使用构造器注入(@RequiredArgsConstructor + private final),符合 Spring 最佳实践。接口无法直接实例化,必须通过 Spring 注入其实现类。确保所有依赖接口的实现类被标记为 @Service、@Component 等,并被 Spring 扫描到。
标签:

【Spring属性注入】构造器注入vs字段注入由讯客互联互联网栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【Spring属性注入】构造器注入vs字段注入