本文目录导读:

在Java中,校验模块的复用是提升开发效率和代码质量的关键,以下我会从设计模式和实际案例两个维度,为你提供几种成熟的复用方案。
核心复用思路:分层解耦 + 策略化
基于注解的校验(JSR-380 / Bean Validation)
这是最标准的复用方式,适合简单字段校验。
// 1. 定义可复用的校验注解
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PhoneValidator.class)
public @interface ValidPhone {
String message() default "手机号格式错误";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
// 2. 校验逻辑实现(可复用)
public class PhoneValidator implements ConstraintValidator<ValidPhone, String> {
private static final String PHONE_REGEX = "^1[3-9]\\d{9}$";
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null || value.isEmpty()) {
return true; // 允许空值,用@NotNull配合
}
return value.matches(PHONE_REGEX);
}
}
// 3. 在任意实体中复用
public class UserDTO {
@ValidPhone
private String phone;
@ValidPhone(groups = {Admin.class}) // 分组校验
private String adminPhone;
}
复用方式:一个注解全局使用,业务代码无需重复写if判断。
策略模式 + 工厂模式(复杂业务校验)
当校验规则复杂且经常变动时,使用策略模式实现可插拔的校验单元。
// 1. 定义校验策略接口
public interface ValidationStrategy<T> {
ValidationResult validate(T target);
}
// 2. 实现具体策略(每个策略独立可复用)
public class OrderAmountStrategy implements ValidationStrategy<Order> {
@Override
public ValidationResult validate(Order order) {
if (order.getAmount() <= 0) {
return ValidationResult.fail("订单金额必须大于0");
}
return ValidationResult.success();
}
}
public class UserAgeStrategy implements ValidationStrategy<User> {
@Override
public ValidationResult validate(User user) {
if (user.getAge() < 0 || user.getAge() > 150) {
return ValidationResult.fail("年龄不合法");
}
return ValidationResult.success();
}
}
// 3. 策略工厂(管理校验规则组合)
public class ValidationFactory {
private static final Map<String, List<ValidationStrategy>> rules = new HashMap<>();
static {
rules.put("order", Arrays.asList(new OrderAmountStrategy(),
new OrderStatusStrategy()));
rules.put("user", Arrays.asList(new UserAgeStrategy(),
new UserNameStrategy()));
}
public static List<ValidationStrategy> getStrategies(String type) {
return rules.getOrDefault(type, Collections.emptyList());
}
}
// 4. 校验执行器(统一复用入口)
public class ValidationExecutor {
public static <T> ValidationResult execute(String type, T target) {
List<ValidationStrategy> strategies = ValidationFactory.getStrategies(type);
for (ValidationStrategy strategy : strategies) {
ValidationResult result = strategy.validate(target);
if (result.isFail()) {
return result;
}
}
return ValidationResult.success();
}
}
// 使用示例
Order order = new Order();
ValidationResult result = ValidationExecutor.execute("order", order);
复用方式:任意业务逻辑只要调用ValidationExecutor.execute("user", user)即可复用所有用户校验规则。
责任链模式(流水线式校验)
适合需要顺序执行且可动态组装的场景。
// 1. 抽象校验节点
public abstract class ValidationHandler {
protected ValidationHandler next;
public ValidationHandler setNext(ValidationHandler next) {
this.next = next;
return next;
}
public abstract boolean handle(Request request);
protected boolean handleNext(Request request) {
if (next == null) return true;
return next.handle(request);
}
}
// 2. 具体节点(可独立复用)
public class TokenValidationHandler extends ValidationHandler {
@Override
public boolean handle(Request request) {
if (request.getToken() == null || request.getToken().isEmpty()) {
System.out.println("Token校验失败");
return false;
}
System.out.println("Token校验通过");
return handleNext(request);
}
}
public class PermissionValidationHandler extends ValidationHandler {
@Override
public boolean handle(Request request) {
if (!"admin".equals(request.getRole())) {
System.out.println("权限不足");
return false;
}
System.out.println("权限校验通过");
return handleNext(request);
}
}
// 3. 动态组装校验链(复用点)
public class ValidationChainBuilder {
public static ValidationHandler buildDefaultChain() {
ValidationHandler tokenHandler = new TokenValidationHandler();
ValidationHandler permissionHandler = new PermissionValidationHandler();
tokenHandler.setNext(permissionHandler);
return tokenHandler; // 返回链头
}
}
// 使用
Request request = new Request();
ValidationHandler chain = ValidationChainBuilder.buildDefaultChain();
boolean pass = chain.handle(request);
复用方式:通过buildDefaultChain()轻松组装可复用的校验流水线,也可通过配置文件动态修改。
模板方法模式(固定校验骨架)
适合校验流程通用但具体校验逻辑不同的场景。
// 1. 抽象校验模板
public abstract class AbstractValidator<T> {
// 模板方法:定义校验的固定骨架
public final ValidationResult validate(T target) {
// 步骤1:基础非空校验
if (target == null) {
return ValidationResult.fail("目标对象不能为空");
}
// 步骤2:具体校验(子类实现)
ValidationResult specificResult = doValidate(target);
if (specificResult.isFail()) {
return specificResult;
}
// 步骤3:后置处理(可选)
postValidate(target);
return ValidationResult.success();
}
protected abstract ValidationResult doValidate(T target);
protected void postValidate(T target) {
// 默认空实现,子类可选覆盖
}
}
// 2. 具体实现类
public class UserValidator extends AbstractValidator<User> {
@Override
protected ValidationResult doValidate(User user) {
if (user.getName() == null || user.getName().length() < 2) {
return ValidationResult.fail("用户名至少2个字符");
}
return ValidationResult.success();
}
}
// 使用
UserValidator validator = new UserValidator();
ValidationResult result = validator.validate(user);
复用方式:所有校验器继承AbstractValidator,自动获得非空校验等通用逻辑。
企业级最佳实践:组合使用
实际项目中通常将上述模式组合:
校验架构分层:
├── 表现层(Controller)
│ ├── @Valid / @Validated 注解(处理基础字段校验)
│ └── 自定义注解(@Phone、@Email等)
├── 业务层(Service)
│ ├── 策略模式校验器(处理复杂业务规则)
│ └── 责任链校验器(处理流程化校验)
└── 基础设施层(Infrastructure)
├── 校验结果封装(ValidationResult)
├── 校验异常统一处理
└── 校验规则配置中心(规则可配置化)
关键复用技巧:
- 将校验逻辑剥离到独立模块(如
validation-common),所有微服务依赖 - 使用SPI或Spring Factories实现校验器的自动发现
- 规则配置化:将校验规则放入数据库或配置中心,运行时动态加载
选择哪种复用方式取决于你的业务复杂度:简单校验用注解,复杂校验用策略模式,流程校验用责任链,固定骨架用模板方法。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播