Java通过自定义@StateTransition注解配合AOP实现状态机流转校验:定义注解约束源/目标状态,构建规则元数据(如Map),AOP拦截方法前校验状态合法性,结合枚举提升类型安全。

<p>Java中通过自定义注解 <code>@StateTransition</code> 实现业务状态机流转合法性校验,核心思路是:定义注解约束「允许的源状态→目标状态」规则,配合 AOP 或反射在状态变更前动态校验是否符合预设流转路径。</p>
<H3>定义 @StateTransition 注解</H3>
<p>注解用于标注状态变更方法(如 <code>updateStatus()</code>),声明合法的流转关系:</p>
<ul>
<li>用 <code>@Target(METHOD)</code> 标明只能加在方法上</li>
<li>用 <code>@Retention(RUNTIME)</code> 确保运行时可通过反射读取</li>
<li>定义 <code>from()</code> 和 <code>to()</code> 属性,支持单值或数组(如 <code>from = {INIT, PROCESSING}</code>)</li>
<li>可选添加 <code>message()</code> 自定义校验失败提示</li>
</ul>
<p>示例:</p>
<font color="blue">public @interface StateTransition {<br>
String[] from() default {};<br>
String to();<br>
String message() default "状态流转不合法";<br>
}</font>
<H3>构建状态流转规则元数据</H3>
<p>不能只靠注解声明,还需一个可查询的规则中心。推荐用静态 Map 或 Spring Bean 管理:</p>
<ul>
<li>键为「源状态」,值为允许跳转到的目标状态集合(如 <code>Map.of("INIT", Set.of("PROCESSING", "CANCELLED"))</code>)</li>
<li>若使用 Spring,可将规则注入 <code>StateTransitionValidator</code> 类,便于统一维护和测试</li>
<li>支持从配置文件(YAML/JSON)加载规则,避免硬编码</li>
</ul>
<H3>实现校验逻辑(AOP 方式推荐)</H3>
<p>用 Spring AOP 拦截带 <code>@StateTransition</code> 的方法,在执行前校验参数中的状态值:</p>
<ul>
<li>获取目标方法上的注解,提取 <code>from()</code> 和 <code>to()</code></li>
<li>从方法参数(如第一个 DTO 或实体)中提取当前状态(<code>currentState</code>)和待更新状态(<code>targetState</code>)</li>
<li>检查 <code>currentState</code> 是否在 <code>from()</code> 列表中,且 <code>targetState</code> 是否等于 <code>to()</code> 或属于规则中心定义的合法目标集</li>
<li>不合法则抛出 <code>IllegalStateException</code> 或自定义异常,中断执行</li>
</ul>
<p>注意:需约定参数顺序或用 <code>@StateParam</code> 注解标记状态字段,提升健壮性。</p>
<H3>配合枚举增强类型安全</H3>
<p>状态建议用 enum 表达,而非字符串字面量:</p>
<ul>
<li>定义 <code>OrderStatus { INIT, PROCESSING, SHIPPED, COMPLETED, CANCELLED }</code></li>
<li>注解的 <code>from()</code> 和 <code>to()</code> 改为接收 <code>OrderStatus.class</code> 类型,或直接传 enum 常量(需用 <code>Class<? extends Enum></code> + 反射解析)</li>
<li>校验时比对 enum 实例,避免字符串拼写错误导致漏检</li>
</ul>
<p>这样既保持注解简洁,又获得编译期检查和 IDE 提示支持。</p>