lambda表达式构建可插拔校验规则库,通过泛型函数式接口+双键注册中心实现类型安全、动态组合与上下文解耦。

用 Lambda 表达式构建可插拔的业务校验规则库,核心是把“验证逻辑”变成可动态注册、组合和执行的一等公民。变量验证不再硬编码在业务流程里,而是通过函数式接口 + Map/Registry 管理规则,实现高内聚、低耦合。
定义统一的校验函数接口
Java 中推荐使用 Function
@FunctionalInterface
public interface Validator<t> {
ValidationResult validate(T value);
}
// ValidationResult 封装是否通过、错误码、提示语等
</t>
这样每个校验规则就是一个 Lambda 实例,例如:
Validator<string> notBlank = s ->
StringUtils.isBlank(s)
? new ValidationResult(false, "不能为空")
: ValidationResult.success();
Validator<integer> positive = i ->
i == null || i
</integer></string>
用 Registry 管理可插拔规则
避免 if-else 或 switch 分支,用 Map 按“业务场景+字段名”或“规则 ID”索引规则:
public class ValidationRegistry {
private final Map<string validator>> registry = new ConcurrentHashMap();
public <t> void register(String ruleId, Validator<t> validator) {
registry.put(ruleId, validator);
}
@SuppressWarnings("unchecked")
public <t> ValidationResult validate(String ruleId, T value) {
Validator<t> validator = (Validator<t>) registry.get(ruleId);
return validator != null ? validator.validate(value) : ValidationResult.success();
}
}
</t></t></t></t></t></string>
使用时可动态加载:
- 启动时扫描 @ValidateRule 注解的 Bean 自动注册
- 从配置中心拉取规则脚本(配合 Groovy/Janino 编译为 Lambda)
- 运行时通过 API 注册新规则(如运营后台配置手机号格式校验)
组合多个规则做链式验证
Lambda 天然支持函数组合。扩展 Validator 接口,添加 andThen 方法:
default Validator<t> andThen(Validator<t> after) {
return t -> {
ValidationResult r1 = this.validate(t);
if (!r1.isSuccess()) return r1;
return after.validate(t);
};
}
</t></t>
轻松组装规则:
Validator<string> mobileValidator = notBlank.andThen(formatMobile).andThen(inBlacklist);
ValidationResult result = mobileValidator.validate("13800138000");
</string>
结合泛型与类型擦除规避强制转换
上面 registry 的 > 带来类型不安全。更健壮的做法是按 Class
private final Map<class>, Map<string validator>>> typeBasedRegistry = new ConcurrentHashMap();
public <t> void register(Class<t> type, String ruleId, Validator<t> validator) {
typeBasedRegistry.computeIfAbsent(type, k -> new ConcurrentHashMap())
.put(ruleId, validator);
}
@SuppressWarnings("unchecked")
public <t> ValidationResult validate(Class<t> type, String ruleId, T value) {
Map<string validator>> rules = typeBasedRegistry.get(type);
Validator<t> validator = rules == null ? null : (Validator<t>) rules.get(ruleId);
return validator != null ? validator.validate(value) : ValidationResult.success();
}
</t></t></string></t></t></t></t></t></string></class>
调用时明确传入类型:registry.validate(String.class, "mobile", phone),安全且清晰。
不复杂但容易忽略:Lambda 是状态无关的纯函数,规则本身不应持有上下文(如用户会话)。需要访问上下文的校验,应封装成 Supplier










