为了账号安全,请及时绑定邮箱和手机立即绑定

Spring不再推荐使用@Autowired了

标签:
Java Spring

在Spring开发领域中,尤其是在Spring Boot框架中,@Autowired 注解一直是将依赖项注入Spring管理的Bean的常用手段。然而,随着Spring最佳实践的发展和新功能的引入,@Autowired 已不再是推荐的依赖注入方式。对于熟悉旧版Spring的开发人员而言,这种转变可能会让熟悉旧版本的开发人员感到意外。本文将探讨为什么@Autowired 正在失去其原有的地位,Spring推荐的替代方案有哪些,以及如何现代化Spring代码库。

什么是 @Autowired?

在我们讨论Spring不再推荐@Autowired之前,先快速了解一下@Autowired的作用。@Autowired用于将依赖注入到类中,这可以应用于字段(field)、构造函数和setter方法,Spring在应用程序启动时自动注入所需的bean。

比如说:

/**

* 这是一个服务类,名为MyService,它依赖于MyRepository。
 */
@Service  
public class MyService {  

    @Autowired  
    private MyRepository myRepository;  
}

在这个情况下,Spring 在创建 MyService 实例时,注入了一个 MyRepository 实例。

尽管这种方法效果不错,但也有其不足之处,特别是在更大、更复杂的应用程序中。让我们来看看原因。

@Autowired 的毛病
  1. 隐藏的依赖:当在字段上使用 @Autowired 时,依赖会在幕后注入,这可能导致隐藏的依赖。这种做法使得很难明确一个类正常工作所需要的依赖,从而增加了测试和调试的复杂性。
  2. 不可变性问题:字段注入允许依赖是可变的,使得类可以稍后更改它们。这降低了组件的不可变性,从而导致难以追踪的错误。
  3. 测试困难:依赖关系通过字段注入的组件在测试时可能比较棘手。由于依赖关系没有通过构造函数传递,你需要在测试设置中手动模拟或注入这些字段,这会增加不必要的样板代码。
  4. 基于构造函数的注入更清晰:通过构造函数的注入,依赖关系在构造函数中显式声明,使得所需的组件一目了然。这种方法使类更易读,更容易测试,同时提升了整体的可维护性。
Spring为什么推荐使用构造注入

近年来,Spring团队倾向于将构造器注入作为处理依赖注入的首选方式,而不再使用@Autowired进行字段注入。这里有一些原因:

  • 构造器注入使依赖关系更加明确,有助于实现无副作用。
  • 它有助于确保对象在创建时就具有所有必要的依赖关系,从而避免部分初始化的问题。
  • 使得单元测试更容易,因为所有依赖项都是通过构造函数传递的。

1. 必要的依赖项:构造函数注入强制你在创建类的实例时提供所有必需的依赖。这确保该类在创建时总是处于有效且完整的状态,所有必要的依赖项都已设置。

@Service  
public class MyService {  
    // 定义一个私有且不可变的MyRepository对象
    private final MyRepository myRepository;  

    // 构造函数,通过注入的方式初始化myRepository对象
    public MyService(MyRepository myRepository) {  
        this.myRepository = myRepository;  
    }  
}

在此示例中,Spring 会自动将 MyRepository 注入构造器中,确保 MyService 始终用有效的仓库对象初始化。

2.不可变:构造器注入鼓励使用 final 字段,从而使得对象变得不可变。一旦注入依赖项,它们将不能被改变,从而减少了意外修改和代码错误的可能性。

3.增强的可测试性:使用构造器注入进行组件测试要容易得多。在测试时,你只需将模拟依赖直接传递给构造器,而无需依赖Spring的内部配置。

4.无需@Autowired: 如果一个类只有一个构造方法,Spring 可以自动注入其依赖,从而无需使用 @Autowired 注解。这简化了代码,减少了注解的冗余。

@RequiredArgsConstructor 火了

对于那些使用构造器注入的类来说,另一个有用的工具是 Lombok 的 @RequiredArgsConstructor 注解。此注解会自动生成一个包含必填字段(这些字段标记为 final)的构造器,从而进一步减少了样板代码。

    @Service  
    @RequiredArgsConstructor  
    public class MyService {  

        private final MyRepository myRepository;  
    }

使用 @RequiredArgsConstructor,可以自动注入必要的依赖项,而无需手动编写构造函数,从而使代码保持干净和简洁。

@Autowired(自动注入)依然很有用,但请谨慎使用

重要的是要注意,Spring 没有弃用 @Autowired,并且完全不推荐使用这个说法也不准确。在某些情况下它仍然有用,例如:

  • setter 注入方式:在某些情况下,当你希望使用 setter 注入时,可以这样做,如果依赖是可选的,或者你可以在对象创建后注入值。然而,尽量少用 setter 注入,仅在必要时才使用。
    @Service  
    public class MyService {  
        // 该类用于管理MyRepository的注入
        private MyRepository myRepository;  

        @Autowired  
        public void setMyRepository(MyRepository myRepository) {  
            this.myRepository = myRepository;  
        }  
    }
  • 遗留代码:如果你正在处理遗留代码库,你可能会遇到 @Autowired 注解。你不需要立即重构所有 @Autowired 的实例,但在你更新和重构代码的过程中,可以考虑逐步过渡到构造器注入。

总结:告别 @Autowired,继续前行

在现代 Spring 开发中,一般来说,构造器注入被认为是依赖注入的最佳实践,提供更干净、更易于维护和测试的代码。虽然 @Autowired 仍然可用,但理解其局限以及 Spring 为何建议不再使用它非常重要。

以下是一些关键要点:

  • 构造器注入有助于提高代码的不可变性和清晰度。
  • 使用构造器注入会使测试变得更加容易,因为你可以直接注入模拟对象或存根。
  • Lombok 的 @RequiredArgsConstructor 可以简化基于构造器的依赖注入。
  • 尽量少用 @Autowired,仅在其他注入方法不适用时才使用。

通过采用这些做法,你可以编写更简洁、更健壮的Spring应用程序,这样的应用程序随着时间更易于维护和测试。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消