场景
在有些场景中jdk(8)自带的函数可能不满足要求,需要自己定义函数。
例如,我们在与第三方通讯的时候,需要做一些前置与后置操作
public R send (T t) {
before(t); // 前置操作
Exception ex = null;
R r = null;
try {
r = sendNative(t);
return r;
} catch (Exception e) {
ex = e;
throw e;
} finally {
after(t, r, ex); // 后置操作
}
}
这些操作可能有:
1、添加全局流水号。如果使用线程变量的话,进入时set, finally时remove
2、记录日志。进入时记录初始时间,finally时记录返回码与耗时
我们可能就需要一系列的before消费者来消费入参t, 一系列对应的after消费者来消费t,r,ex
消费t比较好定义,如
private static final List<Consumer<Object>> BEFORE_CONSUMER_LIST = new ArrayList<>();
public static void addBeforeConsumer(Consumer<Object> consumer) {
BEFORE_CONSUMER_LIST.add(consumer);
}
我们就可以在需要的地方插入一个前置处理
ICommService.addBeforeConsumer(str -> System.out.println("开始记日志,入参为" + str));
现在就遇到一个问题afterConsumer如何定义,因为jdk里定义的最大参数只2个,即BiConsumer,于是这里需要我们定义一个参数更多的Consumer -- MyBiConsumer
MyBiConsumer
完全参考BiConsumer的写法,添加一个参数即可
@FunctionalInterface
public interface MyBiConsumer<T, U, V> {
void accept(T t, U u, V v);
default MyBiConsumer<T, U, V> andThen(MyBiConsumer<? super T, ? super U, ? super V> after) {
Objects.requireNonNull(after);
return (l, r, v) -> {
accept(l, r, v);
after.accept(l, r, v);
};
}
}
定义监听器列表与加入监听器
private static final List<MyBiConsumer<Object, Object, Exception>> AFTER_CONSUMER_LIST = new ArrayList<>();
public static void addAfterConsumer(MyBiConsumer<Object, Object, Exception> consumer) {
AFTER_CONSUMER_LIST.add(consumer);
}
// 在需要的地方添加后置处理消费者
ICommService.addAfterConsumer((str, retStr, e) -> System.out.println(
"入参为:" + str
+ "返回码为:" + retStr
+ ("错误为:" + (e != null ? e.getMessage() : ""))));
after与before方法中,把参数传给消费者即可
private void after(T t, R r, Exception ex) {
for (MyBiConsumer<Object, Object, Exception> con : AFTER_CONSUMER_LIST) {
try {
con.accept(t, r, ex);
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void before(T t) {
for (Consumer<Object> con : BEFORE_CONSUMER_LIST) {
try {
con.accept(t);
} catch (Exception e) {
e.printStackTrace();
}
}
}