96SEO 2026-09-09 16:26 1
打开 jeeflow-core 的 pom.xml运行时依赖只有一行:

org.slf4j
slf4j-api
provided
provided 代表着连 slf4j 都不打包——由集成方提供。怎么说呢,junit、jackson、slf4j-simple 全部是 test scope。不进 JAR,
jeeflow-core 编译产物:零框架依赖。 不碰 Spring、不碰 MyBatis、不碰 Jackson、不碰任何 ORM。
痛点: 你是否因为引擎绑定了大量框架而导致集成成本高、升级困难?这款引擎可让你自由选择框架。
一个工作流引擎,不依赖 JSON 库怎么解析流程定义?不依赖 ORM 怎么持久化?不依赖 Spring 怎么管理事务?答案这方面,SPI. 引擎只定义接口。实现交给集成方,说起来,
jeeflow 定义了 X个 SPI 接口。按必须/可选分为两档:
| SPI | 必须/可选 | 职责 | 不注册的后果 |
|---|---|---|---|
| IProcessRepository | MUST 聚合仓储 – 引擎读写数据的唯一通道,引擎无法启动。怎么说呢, |
d>
java
public interface IProcessRepository {
// 流程定义 CRUD
ProcessDefine findDefineById;void saveDefine;void updateDefine;// 聚合根操作
ProcessInstance findInstanceById;void saveInstance;void updateInstance;// 任务操作
ProcessTask findTaskById;List
java
public interface IJsonProvider {
String toJson;
> 把解析逻辑留给集成方可以避免版本冲突和多余依赖。
: 产生兼容性问题;不过,通过 SPI 可随时切换。怎么说呢,
java public interface IUserProvider { /** 一次返回使用者全部信息 */ UserInfo getUser;public static final class UserInfo { public final String userId;public final String realName;public final String deptId;老实说,public final String deptName;老实说,public final String postId;public final String postName;
public static UserInfo of { …}
}
}
当流程启动时 Engine 调用 FlowUtil.addUserInfoToArgs。 把使用者信息注入到流程变量中:
java
// 注入后流程变量里有:
// u_userid = "admin"
// u_realName = "蒙立东"
// u_deptid = "dept_rnd"
// u_deptname = "研发部"
该方式使决策表达式可以直接引用 u_* 变量,例如 u_deptid == 'dept_finance'。
: 若未注册 IUserProvider。则所有 u_* 变量缺失,你可能需要手动补全或
业务规则。
java
public interface IExpressionEvaluator {
Object eval;怎么说呢,}
决策节点 的边上挂着条件表达式:
json
{
"sourceNode":"decision1"。"targetNode":"task_manager","properties":{
"expr"这方面,"amount>= limit"
}
}
Engine 调用 evaluator.eval 判断走哪条边。
Spring Boot 集成示例:
java
public class SpelExpressionEvaluator implements IExpressionEvaluator {
public Object eval {
ExpressionParser parser = new SpelExpressionParser;StandardEvaluationContext ctx = new StandardEvaluationContext;ctx.setVariables;return parser.parseExpression.getValue;}
}
若未注册。则决策节点只能走默认分支,简单审批流程无大碍。
: 对于复杂业务,你可能需要自定义表达式语言来支持更多运算符或函数;SPI 给你完全控制权,但也代表着要自行实现或集成第三方求值器。
java
public interface IIdGenerator {
long nextID;}
若未注册。则采用时间戳 + 序号方案,简单可靠,但在分布式场景下可能冲突。
Spring Boot 默认用雪花算法:
java
public class SnowflakeIDGenerator implements IIDGenerator {
@Override long nextID { …}
}
业务方也可以替换为数据库序列、UUID 或自定义方案。按理说,
: 在高并发或跨机房环境下默认方案可能导致 ID 冲突。需要自行实现更健壮的生成器。
java
public interface ITransactionTemplate {
T execute;default void execute{…}
interface Supplier
Engine 内部不带事务注解,用 runInTx 包裹需要事务的操作:
java
private
java
public class SpringTransactionTemplate implements ITransactionTemplate{
@Autowired PlatformTransactionManager txManager;@Override T execute{
return new TransactionTemplate.execute;}catch{throw new RuntimeException;} }),}
}
只调用 execute;具体怎么做由集成层决定,
: 若你所在项目已经有自研事务管理或使用其他框架。你需要自行提供相应实现,否则 Engine 将以无事务方式运行。说起来,
Jeeflow 并未使用 Spring DI。而是自己实现轻量级服务定位器。
java
interface Context {
void put;void put,findList;}
java
class SimpleContext implements Context{
private final ConcurrentHashMap
一个 ConcurrentHashMap。即按类型查找,无反射开销。
java
finalclass ServiceContext{
private static volatile Context context;public static
全局静态访问点,使 Engine 任意地方通过 ServiceContext.find 拿到对应 SPI 实现。怎么说呢,
java @Configuration @ConditionalOnClass class JeeflowAutoConfiguration{ @Bean @ConditionalOnMissingBean IJsonProvider jeeflowJson{return new JacksonJsonProvider;老实说,}
@Bean @ConditionalOnMissingBean IIDGenerator jeeflowGen{return new SnowflakeIDGenerator;}
@Bean @ConditionalOnMissingBean ITransactionTemplate jeeflowTx{return new SpringTx;}
@Bean JeeflowEngine engine{ PRepo.ifAvailable);,/* 所有 SPI via ServiceContext.put */ } } @ConditionalOnMissingBean 的魔力让业务方只需声明同名 Bean 即覆盖任意 SPI 默认实现,实现零配置
除了上述基础设施 SPI 外还有业务层面的 AssignmentHandler:
java
interface AssignmentHandler{ String assign;其实,}
它决定“这个任务该分配给谁”。Engine 内置 X 个实现,如 OperatorAssignmentHandler、ApplicantDeptLeaderAssignmentHandler 等。
关键设计是组织维度 handler 如 DeptLeaderAssignmentHandler 等仅通过 IOrgUserProvider 获取部门领导列表,而非直连组织服务;业务方只需实现几个方法即可复用多种 handler,无需重复编码。
有人问为何不用插件行业市场,让社区贡献 SPI 实现?
原因是 jeeflow 的目标不是“可 ”,而是 “可替换”。不过,* 插件是在引擎之上加功能;* SPI 把外部依赖暴露出来让集成方用自己的实现替换。
Jeeflow 覆盖了所有外部依赖: * 数据存储 → IProcessRepository * JSON → IJsonProvider * 使用者 → IUserProvider * 表达式 → IExpressionEvaluator * ID → IIDGenerator * 事务 → ITransactionTemplate
这样 Engine 可以跑在 Spring Boot / GoFrame / FastAPI / Laravel 等不同技术栈上—换框架不换引擎。
98KB 的 engine。零框架依赖,通过 X 个 SPI 撬动五语言环境。
SPI 并非纯粹架构洁癖,而是工程刚需——同构前提是主要不绑定任何语言特定框架;Java 引擎无需 Spring。Go 引擎无需 Gin,Python 一样如此。
至于下一篇预告,第 N 页 · 会签三兄弟:并行/串行/按比例如何组合出三种模式?一票否决级联废弃怎么做,
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback