You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通用库自定义异常适配问题:多仓库不同异常类复用

最优通用配置方案

以下是几种无需逐个方法传参的通用解决方案,按解耦程度和可维护性排序:

1. 依赖注入+异常工厂模式

定义统一的异常工厂接口,让两个仓库各自实现该接口,通用库仅依赖接口生成异常,完全隔离具体异常类的耦合。

通用库代码

// 通用库中定义异常工厂接口
public interface ExceptionFactory {
    RuntimeException create(String message);
    RuntimeException create(String message, Throwable cause);
}

// 通用库业务类,通过构造器注入工厂
public class CommonBusinessService {
    private final ExceptionFactory exceptionFactory;

    public CommonBusinessService(ExceptionFactory exceptionFactory) {
        this.exceptionFactory = exceptionFactory;
    }

    public void validateParam(String param) {
        if (param == null || param.isBlank()) {
            throw exceptionFactory.create("参数不能为空");
        }
    }
}

仓库实现代码

Recruit仓库提供自己的工厂实现:

public class RecruitExceptionFactory implements ExceptionFactory {
    @Override
    public RuntimeException create(String message) {
        return new RecruitException(message);
    }

    @Override
    public RuntimeException create(String message, Throwable cause) {
        return new RecruitException(message, cause);
    }
}

// 初始化通用库组件时传入工厂
CommonBusinessService service = new CommonBusinessService(new RecruitExceptionFactory());

Developer仓库同理,实现DeveloperExceptionFactory即可。

2. SPI服务自动发现机制

利用语言自带的SPI(服务提供者接口)机制,让通用库在启动时自动加载对应仓库的异常工厂实现,无需手动注入。

通用库代码

复用上面的ExceptionFactory接口,新增加载器:

public class ExceptionFactoryLoader {
    public static ExceptionFactory get() {
        ServiceLoader<ExceptionFactory> loader = ServiceLoader.load(ExceptionFactory.class);
        return loader.findFirst().orElseThrow(() -> new IllegalStateException("未找到异常工厂实现"));
    }
}

// 通用库业务类直接使用加载器获取工厂
public class CommonBusinessService {
    private final ExceptionFactory exceptionFactory = ExceptionFactoryLoader.get();

    public void doBusiness() {
        if (someError) {
            throw exceptionFactory.create("业务执行失败");
        }
    }
}

仓库配置

在Recruit仓库的META-INF/services目录下创建文件com.yourpackage.ExceptionFactory,内容为:

com.recruit.RecruitExceptionFactory

Developer仓库同理,创建对应文件并写入自己的工厂类全限定名。

3. 类路径检测动态生成异常

如果不想引入工厂类,可通过检测类路径中存在的异常类,动态反射创建实例,适合简单场景。

通用库代码

public class ExceptionCreator {
    private static Class<? extends RuntimeException> targetException;

    static {
        try {
            // 优先检测RecruitException
            targetException = Class.forName("com.recruit.RecruitException").asSubclass(RuntimeException.class);
        } catch (ClassNotFoundException e) {
            try {
                // 检测失败则加载DeveloperException
                targetException = Class.forName("com.developer.DeveloperException").asSubclass(RuntimeException.class);
            } catch (ClassNotFoundException ex) {
                throw new IllegalStateException("未找到指定异常类");
            }
        }
    }

    public static RuntimeException create(String message) {
        try {
            return targetException.getConstructor(String.class).newInstance(message);
        } catch (Exception e) {
            throw new RuntimeException("创建异常失败", e);
        }
    }
}

// 通用库业务类使用
public class CommonBusinessService {
    public void processData() {
        if (dataInvalid) {
            throw ExceptionCreator.create("数据格式无效");
        }
    }
}

注意事项

需确保两个异常类的构造方法签名完全一致(比如都有String参数的构造器)。


内容的提问来源于stack exchange,提问作者Yash Mittal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 04:41:09