Tôi đang giới thiệu Spring Statemachine vào một dự án hiện có, với hy vọng hợp nhất và làm rõ logic kinh doanh của chúng tôi. Chúng ta có các thực thể JPA khác nhau với các trạng thái kết nối và tôi đang gặp một số vấn đề với việc thiết lập trạng thái tồn tại trạng thái hiện tại của một máy trạng thái hiện có.Duy trì và khôi phục trạng thái hiện tại trong Spring Statemachine
Tôi đang sử dụng StateMachineFactory để tạo một thể hiện StateMachine mới cho mỗi cá thể thực thể. Tôi đang lưu trữ trạng thái hiện tại của StateMachine trong một trường riêng biệt cho Hibernate để tồn tại và lý tưởng là cần phải đồng bộ hóa giá trị của trường persisted với StateMachine. Câu hỏi của tôi là về việc làm thế nào để đạt được điều này trong Spring Statemachine.
@Entity
@EntityListeners(MyEntityListener.class)
public class MyEntity {
@Column
private MyState internalState; // Using AttributeConverter
@Transient
private StateMachine<MyState, Event> stateMachine;
}
public class MyEntityListener {
@PostLoad
public void postLoad(MyEntity entity) {
// TODO Set StateMachine's current state to entity's internal state
);
}
Một cách tiếp cận có thể để xác định chuyển địa phương để di chuyển các trạng thái ban đầu vào tình trạng tiếp tục tồn tại. Sau đó tôi có thể thực hiện kiểm tra có điều kiện để tìm một sự kiện gắn liền với một chuyển đổi cục bộ, điều này sẽ chuyển trạng thái nguồn vào trạng thái đích. Điều này có vẻ hơi lộn xộn với tôi và tôi muốn giữ cấu hình máy của tiểu bang của tôi càng sạch càng tốt. Tôi không thể thấy làm thế nào tôi có thể thiết lập trạng thái hiện tại của StateMachine thông qua một API công cộng mà không cần chuyển qua một quá trình chuyển đổi và một cách tiếp cận khác mà tôi khám phá là bao bọc thể hiện StateMachine để lộ phương thức sau đây (vì nó thuận tiện mặc định). phạm vi):
package org.springframework.statemachine.support;
public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSupport<S, E> implements StateMachine<S, E>, StateMachineAccess<S, E> {
void setCurrentState(State<S, E> state, Message<E> message, Transition<S, E> transition, boolean exit, StateMachine<S, E> stateMachine)
}
package org.springframework.statemachine.support;
public class MyStateMachineWrapper<S, E> {
private AbstractStateMachine<S, E> stateMachine;
public MyStateMachineWrapper(StateMachine<S, E> stateMachine) {
if (stateMachine instanceof AbstractStateMachine) {
this.stateMachine = (AbstractStateMachine<S, E>)stateMachine;
} else {
throw new IllegalArgumentException("Provided StateMachine is not a valid type");
}
}
public void setCurrentState(S status) {
stateMachine.setCurrentState(findState(status), null, null, false, stateMachine);
}
private State<S, E> findState(S status) {
for (State<S, E> state : stateMachine.getStates()) {
if (state.getId() == status) {
return state;
}
}
throw new IllegalArgumentException("Specified status does not equate to valid State");
}
}
sau đó tôi có thể ném đoạn mã sau vào MyEntityListener.postLoad:
MyStateMachineWrapper<MyState, Event> myStateMachineWrapper = new MyStateMachineWrapper<>(entity.getStateMachine());
myStateMachineWrapper.setCurrentState(entity.getInternalState());
Phương pháp trên dường như hoạt động tốt nhưng tôi không thể tưởng tượng được đây là cách nó được hình dung để hoạt động. Chắc chắn có một phương pháp sạch hơn để đạt được điều này hoặc có lẽ dự án không đủ trưởng thành và chưa bao gồm chức năng này?
Cảm ơn mọi ý kiến và ý kiến.
Những gì bạn đang cố gắng làm chưa thể bởi vì chúng ta đang thiếu một số tính năng bên trong. https://github.com/spring-projects/spring-statemachine/issues/34 và https://github.com/spring-projects/spring-statemachine/issues/35 liên quan trực tiếp đến các tính năng này. Đồng bộ hóa máy nhà nước không chỉ cần thiết lập trạng thái hiện tại. Chúng tôi đang cố gắng để thực hiện SPI của một máy nhà nước phân phối có thể sử dụng để đồng bộ hóa và duy trì trạng thái hiện tại của nó và mọi thứ khác những gì nó cần để hoạt động đúng. Tôi hiện đang lên kế hoạch để bắt đầu công việc này ngay bây giờ mà cột mốc thứ hai đã hết. –
Cảm ơn bạn đã làm rõ điều đó. Vì không có cách tiếp cận chính xác nào, tôi sẽ kiểm tra kỹ cách giải quyết ở trên vì trường hợp sử dụng của chúng tôi khá hạn chế ngay bây giờ và hy vọng chúng tôi có thể thực hiện mà không cần thay đổi sắp tới của bạn. – Alan
Alan, entity.getStateMachine() cho null, đó là bình thường, vì nó là thoáng qua. Làm thế nào để làm việc này nếu bạn vượt qua null trong MyStateMachineUtils.setCurrentState (entity.getStateMachine(), entity.getInternalState()); – Petar