如何在控制器的方法中注入服务?
How to inject service in controller's method?
我在控制器方法中注入服务时遇到问题。我有以下服务:
@Service
@RequiredArgsConstructor
public class CreateFranchiseUseCase {
private final FranchiseService franchiseService;
private final UserService userService;
private final ACLEntryService aclEntryService;
private final FranchiseDTOMapper franchiseDTOMapper;
public Franchise execute(CreateFranchiseDTO dto) {
// ...
}
}
然后在控制器中:
@RestController
@RequiredArgsConstructor
public class FranchiseController {
// ...
@PostMapping("/api/franchises")
public ResponseEntity<Object> createFranchise(CreateFranchiseDTO dto, CreateFranchiseUseCase useCase) {
Frachise franchise = useCase.execute(dto);
// ...
}
}
当我调用此端点时,我得到 NullPointerException。异常发生在执行方法和调试方法我发现所有属性:franchiseService
、userService
、aclEntryService
和franchiseDTOMapper
都是NULL。
所有 classes:FranchiseService
、UserService
和 ACLEntryService
都带有 @Service
注释。 FranchiseDTOMapper
被注释为 @Mapper(componentModel = "spring")
Spring是否支持方法注入?或者有什么方法可以在 createFranchise()
方法中请求 CreateFranchiseUseCase
class 的实例,如下所示:
@PostMapping("/api/franchises")
public ResponseEntity<Object> createFranchise(CreateFranchiseDTO dto) {
CreateFranchiseUseCase useCase = container.get(CreateFranchiseUseCase.class) // <-- something like this
Frachise franchise = useCase.execute(dto);
// ...
}
据我所知,不可能让 Spring 将对象注入到方法中。
相反,您可以让 Spring 通过控制器的构造函数注入对象。
这会导致这样的结果:
@RestController
public class FranchiseController {
private final CreateFranchiseUseCase createFranchiseUseCase;
public FranchiseController(CreateFranchiseUseCase createFranchiseUseCase) {
this.createFranchiseUseCase = createFranchiseUseCase;
}
@PostMapping("/api/franchises")
public ResponseEntity<Object> createFranchise(CreateFranchiseDTO dto) {
Frachise franchise = createFranchiseUseCase.execute(dto);
// ...
}
}
即使您使用 Lombok 创建构造函数,这也应该有效。
你可以像这样注入它,但考虑通过你的控制器构造函数注入服务。
@PostMapping("/api/franchises")
public ResponseEntity<Object> createFranchise(CreateFranchiseDTO dto) {
CreateFranchiseUseCase useCase = new CreateFranchiseUseCase();
Frachise franchise = useCase.execute(dto);
// ...
}
编辑:
但请记住,您必须向 CreateFranchiseUseCase 注入其他服务。您可以像这样在构造函数中执行此操作:
public CreateFranchiseUseCase () {
FranchiseService franchiseService = new FranchiseService();
UserService userService = new UserService();
ACLEntryService aclEntryService = new ACLEntryService();
FranchiseDTOMapper franchiseDTOMapper = new FranchiseDTOMapper();
}
或者像这样在没有构造函数的情况下注入它:
@Service
@RequiredArgsConstructor
public class CreateFranchiseUseCase {
private final FranchiseService franchiseService = new FranchiseService();
private final UserService userService = new UserService();
private final ACLEntryService aclEntryService = new ACLEntryService();
private final FranchiseDTOMapper franchiseDTOMapper = new FranchiseDTOMapper();
public Franchise execute(CreateFranchiseDTO dto) {
// ...
}
}
Does Spring support Method Injection?
没有。按参数列出的可接收对象如下:
您可以使用 ApplicatonContext#getBean()
:
@Autowired
private ApplicationContext context;
@PostMapping("/api/franchises")
public ResponseEntity<Object> createFranchise(CreateFranchiseDTO dto) {
reateFranchiseUseCase useCase = context.getBean(CreateFranchiseUseCase.class);
// ...
}
如果每个请求都需要CreateFranchiseUseCase
对象实例化,则需要添加@Scope(WebApplicationContext.SCOPE_REQUEST)
:
@Service
@Scope(WebApplicationContext.SCOPE_REQUEST)
public class CreateFranchiseUseCase {
我在控制器方法中注入服务时遇到问题。我有以下服务:
@Service
@RequiredArgsConstructor
public class CreateFranchiseUseCase {
private final FranchiseService franchiseService;
private final UserService userService;
private final ACLEntryService aclEntryService;
private final FranchiseDTOMapper franchiseDTOMapper;
public Franchise execute(CreateFranchiseDTO dto) {
// ...
}
}
然后在控制器中:
@RestController
@RequiredArgsConstructor
public class FranchiseController {
// ...
@PostMapping("/api/franchises")
public ResponseEntity<Object> createFranchise(CreateFranchiseDTO dto, CreateFranchiseUseCase useCase) {
Frachise franchise = useCase.execute(dto);
// ...
}
}
当我调用此端点时,我得到 NullPointerException。异常发生在执行方法和调试方法我发现所有属性:franchiseService
、userService
、aclEntryService
和franchiseDTOMapper
都是NULL。
所有 classes:FranchiseService
、UserService
和 ACLEntryService
都带有 @Service
注释。 FranchiseDTOMapper
被注释为 @Mapper(componentModel = "spring")
Spring是否支持方法注入?或者有什么方法可以在 createFranchise()
方法中请求 CreateFranchiseUseCase
class 的实例,如下所示:
@PostMapping("/api/franchises")
public ResponseEntity<Object> createFranchise(CreateFranchiseDTO dto) {
CreateFranchiseUseCase useCase = container.get(CreateFranchiseUseCase.class) // <-- something like this
Frachise franchise = useCase.execute(dto);
// ...
}
据我所知,不可能让 Spring 将对象注入到方法中。
相反,您可以让 Spring 通过控制器的构造函数注入对象。
这会导致这样的结果:
@RestController
public class FranchiseController {
private final CreateFranchiseUseCase createFranchiseUseCase;
public FranchiseController(CreateFranchiseUseCase createFranchiseUseCase) {
this.createFranchiseUseCase = createFranchiseUseCase;
}
@PostMapping("/api/franchises")
public ResponseEntity<Object> createFranchise(CreateFranchiseDTO dto) {
Frachise franchise = createFranchiseUseCase.execute(dto);
// ...
}
}
即使您使用 Lombok 创建构造函数,这也应该有效。
你可以像这样注入它,但考虑通过你的控制器构造函数注入服务。
@PostMapping("/api/franchises")
public ResponseEntity<Object> createFranchise(CreateFranchiseDTO dto) {
CreateFranchiseUseCase useCase = new CreateFranchiseUseCase();
Frachise franchise = useCase.execute(dto);
// ...
}
编辑: 但请记住,您必须向 CreateFranchiseUseCase 注入其他服务。您可以像这样在构造函数中执行此操作:
public CreateFranchiseUseCase () {
FranchiseService franchiseService = new FranchiseService();
UserService userService = new UserService();
ACLEntryService aclEntryService = new ACLEntryService();
FranchiseDTOMapper franchiseDTOMapper = new FranchiseDTOMapper();
}
或者像这样在没有构造函数的情况下注入它:
@Service
@RequiredArgsConstructor
public class CreateFranchiseUseCase {
private final FranchiseService franchiseService = new FranchiseService();
private final UserService userService = new UserService();
private final ACLEntryService aclEntryService = new ACLEntryService();
private final FranchiseDTOMapper franchiseDTOMapper = new FranchiseDTOMapper();
public Franchise execute(CreateFranchiseDTO dto) {
// ...
}
}
Does Spring support Method Injection?
没有。按参数列出的可接收对象如下:
您可以使用 ApplicatonContext#getBean()
:
@Autowired
private ApplicationContext context;
@PostMapping("/api/franchises")
public ResponseEntity<Object> createFranchise(CreateFranchiseDTO dto) {
reateFranchiseUseCase useCase = context.getBean(CreateFranchiseUseCase.class);
// ...
}
如果每个请求都需要CreateFranchiseUseCase
对象实例化,则需要添加@Scope(WebApplicationContext.SCOPE_REQUEST)
:
@Service
@Scope(WebApplicationContext.SCOPE_REQUEST)
public class CreateFranchiseUseCase {