Springboot集成SpringState狀態(tài)機的實現(xiàn)
1.SpringState 簡介
狀態(tài)機核心概念??
| 項目 | 說明 |
|---|---|
| 狀態(tài)(State)?? | 對象生命周期中的特定條件(如訂單的待支付、已發(fā)貨) |
| 事件(Event)?? | 觸發(fā)狀態(tài)轉(zhuǎn)換的動作(如支付成功、取消訂單) |
| 轉(zhuǎn)換(Transition)?? | 定義事件如何驅(qū)動狀態(tài)遷移(如待支付 → 支付事件 → 待發(fā)貨) |
| 守衛(wèi)(Guard)?? | 條件檢查,決定是否允許轉(zhuǎn)換(如“僅未超時訂單可支付”) |
| ??動作(Action)?? | 條件檢查,決定是否允許轉(zhuǎn)換(如“僅未超時訂單可支付”) |
應(yīng)用場景
訂單生命周期管理??
管理訂單從創(chuàng)建到完成的完整流程(如待支付 → 待發(fā)貨 → 已完成)工作流引擎??
審批流程的狀態(tài)控制(如提交 → 審核中 → 已批準(zhǔn))??游戲狀態(tài)流轉(zhuǎn)??
角色狀態(tài)切換(如空閑 → 戰(zhàn)斗 → 死亡)物聯(lián)網(wǎng)設(shè)備監(jiān)控??
設(shè)備狀態(tài)跟蹤(如離線 → 在線 → 故障)
2.狀態(tài)機示例
2.1 項目結(jié)構(gòu)和依賴包

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>spring-state-m</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-boot.version>3.5.3</spring-boot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- Spring State Machine -->
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-starter</artifactId>
<version>4.0.0</version>
</dependency>
<!-- Spring State Machine Redis Persistence -->
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-data-redis</artifactId>
<version>4.0.0</version>
</dependency>
</dependencies>
</project>
啟動類
package org.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@EnableAsync
@SpringBootApplication
public class SpringStateMachine {
public static void main(String[] args) {
SpringApplication.run(SpringStateMachine.class, args);
}
}
2.2 定義事件類和狀態(tài)類
事件用于驅(qū)動狀態(tài)轉(zhuǎn)移,狀態(tài)用于記錄事件進度
事件類
package org.example.common;
/**
* @Author zhx && moon
* @Since 21
* @Date 2025-06-18 PM 6:38
*/
public enum OrderEvent {
PAY, // 支付操作
SHIP, // 發(fā)貨操作
CONFIRM, // 確認收貨
CANCEL // 取消訂單
}
狀態(tài)類
package org.example.common;
/**
* @Author zhx && moon
* @Since 21
* @Date 2025-06-18 PM 6:37
*/
public enum OrderState {
UNPAID, // 待支付
PAID, // 已支付
SHIPPED, // 已發(fā)貨
CONFIRMED, // 已確認收貨
CANCELLED // 已取消
}
2.3 Spring 事件監(jiān)聽器
Spring 事件監(jiān)聽器,用于異步處理事件流,當(dāng)狀態(tài)機結(jié)束時,推送當(dāng)前狀態(tài)機到監(jiān)聽器,監(jiān)聽器則從持久化中刪除該狀態(tài)機
package org.example.config;
import org.example.entity.OrderSMContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
/**
* @Author zhx && moon
* @Since 21
* @Date 2025-06-20 AM 10:18
*/
@Component
public class AsyncEventListener {
Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
SMContainer smContainer;
@Async
@EventListener
public void handleAsyncEvent(OrderSMContext context) {
logger.info("order id {} has delete {}", context.getOrderId(), smContainer.delete(context.getOrderId()));
}
}
2.4 狀態(tài)機持久化類
利用 Redis 做狀態(tài)機的持久化存儲
2.4.1 Redis 狀態(tài)機持久化容器
package org.example.config;
import org.example.common.OrderEvent;
import org.example.common.OrderState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.statemachine.data.redis.RedisStateMachineContextRepository;
import org.springframework.statemachine.persist.RepositoryStateMachinePersist;
import org.springframework.stereotype.Component;
/**
* @Author zhx && moon
* @Since 21
* @Date 2025-06-18 PM 6:54
*/
@Component
public class MYRedisPerSisterConfig {
@Autowired
private RedisConnectionFactory factory;
/**
* 創(chuàng)建 RedisStateMachineRepository 實例
*/
@Bean(name = "redisStateMachineContextRepository")
public MYRedisStateMachinePer<OrderState, OrderEvent> getRedisPerSister() {
// 創(chuàng)建 RedisStateMachineRepository 實例
RedisStateMachineContextRepository<OrderState, OrderEvent> repository = new RedisStateMachineContextRepository<>(factory);
// 持久化
RepositoryStateMachinePersist perSister = new RepositoryStateMachinePersist(repository);
// 獲取 Redis StateMachinePerSister 實例
MYRedisStateMachinePer machine = new MYRedisStateMachinePer<>(perSister);
RedisTemplate<String, byte[]> redisTemplate = createDefaultTemplate(factory);
machine.setRedisTemplate(redisTemplate);
// 返回
return machine;
}
/**
* 與 RedisStateMachineContextRepository 使用相同的序列化配置
* @param connectionFactory
* @return
*/
private static RedisTemplate<String, byte[]> createDefaultTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, byte[]> template = new RedisTemplate();
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setConnectionFactory(connectionFactory);
template.afterPropertiesSet();
return template;
}
}
2.4.2 Redis 配置
package org.example.config;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.statemachine.StateMachinePersist;
import org.springframework.statemachine.data.redis.RedisStateMachinePersister;
/**
* @Author zhx && moon
* @Since 21
* @Date 2025-06-19 PM 5:21
*/
public class MYRedisStateMachinePer<S, E> extends RedisStateMachinePersister<S, E> {
RedisTemplate<String, byte[]> redisTemplate;
public MYRedisStateMachinePer(StateMachinePersist<S, E, String> stateMachinePersist) {
super(stateMachinePersist);
}
public void setRedisTemplate(RedisTemplate<String, byte[]> redisTemplate){
this.redisTemplate = redisTemplate;
}
/**
* 檢查 Redis 中是否存在指定的 key
* @param key
* @return
*/
public boolean isUnExist(String key){
return !this.redisTemplate.hasKey(key);
}
/**
* 刪除 Redis 中指定的 key
* @param key
* @return
*/
public boolean deleteKey(String key){
return this.redisTemplate.delete(key);
}
}
2.4.3 狀態(tài)機監(jiān)聽器
用于監(jiān)聽狀態(tài)機狀態(tài)變化
package org.example.config;
import org.example.common.OrderEvent;
import org.example.common.OrderState;
import org.example.entity.OrderSMContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.messaging.Message;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.listener.StateMachineListenerAdapter;
import org.springframework.statemachine.state.State;
import org.springframework.stereotype.Component;
/**
* @Author zhx && moon
* @Since 21
* @Date 2025-06-19 PM 4:58
*/
@Component
public class RedStateMachineListener extends StateMachineListenerAdapter<OrderState, OrderEvent> {
Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private ApplicationEventPublisher publisher;
/**
* 狀態(tài)變化
* @param from
* @param to
*/
@Override
public void stateChanged(State<OrderState, OrderEvent> from, State<OrderState, OrderEvent> to) {
// 狀態(tài)變更時的處理
if (null == from) {
logger.info("state machine init, from Init to {}", to.getId());
} else {
logger.info("state machine change, from {} to {}", from.getId(), to.getId());
}
}
/**
* 狀態(tài)機啟動成功時的回調(diào)
* @param sm
*/
@Override
public void stateMachineStarted(StateMachine<OrderState, OrderEvent> sm) {
logger.info("state machine {} start success.", sm.getId());
}
/**
* 狀態(tài)機結(jié)束的回調(diào)
* @param sm
*/
@Override
public void stateMachineStopped(StateMachine<OrderState, OrderEvent> sm) {
logger.info("state machine {} stop success.", sm.getId());
publisher.publishEvent(new OrderSMContext(sm.getId()));
}
@Override
public void eventNotAccepted(Message<OrderEvent> event) {
logger.error("Event not accepted: {}", event.getPayload());
}
}
2.5 裝機器容器
用于管理狀態(tài)機的創(chuàng)建,本地化緩存與持久化存儲
package org.example.config;
import org.example.common.OrderEvent;
import org.example.common.OrderState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.config.StateMachineFactory;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* @Author zhx && moon
* @Since 21
* @Date 2025-06-19 PM 4:30
*/
@Component
public class SMContainer {
Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private StateMachineFactory<OrderState, OrderEvent> factory;
@Autowired
private MYRedisStateMachinePer<OrderState, OrderEvent> myRedisStateMachinePer;
private Map<String, StateMachine<OrderState, OrderEvent>> map = new HashMap<>(16);
/**
* 獲取狀態(tài)機
* @param orderId 訂單ID
* @return 狀態(tài)機實例
*/
public synchronized StateMachine<OrderState, OrderEvent> getStateMachine(String orderId) {
String key = getKey(orderId);
try {
// 取緩存
StateMachine<OrderState, OrderEvent> sm = map.get(orderId);
// 校驗
if (Objects.isNull(sm)) {
// 獲取狀態(tài)機實例
sm = factory.getStateMachine(orderId);
// 校驗是否存在
if (myRedisStateMachinePer.isUnExist(key)) {
sm.startReactively().subscribe();
myRedisStateMachinePer.persist(sm, key);
} else {
// 恢復(fù)狀態(tài)
myRedisStateMachinePer.restore(sm, key);
}
// 緩存狀態(tài)機
map.put(orderId, sm);
}
return sm;
} catch (Exception e) {
logger.error("get state machine error: {}", e.getMessage(), e);
return null;
}
}
/**
* 保存狀態(tài)機
* @param orderId
* @param stateMachine
*/
public synchronized boolean save(StateMachine<OrderState, OrderEvent> stateMachine, String orderId){
try {
String key = getKey(orderId);
myRedisStateMachinePer.persist(stateMachine, key);
return true;
} catch (Exception e) {
logger.error("save state machine error: {}", e.getMessage(), e);
return false;
}
}
/**
* 刪除狀態(tài)機
* @param orderId
* @return
*/
public synchronized boolean delete(String orderId){
return myRedisStateMachinePer.deleteKey(getKey(orderId));
}
/**
* 獲取 KEY
* @param orderId
* @return
*/
private String getKey(String orderId){
return "STATE-MACHINE:" +orderId;
}
}
2.6 狀態(tài)機事件發(fā)送器
用于統(tǒng)一發(fā)送狀態(tài)機事件,管理事件發(fā)送過程
package org.example.config;
import org.example.common.OrderEvent;
import org.example.common.OrderState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.StateMachineEventResult;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @Author zhx && moon
* @Since 21
* @Date 2025-06-20 PM 2:22
*/
@Component
public class SMEventSender {
Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
SMContainer smContainer;
/**
* 初始化訂單狀態(tài)機
* @param orderId
*/
public void initOrderStateMachine(String orderId) {
smContainer.getStateMachine(orderId);
}
/**
* 發(fā)送事件
* @param orderId
* @param event
* @return
*/
public boolean send(String orderId, OrderEvent event) {
// 獲取狀態(tài)
StateMachine<OrderState, OrderEvent> sm = smContainer.getStateMachine(orderId);
// 構(gòu)建事件消息
Message<OrderEvent> message = MessageBuilder
.withPayload(event)
.setHeader("orderId", orderId) // 訂單對象關(guān)聯(lián)狀態(tài)機
.build();
// 發(fā)送事件
AtomicBoolean result = new AtomicBoolean(false);
sm.sendEvent(Mono.just(message)).subscribe(r->{
if (r.getResultType() == StateMachineEventResult.ResultType.ACCEPTED) {
// 成功
result.set(true);
// 在未完成時持久化
if (!OrderEvent.CONFIRM.equals(event)) {
smContainer.save(sm, orderId);
}
} else {
result.set(false);
}
});
// 輸出
logger.info("send event: {}, orderId: {}, result: {}", event, orderId, result.get());
// 返回
return result.get();
}
}
2.7 狀態(tài)機配置
狀態(tài)機配置,定義事件和狀態(tài)關(guān)系,以及守衛(wèi)和動作
package org.example.config;
import org.example.common.OrderEvent;
import org.example.common.OrderState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.config.EnableStateMachineFactory;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import java.util.EnumSet;
/**
* @Author zhx && moon
* @Since 21
* @Date 2025-06-18 PM 6:38
*/
@Configuration
@EnableStateMachineFactory
public class StateMachineConfig extends StateMachineConfigurerAdapter<OrderState, OrderEvent> {
Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
RedStateMachineListener listener;
@Override
public void configure(StateMachineConfigurationConfigurer<OrderState, OrderEvent> config) throws Exception {
config.withConfiguration()
// 注冊監(jiān)聽器
.listener(listener);
}
/**
* 狀態(tài)機初始化
* @param states
* @throws Exception
*/
@Override
public void configure(StateMachineStateConfigurer<OrderState, OrderEvent> states) throws Exception {
states.withStates()
.initial(OrderState.UNPAID)
.states(EnumSet.allOf(OrderState.class))
.end(OrderState.CONFIRMED)
.end(OrderState.CANCELLED);
}
/**
* 狀態(tài)轉(zhuǎn)移邏輯
* @param transitions
* @throws Exception
*/
@Override
public void configure(StateMachineTransitionConfigurer<OrderState, OrderEvent> transitions) throws Exception {
transitions
// 支付:UNPAID -> PAID
.withExternal()
.source(OrderState.UNPAID)
.target(OrderState.PAID)
.guard(context -> {
// (前置)守衛(wèi)條件,校驗支付結(jié)果
logger.info("check order {} pay result ...", context.getMessageHeader("orderId"));
return true;
})
.action(context -> {
// (后置)觸發(fā)動作,通知倉庫備貨
logger.info("order {} pay success, notify warehouse to prepare goods ...", context.getMessageHeader("orderId"));
})
.event(OrderEvent.PAY)
.and()
// 發(fā)貨:PAID -> SHIPPED
.withExternal()
.source(OrderState.PAID)
.target(OrderState.SHIPPED)
.event(OrderEvent.SHIP)
.and()
// 確認收貨:SHIPPED -> CONFIRMED
.withExternal()
.source(OrderState.SHIPPED)
.target(OrderState.CONFIRMED)
.event(OrderEvent.CONFIRM)
.and()
// 取消訂單(僅在待支付可取消)
.withExternal()
.source(OrderState.UNPAID)
.target(OrderState.CANCELLED)
.event(OrderEvent.CANCEL);
}
}
2.8 接口類
用于模擬訂單操作
package org.example.controller;
import org.example.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author zhx && moon
* @Since 21
* @Date 2025-06-18 PM 6:41
*/
@RestController
@RequestMapping("/orders")
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping("/create")
public String create() {
return orderService.createOrder();
}
@GetMapping("/pay/{orderId}")
public String pay(@PathVariable("orderId") String orderId) {
return orderService.payOrder(orderId);
}
@GetMapping("/shipped/{orderId}")
public String shipped(@PathVariable("orderId") String orderId) {
return orderService.shipped(orderId);
}
@GetMapping("/confirm/{orderId}")
public String confirm(@PathVariable("orderId") String orderId) {
return orderService.confirm(orderId);
}
@GetMapping("/{orderId}/status")
public String status(@PathVariable String orderId) {
return "當(dāng)前狀態(tài): " + orderService.getOrderState(orderId);
}
}
2.9 實現(xiàn)類
package org.example.service;
import org.example.common.OrderEvent;
import org.example.common.OrderState;
import org.example.config.SMEventSender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @Author zhx && moon
* @Since 21
* @Date 2025-06-18 PM 6:40
*/
@Service
public class OrderService {
@Autowired
SMEventSender smEventSender;
/**
* 創(chuàng)建訂單并初始化狀態(tài)機
* @return
*/
public String createOrder() {
try {
// 使用時間戳作為訂單ID
String orderId = String.valueOf(System.currentTimeMillis());
// 初始化
smEventSender.initOrderStateMachine(orderId);
// 返回訂單ID
return orderId;
} catch (Exception e) {
return e.getMessage();
}
}
/**
* 支付
* @param orderId
* @return
*/
public String payOrder(String orderId) {
try {
boolean result = smEventSender.send(orderId, OrderEvent.PAY);
return "success:" + result;
} catch (Exception e) {
return e.getMessage();
}
}
/**
* 發(fā)貨
* @param orderId
* @return
*/
public String shipped(String orderId) {
try {
boolean result = smEventSender.send(orderId, OrderEvent.SHIP);
return "success:" + result;
} catch (Exception e) {
return e.getMessage();
}
}
/**
* 確認收貨
* @param orderId
* @return
*/
public String confirm(String orderId) {
try {
boolean result = smEventSender.send(orderId, OrderEvent.CONFIRM);
return "success:" + result;
} catch (Exception e) {
return e.getMessage();
}
}
public OrderState getOrderState(String orderId) {
return OrderState.UNPAID;
}
}
2.10 狀態(tài)機上下文
用于管理狀態(tài)機信息
package org.example.entity;
import org.example.common.OrderState;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
/**
* @Author zhx && moon
* @Since 21
* @Date 2025-06-18 PM 6:54
*/
public class OrderSMContext {
public OrderSMContext(String orderId){
this.orderId = orderId;
}
private String orderId;
private OrderState currentState;
private Map<String, Object> extendedState = new HashMap<>();
private LocalDateTime createdAt;
private LocalDateTime lastModifiedAt;
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
}
2.11 配置文件
spring:
data:
redis:
database: 0
host: 192.168.1.103
port: 6379
password: 123456
timeout: 5000
3.狀態(tài)機測試
3.1創(chuàng)建訂單

3.2持久化結(jié)果
初始化時自動將數(shù)據(jù)持久化到 Redis

3.3 支付訂單

3.4 發(fā)貨

3.5 確認收貨

后臺日志

到此這篇關(guān)于Springboot集成SpringState狀態(tài)機的實現(xiàn)的文章就介紹到這了,更多相關(guān)SpringState 狀態(tài)機內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JAVA HashSet和TreeSet 保證存入元素不會重復(fù)的操作
這篇文章主要介紹了JAVA HashSet和TreeSet 保證存入元素不會重復(fù)的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09
Spring+SpringMVC+MyBatis深入學(xué)習(xí)及搭建(二)之MyBatis原始Dao開發(fā)和mapper代理開發(fā)
這篇文章主要介紹了Spring+SpringMVC+MyBatis深入學(xué)習(xí)及搭建(二)之MyBatis原始Dao開發(fā)和mapper代理開發(fā),需要的朋友可以參考下2017-05-05
freemarker?jsp?java內(nèi)存方式實現(xiàn)分頁示例
這篇文章主要介紹了freemarker?jsp?java內(nèi)存方式實現(xiàn)分頁示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-06-06
spring-boot整合dubbo:Spring-boot-dubbo-starter
這篇文章主要介紹了spring-boot整合dubbo:Spring-boot-dubbo-starter的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-05-05
Spring boot中自定義Json參數(shù)解析器的方法
這篇文章主要介紹了Spring boot中自定義Json參數(shù)解析器的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-01-01
java中VO PO DTO POJO BO DO對象的應(yīng)用場景及使用
文章介紹了Java開發(fā)中常用的幾種對象類型及其應(yīng)用場景,包括VO、PO、DTO、POJO、BO和DO等,并通過示例說明了它們在不同場景下的應(yīng)用2025-01-01
Netty分布式NioEventLoop任務(wù)隊列執(zhí)行源碼分析
這篇文章主要為大家介紹了Netty分布式NioEventLoop任務(wù)隊列執(zhí)行源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-03-03
Java里得到00:00:00格式的時分秒的Timestamp
Java里如何得到00:00:00格式的時分秒的Timestamp ,下面是具體的實現(xiàn)代碼,需要的朋友可以參考下。2009-09-09

