我正在遵循最佳實踐來增強我的 SpringBoot 專案的代碼庫,并且我的控制器類符合所有其他類,但我不確定這是否會構成有狀態,因為服務類不會發生變化,這會使其不可變嗎?
例子:
@RestController
@RequestMapping(value = "/users")
public class UserController {
final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
}
userService 實體欄位設定為 final 并在控制器的建構式方法中實體化,這是否意味著控制器類違反了這一最佳實踐并且是有狀態的?
謝謝
uj5u.com熱心網友回復:
該final關鍵字只是強制執行的具體UserService不能在生命周期程序中改變UserController實體。
SpringControllers是單例,因此每個類有一個實體,這意味著對 的多個后續請求由Controller同一個實體提供服務。
所以不,final關鍵字不會使您的控制器有狀態。依賴另一個類來完成作業不會使呼叫類(您的Controller)有狀態。
另外:final 關鍵字只是使變數參考不可變,即您的 userService 屬性始終指向同一個UserService實體。但是,UserService實體本身可能仍然是可變的(例如,如果它具有可以更改的狀態)。由于@Service類在 Spring 中也是單例,因此您可能也希望使其成為Service無狀態的。
uj5u.com熱心網友回復:
依賴關系不會影響物件的“狀態”。為了讓您的控制器完成任何實際作業,您必須注入各種依賴項(其他服務)。然而,你應該注射這個UserService有@Authowired,只是宣稱它在建構式中可能無法正常作業(雖然我肯定不是100%)。
將被視為狀態的是在處理請求時寫入的某個值。任何不變的東西都不是真正的狀態。
主要目標是讓一個控制器來處理許多請求,而沒有任何它們(請求)相互干擾的風險。
uj5u.com熱心網友回復:
不,這不會使控制器有狀態。我認為這是最好的方法。你也可以做這個UserService領域private。建構式注入優于 Field 注入 IMO 例如https://www.javacodegeeks.com/2019/02/field-setter-constructor-injection.html
uj5u.com熱心網友回復:
你的代碼非常好。UserService是您的依賴項,UserController而不是將“添加”狀態到您的控制器的東西。
有狀態控制器如下所示:
@RestController
@RequestMapping(value = "/users")
public class UserController {
final UserService userService;
private final List<String> requestedUsers = new ArrayList();
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping(value = /{userId})
@ResponseStatus(HttpStatus.OK)
public User getUser(@PathVariable long userId) {
requestedUsers.add(userId);
return this.userService.getUser(userId);
}
}
現在,你有你的控制器類中的可變屬性:requestedUsers。每次對給定的 GET 請求完成時,您都可以userId通過將其添加userId到串列中來更改此串列。這將“添加”狀態到您的控制器,因為現在它包含每次向控制器發出請求時共享和更改的可變資料。值得注意的是,即使有requestedUsersasfinal也不會改變控制器的狀態。該final關鍵字只是保證了的參考requestedUsers屬性不會改變,但實際的資料結構,它指向的是可以改變的(因為它是可能的List,對此您可以無需改變其基準添加或洗掉元素)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/362791.html
