在服务层的存储库中使用“autowired”注释和“private Final”有什么区别?

问题描述 投票:0回答:2

我看过一些教程,他们使用不同的语法来完成同样的事情。一旦通过控制器发出创建学生对象的 POST 请求,服务层就会使用这两种方法注入存储库。

方法一:

@Service
@AllArgsConstructor
@Transactional
public class StudentService {
    private final StudentRepository studentRepo;
    // complete service code using studentRepo
}

以及方法2:

@Service
public class StudentService {
    @Autowire
    private StudentRepository studentRepo;
    // complete service code using studentRepo
}

我读到它与构造函数和字段注入有关,但我真的不明白这种语法如何解决差异。有什么解释或资源可以让我更好地理解吗? 预先感谢您!

java spring-boot annotations autowired
2个回答
8
投票

您堆叠了很多框架,这增加了混乱。造成混乱的原因可能是您使用的是 Lombok。

@AllArgsConstructor
自动添加一个构造函数,其中包含构造服务实例所需的所有参数。

@AllArgsConstructor
为类中的每个字段生成一个带有 1 个参数的构造函数。标有
@NonNull
的字段会导致对这些参数进行空检查。 - 来源:Lombok 文档

使用

@AllArgsConstructor
有效地生成以下类

@Service
@Transactional
public class StudentService {

    private final StudentRepository studentRepo;

    public StudentService(StudentRepository studentRepo) {
        this.studentRepo=studentRepo;
    }
    // complete service code using studentRepo
}

现在这个类只有一个构造函数,Spring 将使用它来进行依赖注入。这称为基于构造函数的依赖注入。

@Service
@Transactional
public class StudentService {
    @Autowire
    private StudentRepository studentRepo;
    // complete service code using studentRepo
}

这称为基于字段的依赖注入。

恕我直言,您应该更喜欢基于构造函数的依赖注入,原因很简单,它非常易于使用并且就在您面前。您可以轻松地测试它,而使用字段注入编写单元测试很困难(呃),因为您需要反射来注入字段。


3
投票

依赖注入可以通过不同的方式实现。您正在谈论但可能不清楚的两种方式是:

  1. 现场注入:
@Service
public class StudentService {
  @Autowired
  private StudentRepository studentRepo;
   // complete service code using studentRepo
}
  1. 基于构造函数的 DI:
@Service
//@AllArgsConstructor <-- commenting this for now. Probably your source of confusion
@Transactional
public class StudentService {
    private final StudentRepository studentRepo;

     // For Spring Boot 1.4 and above, using @Autowired on constructor is optional
     // Dependency being injected through constructor
    public StudentService(StudentRepository studentRepo) {
             this.studentRepo = studentRepo;
    }
     // complete service code using studentRepo
}

现在,如果您输入

@AllArgsConstructor
(来自 project lombok 的注释),将在
constructor
文件中为您生成包含所有成员字段的
.class
,并且将发生所需的 DI。

© www.soinside.com 2019 - 2024. All rights reserved.