1. 引言
针对高效的Java任务执行:SafeExecutor工具类的设计理念与应用 中需补充多参数类,则需要再次设计新接口和新方法进行支持
2. 设计目标
CallableWithMultiParams
和 SafeExecutor
的设计目标包括:
1. 支持多类型参数和返回值的任务:处理带多个不同类型参数和返回值的任务,提供更高的灵活性和强大功能。
3. 关键组件
3.1 CallableWithMultiParams 接口
CallableWithMultiParams
是一个泛型函数式接口,表示一个带有多个不同类型参数并返回结果的任务。该接口可以抛出异常。
这个接口将支持多个不同类型的参数,并返回一个结果。
package com.dereksmart.crawling.util.fuction;
/**
* CallableWithMultiParams 是一个泛型接口,允许执行带有多个不同参数的任务并返回一个结果。
*
* @param <R> 返回值的类型
* @param <P> 参数的类型
* @Author derek_smart
* @Date 2025/2/19 7:45
*/
@FunctionalInterface
public interface CallableWithMultiParams<R, P1, P2, P3> {
R call(P1 param1, P2 param2, P3 param3) throws Exception;
default R callWithRuntimeException(P1 param1, P2 param2, P3 param3) {
try {
return call(param1, param2, param3);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
default R callWithoutException(P1 param1, P2 param2, P3 param3) {
try {
return call(param1, param2, param3);
} catch (Exception e) {
return null;
}
}
static <R, P1, P2, P3> CallableWithMultiParams<R, P1, P2, P3> empty() {
return (param1, param2, param3) -> null;
}
}
3.2 SafeExecutor
工具类
将提供一组静态方法来安全地执行 CallableWithMultiParams
,并处理异常。
package com.dereksmart.crawling.util.fuction;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
* 提供了一组静态方法来安全地执行同步和异步任务。
* 这些方法在执行过程中捕获异常,并通过指定的异常处理器处理异常。
* 该类提供了无返回值和有返回值的任务执行方法,并支持默认值和异常处理器的自定义。
* @Author derek_smart
* @Date 2025/2/18 8:50
*/
public final class SafeExecutor {
/**
* 默认的异常处理器,忽略所有异常。
*/
public static final Consumer<Exception> IGNORE_EXCEPTION_HANDLER = e -> {
};
private SafeExecutor() {
// Private constructor to prevent instantiation
}
// 同步方法
/**
* 执行一个无返回值的任务,并忽略任何异常。
*
* @param callable 要执行的任务
*/
public static void executeWithoutException(VoidCallable callable) {
execute(callable, IGNORE_EXCEPTION_HANDLER);
}
/**
* 执行一个无返回值的任务,并使用指定的异常处理器处理异常。
*
* @param callable 要执行的任务
* @param exceptionHandler 异常处理器
*/
public static void execute(VoidCallable callable, Consumer<Exception> exceptionHandler) {
try {
callable.call();
} catch (Exception e) {
handleException(e, exceptionHandler);
}
}
/**
* 执行一个有返回值的任务,并忽略任何异常。如果发生异常,返回 null。
*
* @param supplier 要执行的任务
* @param <T> 返回值的类型
* @return 任务的返回值,如果发生异常则返回 null
*/
public static <T> T supplyWithoutException(Supplier<T> supplier) {
return supplyWithoutException(supplier, null, IGNORE_EXCEPTION_HANDLER);
}
/**
* 执行一个有返回值的任务,并忽略任何异常。如果发生异常,返回指定的默认值。
*
* @param supplier 要执行的任务
* @param defaultValue 默认返回值
* @param <T> 返回值的类型
* @return 任务的返回值,如果发生异常则返回默认值
*/
public static <T> T supplyWithoutException(Supplier<T> supplier, T defaultValue) {
return supplyWithoutException(supplier, defaultValue, IGNORE_EXCEPTION_HANDLER);
}
/**
* 执行一个有返回值的任务,并使用指定的异常处理器处理异常。如果发生异常,返回指定的默认值。
*
* @param supplier 要执行的任务
* @param defaultValue 默认返回值
* @param exceptionHandler 异常处理器
* @param <T> 返回值的类型
* @return 任务的返回值,如果发生异常则返回默认值
*/
public static <T> T supplyWithoutException(Supplier<T> supplier, T defaultValue, Consumer<Exception> exceptionHandler) {
try {
return supplier.get();
} catch (Exception e) {
handleException(e, exceptionHandler);
}
return defaultValue;
}
/**
* 异步执行一个无返回值的任务,并忽略任何异常。
*
* @param callable 要执行的任务
*/
public static void executeAsyncWithoutException(VoidCallable callable) {
executeAsync(callable, IGNORE_EXCEPTION_HANDLER);
}
/**
* 异步执行一个无返回值的任务,并使用指定的异常处理器处理异常。
*
* @param callable 要执行的任务
* @param exceptionHandler 异常处理器
*/
public static void executeAsync(VoidCallable callable, Consumer<Exception> exceptionHandler) {
CompletableFuture.runAsync(() -> {
try {
callable.call();
} catch (Exception e) {
handleException(e, exceptionHandler);
}
});
}
/**
* 异步执行一个有返回值的任务,并忽略任何异常。如果发生异常,返回 null。
*
* @param supplier 要执行的任务
* @param <T> 返回值的类型
* @return 一个 CompletableFuture,表示任务的返回值,如果发生异常则返回 null
*/
public static <T> CompletableFuture<T> supplyAsyncWithoutException(Supplier<T> supplier) {
return supplyAsyncWithoutException(supplier, null, IGNORE_EXCEPTION_HANDLER);
}
/**
* 异步执行一个有返回值的任务,并忽略任何异常。如果发生异常,返回指定的默认值。
*
* @param supplier 要执行的任务
* @param defaultValue 默认返回值
* @param <T> 返回值的类型
* @return 一个 CompletableFuture,表示任务的返回值,如果发生异常则返回默认值
*/
public static <T> CompletableFuture<T> supplyAsyncWithoutException(Supplier<T> supplier, T defaultValue) {
return supplyAsyncWithoutException(supplier, defaultValue, IGNORE_EXCEPTION_HANDLER);
}
/**
* 异步执行一个有返回值的任务,并使用指定的异常处理器处理异常。如果发生异常,返回指定的默认值。
*
* @param supplier 要执行的任务
* @param defaultValue 默认返回值
* @param exceptionHandler 异常处理器
* @param <T> 返回值的类型
* @return 一个 CompletableFuture,表示任务的返回值,如果发生异常则返回默认值
*/
public static <T> CompletableFuture<T> supplyAsyncWithoutException(Supplier<T> supplier, T defaultValue, Consumer<Exception> exceptionHandler) {
return CompletableFuture.supplyAsync(() -> {
try {
return supplier.get();
} catch (Exception e) {
handleException(e, exceptionHandler);
return defaultValue;
}
});
}
// 新增方法:处理带多个参数和返回值的任务
/**
* 执行一个带多个参数和返回值的任务,并忽略任何异常。
*
* @param callable 要执行的任务
* @param params 参数
* @param <R> 返回值的类型
* @param <P> 参数的类型
* @return 任务的返回值,如果发生异常则返回 null
*/
public static <R, P> R callWithoutException(CallableWithParams<R, P> callable, P... params) {
return callWithoutException(callable, null, IGNORE_EXCEPTION_HANDLER, params);
}
/**
* 执行一个带多个参数和返回值的任务,并使用指定的异常处理器处理异常。
*
* @param callable 要执行的任务
* @param defaultValue 默认返回值
* @param exceptionHandler 异常处理器
* @param params 参数
* @param <R> 返回值的类型
* @param <P> 参数的类型
* @return 任务的返回值,如果发生异常则返回默认值
*/
public static <R, P> R callWithoutException(CallableWithParams<R, P> callable, R defaultValue, Consumer<Exception> exceptionHandler, P... params) {
try {
return callable.call(params);
} catch (Exception e) {
handleException(e, exceptionHandler);
return defaultValue;
}
}
/**
* 异步执行一个带多个参数和返回值的任务,并忽略任何异常。
*
* @param callable 要执行的任务
* @param params 参数
* @param <R> 返回值的类型
* @param <P> 参数的类型
* @return 一个 CompletableFuture,表示任务的返回值,如果发生异常则返回 null
*/
public static <R, P> CompletableFuture<R> callAsyncWithoutException(CallableWithParams<R, P> callable, P... params) {
return callAsyncWithoutException(callable, null, IGNORE_EXCEPTION_HANDLER, params);
}
/**
* 异步执行一个带多个参数和返回值的任务,并使用指定的异常处理器处理异常。
*
* @param callable 要执行的任务
* @param defaultValue 默认返回值
* @param exceptionHandler 异常处理器
* @param params 参数
* @param <R> 返回值的类型
* @param <P> 参数的类型
* @return 一个 CompletableFuture,表示任务的返回值,如果发生异常则返回默认值
*/
public static <R, P> CompletableFuture<R> callAsyncWithoutException(CallableWithParams<R, P> callable, R defaultValue, Consumer<Exception> exceptionHandler, P... params) {
return CompletableFuture.supplyAsync(() -> {
try {
return callable.call(params);
} catch (Exception e) {
handleException(e, exceptionHandler);
return defaultValue;
}
});
}
/**
* 处理异常的方法。如果提供了异常处理器,则调用它来处理异常。
*
* @param e 异常
* @param exceptionHandler 异常处理器
*/
private static void handleException(Exception e, Consumer<Exception> exceptionHandler) {
if (Objects.nonNull(exceptionHandler)) {
exceptionHandler.accept(e);
}
}
// 同步执行带多个不同类型参数的任务
public static <R, P1, P2, P3> R callWithoutException(CallableWithMultiParams<R, P1, P2, P3> callable, P1 param1, P2 param2, P3 param3) {
try {
return callable.call(param1, param2, param3);
} catch (Exception e) {
return null;
}
}
public static <R, P1, P2, P3> R callWithoutException(CallableWithMultiParams<R, P1, P2, P3> callable, R defaultValue, Consumer<Exception> exceptionHandler, P1 param1, P2 param2, P3 param3) {
try {
return callable.call(param1, param2, param3);
} catch (Exception e) {
handleException(e, exceptionHandler);
return defaultValue;
}
}
// 异步执行带多个不同类型参数的任务
public static <R, P1, P2, P3> CompletableFuture<R> callAsyncWithoutException(CallableWithMultiParams<R, P1, P2, P3> callable, P1 param1, P2 param2, P3 param3) {
return CompletableFuture.supplyAsync(() -> {
try {
return callable.call(param1, param2, param3);
} catch (Exception e) {
return null;
}
});
}
public static <R, P1, P2, P3> CompletableFuture<R> callAsyncWithoutException(CallableWithMultiParams<R, P1, P2, P3> callable, R defaultValue, Consumer<Exception> exceptionHandler, P1 param1, P2 param2, P3 param3) {
return CompletableFuture.supplyAsync(() -> {
try {
return callable.call(param1, param2, param3);
} catch (Exception e) {
handleException(e, exceptionHandler);
return defaultValue;
}
});
}
}
其中以下几个方法针对 CallableWithMultiParams进行调实现。
// 同步执行带多个不同类型参数的任务
public static <R, P1, P2, P3> R callWithoutException(CallableWithMultiParams<R, P1, P2, P3> callable, P1 param1, P2 param2, P3 param3) {
try {
return callable.call(param1, param2, param3);
} catch (Exception e) {
return null;
}
}
public static <R, P1, P2, P3> R callWithoutException(CallableWithMultiParams<R, P1, P2, P3> callable, R defaultValue, Consumer<Exception> exceptionHandler, P1 param1, P2 param2, P3 param3) {
try {
return callable.call(param1, param2, param3);
} catch (Exception e) {
handleException(e, exceptionHandler);
return defaultValue;
}
}
// 异步执行带多个不同类型参数的任务
public static <R, P1, P2, P3> CompletableFuture<R> callAsyncWithoutException(CallableWithMultiParams<R, P1, P2, P3> callable, P1 param1, P2 param2, P3 param3) {
return CompletableFuture.supplyAsync(() -> {
try {
return callable.call(param1, param2, param3);
} catch (Exception e) {
return null;
}
});
}
public static <R, P1, P2, P3> CompletableFuture<R> callAsyncWithoutException(CallableWithMultiParams<R, P1, P2, P3> callable, R defaultValue, Consumer<Exception> exceptionHandler, P1 param1, P2 param2, P3 param3) {
return CompletableFuture.supplyAsync(() -> {
try {
return callable.call(param1, param2, param3);
} catch (Exception e) {
handleException(e, exceptionHandler);
return defaultValue;
}
});
}
3.3使用示例
如何使用 SafeExecutor
和 CallableWithMultiParams
的示例。
// 同步执行任务
String result1 = SafeExecutor.callWithoutException(concatTask, "Number: ", 42, true);
System.out.println(result1); // 输出: Number: 42
// 同步执行任务,带默认值和异常处理器
String result2 = SafeExecutor.callWithoutException(concatTask, "Default Value", e -> System.err.println("Error: " + e.getMessage()), "Number: ", 42, false);
System.out.println(result2); // 输出: Default Value
// 异步执行任务
CompletableFuture<String> future1 = SafeExecutor.callAsyncWithoutException(concatTask, "Number: ", 42, true);
future1.thenAccept(resu -> System.out.println(result)); // 输出: Number: 42
// 异步执行任务,带默认值和异常处理器
CompletableFuture<String> future2 = SafeExecutor.callAsyncWithoutException(concatTask, "Default Value", e -> System.err.println("Error: " + e.getMessage()), "Number: ", 42, false);
future2.thenAccept(resu -> System.out.println(result)); // 输出: Default Value
通过这种设计,CallableWithMultiParams
接口可以支持不同类型的参数,SafeExecutor
工具类提供了对这些任务的同步和异步执行方法,并在发生异常时进行处理。
4. 结论
介绍了 CallableWithMultiParams
接口和 SafeExecutor
工具类的设计与实现。通过这些工具,可以提高代码的可读性、可维护性和灵活性。CallableWithMultiParams
支持带有不同类型参数的任务执行,而 SafeExecutor
提供了一组方法来安全地执行这些任务,并在发生异常时进行处理。这不仅简化了异常处理逻辑,还提供了对同步和异步任务的支持。