好久没有写JAVA了 今天突然看到Sonarlint的提示
什么??竟然不推荐这样写? 难道我一直写的都是错的?? 所以我深入了解了一下为什么要我改成构造函数注入
在Spring框架中,依赖注入(DI)是一种核心功能,它允许对象通过构造函数、setter方法或字段直接定义其依赖关系。这里,我们专注于两种常见的注入方式:字段注入(通过@Autowired注解)和构造函数注入。理解这两种注入方式的全过程对于编写可维护、可测试和健壮的Spring应用至关重要。
字段注入(使用@Autowired)
字段注入是Spring允许的依赖注入的简便方式,它直接在类的字段上使用@Autowired注解。这种方式的注入流程相对简单直接:
注入全过程
- 启动阶段:当Spring应用启动时,Spring容器开始创建并管理bean。它扫描项目中的类,查找带有@Component、@Service、@Controller等注解的类,并为这些类创建bean。
- 依赖查找:在字段上使用@Autowired时,Spring容器在运行时自动检测系统中可用的匹配该字段类型的bean。
- 自动注入:容器将找到的bean直接注入到被@Autowired标记的字段中。这一过程通常在bean的构造函数执行之后发生,意味着新创建的对象的字段将在稍后的时间点被Spring自动填充。
- 后处理:一旦所有的字段被注入后,bean才被认为是完全初始化的,并且随后会触发任何回调方法,如标记有@PostConstruct的方法。
优点与缺点
优点:
- 简单易用:直接在字段上标注@Autowired,无需额外的构造函数或setter方法。
- 代码简洁:减少了模板代码,特别是在依赖数量不多时。
缺点:
- 不支持不可变性:由于字段是在对象创建后注入,不能声明为final。
- 降低可测试性:不使用Spring容器时,例如在单元测试中,很难替换依赖项。
- 违反了Spring推荐的最佳实践:构造函数注入是推荐的方式,因为它支持不可变性,并且依赖在使用前总是被初始化。
构造函数注入
构造函数注入是将依赖作为参数传递给类的构造函数。Spring容器使用这些参数来创建bean实例。
注入全过程
- 启动阶段:与字段注入相同,Spring首先创建所有的bean定义,并扫描标注了Spring注解的类。
- 依赖解析:对于构造函数注入,当创建类的实例时,Spring容器查看类的构造函数参数,确定需要注入哪些依赖。
- 依赖注入:Spring容器然后实例化这些依赖(如果它们尚未创建)并通过构造函数注入到正在创建的bean中。这确保了在对象完全构造之前所有必需的依赖都已经提供。
- 对象初始化:一旦所有构造函数参数被注入,对象被实例化,并且所有设置方法和回调都被调用。
优点与缺点
优点:
- 支持不可变性:依赖可以被声明为final,确保了一旦构造对象后不会改变。
- 促进了更好的软件设计:构造函数注入强制要求依赖在构造对象时必须存在,从而保证了bean的依赖不会是null。
- 提高可测试性:容易在测试中通过构造函数替换依赖,特别是使用Mock对象时。
缺点:
- 构造函数臃肿:如果一个类有多个依赖,构造函数可能会变得很长,这可能使代码更难阅读和维护。
- 可能需要更多配置:特别是在存在多个构造函数或需要特定的配置来选择适当构造函数时。
对比总结
字段注入和构造函数注入在Spring中都是实现依赖注入的有效方式。然而,构造函数注入通常被视为更好的实践,因为它支持不可变性、有助于确保依赖的及时提供,同时还增强了代码的可测试性。字段注入虽然代码更简洁,但它在测试性和代码清晰度方面表现较差。
在选择适合项目的注入方式时,重要的是考虑到具体的应用场景、团队的编码标准以及维护和测试的便利性。理解各自的注入流程和特点可以帮助开发者做出最适合他们需要的选择。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。