我看过一些教程,他们使用不同的语法来完成同样的事情。一旦通过控制器发出创建学生对象的 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
}
我读到它与构造函数和字段注入有关,但我真的不明白这种语法如何解决差异。有什么解释或资源可以让我更好地理解吗? 预先感谢您!
您堆叠了很多框架,这增加了混乱。造成混乱的原因可能是您使用的是 Lombok。
@AllArgsConstructor
自动添加一个构造函数,其中包含构造服务实例所需的所有参数。
为类中的每个字段生成一个带有 1 个参数的构造函数。标有@AllArgsConstructor
的字段会导致对这些参数进行空检查。 - 来源:Lombok 文档@NonNull
使用
@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
}
这称为基于字段的依赖注入。
恕我直言,您应该更喜欢基于构造函数的依赖注入,原因很简单,它非常易于使用并且就在您面前。您可以轻松地测试它,而使用字段注入编写单元测试很困难(呃),因为您需要反射来注入字段。
依赖注入可以通过不同的方式实现。您正在谈论但可能不清楚的两种方式是:
@Service
public class StudentService {
@Autowired
private StudentRepository studentRepo;
// complete service code using studentRepo
}
@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。