构造函数实现依赖注入

148 阅读3分钟

背景:

今天看到一篇文章,写2025年了,不再提倡使用@Autowried或者@Resource注解实现依赖注入了,而是提倡使用构造函数注入,同时提除了简化得使用方法,如下:

通过在需要依赖注入得类上,添加Lombok得@RequiredArgsConstructor注解,然后在类中将你需要注入的类,使用final关键字或者@NonNull注解达到依赖注入的效果。
@Service
@RequiredArgsConstructor
public class ServiceAimpl implements ServiceA{
    // 方式一:final
    private final ServiceB serviceB;
    
    // 方式二:@NonNull
    @NonNull
    private ServiceC serviceC;
}

理解

在看完上述代码后,因为基础不好,有些不太理解,为什么可以实现,于是百度搜素,现在此做下记录。

`@RequiredArgsConstructor` 注解会为类生成一个包含所有 `final` 字段和用 `@NonNull` 标注的字段的构造函数。

当使用这个注解时,Lombok 会自动创建一个有参构造函数,而不会创建无参构造函数(除非你明确地定义了它)。

因此,在创建对象时,默认情况下会使用 Lombok 生成的有参构造函数,这正是实现构造函数注入的方式之一。

详细解释

  1. Lombok 生成的构造函数

    • @RequiredArgsConstructor 会根据类中的 final 字段和 @NonNull 标注的字段自动生成一个构造函数。这个构造函数要求提供这些字段的值作为参数。
    • 如果你没有显式地定义任何其他构造函数(如无参构造函数),那么 Lombok 生成的有参构造函数将成为唯一的构造函数。
  2. Spring 的依赖注入

    • 在 Spring 框架中,当你使用构造函数注入时,Spring 会尝试找到一个匹配的构造函数来创建并初始化 Bean。由于 Lombok 生成的有参构造函数包含了所有必要的依赖项,Spring 会使用这个构造函数来进行依赖注入。
    • 这种方式确保了在对象创建时,所有的依赖项都被正确初始化,从而避免了潜在的 null 值问题,并且有助于创建不可变对象。
  3. 无参构造函数

    • 如果你需要无参构造函数(例如,为了某些框架或库的要求),你可以通过添加 @NoArgsConstructor 注解来让 Lombok 生成一个无参构造函数。但这通常不是必需的,特别是在使用构造函数注入的情况下。
    • 如果你同时使用 @RequiredArgsConstructor@NoArgsConstructor,Lombok 会分别为你生成两个构造函数:一个有参构造函数和一个无参构造函数。

示例

仅使用 @RequiredArgsConstructor

import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class ServiceImplA {

    private final ServiceImplB serviceImplB;

    // 业务逻辑...
}

在这个例子中,Lombok 会生成一个接受 ServiceImplB 参数的构造函数。Spring 将使用这个构造函数来创建 ServiceImplA 的实例,并将 ServiceImplB 作为参数传递给它。

同时使用 @RequiredArgsConstructor@NoArgsConstructor

如果你确实需要无参构造函数,可以这样做:

import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
@NoArgsConstructor
public class ServiceImplA {

    private final ServiceImplB serviceImplB;

    // 业务逻辑...
}

在这种情况下,Lombok 会生成两个构造函数:一个有参构造函数和一个无参构造函数。不过,通常在使用构造函数注入时,不需要无参构造函数。

总结

  • @RequiredArgsConstructor 会生成一个包含所有 final 字段和 @NonNull 标注字段的有参构造函数。
  • 构造函数注入:Spring 会使用这个有参构造函数来创建并初始化 Bean,从而确保所有依赖项都被正确注入。
  • 无参构造函数:通常不需要显式定义无参构造函数,除非有特殊需求。

通过这种方式,@RequiredArgsConstructor 不仅简化了代码,还确保了依赖项的正确初始化,提升了代码的健壮性和可维护性。