目录

引言

1、Bean的注入

1.1、Setter方法

1.2、字段注入

1.3、构造器注入

2、@Autowired和@Resource

2.1、@Autowired

2.2、@Resource

3、优雅的构造器注入

3.1、为什么不推荐@Autowired和@Resource

3.2、lombok的@RequiredArgsConstructor

引言

有的公司在SpringBoot禁止使用@Autowired和@Resource了 还有SpringBoot官方也不推荐这种形

式 IDEA编辑器也会给出提示信息不推荐

1、Bean的注入

在Spring框架中,Bean的注入方式主要有三种:构造器注入、Setter方法注入和字段注入。下面是

对这三种注入方式的介绍:

1.1、Setter方法

通过Setter方法将依赖注入到类中。这种方式允许在对象创建之后再设置依赖,适用于需要在对象

创建后进行一些初始化操作的场景。

示例

@Service
public class MyService {
    private MyRepository myRepository;

    @Autowired
    public void setMyRepository(MyRepository myRepository) {
        this.myRepository = myRepository;
    }

    // 业务逻辑方法
}

1.2、字段注入

直接在字段上使用注解将依赖注入到类中。这种方式使用起来很方便,但不推荐,因为它不利于单

元测试和依赖管理。

示例

@Service
public class MyService {
    @Autowired
    private MyRepository myRepository;

    // 业务逻辑方法
}

1.3、构造器注入

通过构造函数参数将依赖注入到类中。这种方式在对象创建时就已经完成了依赖注入,确保了依赖

的完整性和不可变性。因此,构造器注入是推荐的注入方式。

示例

@Service
public class MyService {
    private final MyRepository myRepository;

    @Autowired
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }

    // 业务逻辑方法
}

2、@Autowired和@Resource

@Autowired和@Resource在平常都是用来注入Bean 一般都用于字段注入方式 当然他们也可以构

造器注入和Setter方法注入 只是用的比较少

示例:

@Service
public class MyService {
    @Autowired
    private MyRepository myRepository;

    // 业务逻辑方法
}


@Service
public class MyService {
    @Resource
    private MyRepository myRepository;

    // 业务逻辑方法
}

2.1、@Autowired

这是Spring框架提供的注解,主要用于自动装配Bean。

  1. 按类型注入:默认情况下,@Autowired按类型(by type)进行注入。
  2. 与@Qualifier结合使用:可以与@Qualifier注解结合使用,以按名称(by name)进行注入。
  3. 构造器、Setter方法、字段注入:可以用于构造器、Setter方法和字段注入。

示例

@Service
public class MyService {
    @Autowired
    private MyRepository myRepository;

    // 业务逻辑方法
}

2.2、@Resource

这是Java标准的注解(来自JSR-250),也可以用于依赖注入。

特性

  1. 按名称注入:默认情况下,@Resource按名称(by name)进行注入。
  2. 按类型注入:如果找不到匹配的名称,则按类型(by type)进行注入。
  3. Setter方法和字段注入:通常用于Setter方法和字段注入,不直接支持构造器注入。
@Service
public class MyService {
    @Resource
    private MyRepository myRepository;

    // 业务逻辑方法
}

解释:Spring会首先尝试按名称查找一个名为myRepository的Bean,如果找不到,再按类型查找

一个MyRepository类型的Bean进行注入。 

3、优雅的构造器注入

3.1、为什么不推荐@Autowired和@Resource

推荐使用构造器注入而不是字段注入(@Autowired@Resource)的主要原因是构造器注入在设计

和测试方面具有显著优势。以下是具体原因:

1. 不可变性和线程安全

构造器注入使得依赖在对象创建时就被完全初始化,从而保证了对象的不可变性。不可变对象在多

线程环境下是线程安全的,因为它们的状态在创建之后不会改变。

2. 强制依赖

使用构造器注入可以强制依赖的存在。如果一个类的构造函数需要某个依赖,那么在创建这个类的

实例时,必须提供这个依赖,否则编译器会报错。这确保了类在使用前已经完全初始化。

3. 易于测试

构造器注入使得类更容易进行单元测试。你可以在测试中轻松地创建类的实例,并通过构造器传递

Mock或Stub对象,而不需要依赖于Spring框架的上下文。

4. 减少反射使用

字段注入和Setter方法注入通常需要使用反射机制,这可能会带来性能上的开销。构造器注入则不

需要反射,性能更优。

5. 清晰的依赖关系

构造器注入使得类的依赖关系更加明确和清晰。通过查看构造函数的参数列表,开发者可以一目了

然地知道这个类依赖于哪些其他类。

6. 避免循环依赖

构造器注入能够更好地避免循环依赖问题。在使用字段注入时,容易发生循环依赖,而构造器注入

则可以在编译时发现并解决这些问题。

7. 单一职责原则

使用构造器注入有助于遵循单一职责原则(SRP)。如果一个类需要过多的依赖,可能意味着这个

类承担了太多的职责,需要重构。

示例对比

字段注入:

@Service
public class MyService {
    @Autowired
    private MyRepository myRepository;

    // 业务逻辑方法
}

构造器注入:

@Service
public class MyService {
    private final MyRepository myRepository;

    @Autowired
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }

    // 业务逻辑方法
}

3.2、lombok的@RequiredArgsConstructor

 如果我们使用构造器注入 每写一个bean 就要往构造函数 添加一个 这样很麻烦

示例:

public class MyService {
    private final MyRepository myRepository;
    private final MyOtherDependency myOtherDependency;

    public MyService(MyRepository myRepository, MyOtherDependency myOtherDependency) {
        this.myRepository = myRepository;
        this.myOtherDependency = myOtherDependency;
    }
}

lombok提供了一个注解@RequiredArgsConstructor 只需要加上类上 编译的时候会自动帮我们生成

构造函数 我们只需要将bean声明为final类型

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

@Service
@RequiredArgsConstructor
public class MyService {
    private final MyRepository myRepository;
    private final MyOtherDependency myOtherDependency;
}

编译后:

import org.springframework.stereotype.Service;

@Service
public class MyService {
    private final MyRepository myRepository;
    private final MyOtherDependency myOtherDependency;

    // 由Lombok生成的构造函数
    public MyService(MyRepository myRepository, MyOtherDependency myOtherDependency) {
        this.myRepository = myRepository;
        this.myOtherDependency = myOtherDependency;
    }
}