[英]How I can handle any change field in Entity (Spring Boot)
例如我有實體用戶。
用戶有一個狀態字段。
當狀態改變時,我需要來自 UserService 的調用方法。
我有最糟糕的解決方案。 但是將服務注入實體是非常糟糕的。
@Entity
public class User {
private String status;
@Transient
private String lastStatus;
@Transient
@Autowired
private UserService userService;
public String getStatus() {
return status;
}
public void setStatus(String status) {
lastStatus = this.status;
this.status = status;
}
@PreUpdate
public void handleChangeStaus() {
if (!status.equals(lastStatus)) {
userService.doSomething();
}
}
}
一種方法是從您的User
實體 class發布域事件,然后為此事件創建偵聽器。
首先,讓我們創建一個事件:
@AllArgsConstructor
@Getter
public class UserStatusChangeEvent {
private final UUID userId;
private final String lastStatus;
private final String newStatus;
}
然后您的User
實體 class 應該使用默認域事件發布機制實現AbstractAggregateRoot
接口,以讓您的實體發布事件並在您的setStatus
方法中發布一個:
@Entity
@Getter
public class User implements AbstractAggregateRoot<User> {
private UUID userId;
private String status;
@Transient
private String lastStatus;
public void setStatus(String status) {
lastStatus = this.status;
this.status = status;
registerEvent(new UserStatusChangeEvent(userId, lastStatus, status));
}
}
然后使用監聽器創建一個單獨的 class ,將其定義為 bean ( @Component
) 並在那里注入您的UserService
:
@RequiredArgsConstructor
@Component
public class UserStatusListener {
private final UserService userService;
@EventListener
public void onStatusChange(UserStatusChangeEvent statusChangeEvent) {
if (!statusChangeEvent.getNewStatus().equals(statusChangeEvent.getLastStatus())) {
userService.doSomething();
}
}
}
Spring 將為您做“魔術”——將您的事件發布為應用程序事件並在啟動時注冊您的偵聽器。
請注意,spring-data 將僅在您的實體存儲庫上調用save
或saveAll
方法后發布您的域事件,因此沒有保存 - 沒有事件。
如果您希望偵聽器根據事務(成功、失敗、之前或之后等)工作,也可以使用具有不同事務階段的@TransactionalEventListener
而不是@EventListener
。
PS 我在類上使用 Lombok 注釋來簡化代碼並通過構造函數注入字段。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.