All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.gdface.utils.BaseInterfaceDecorator Maven / Gradle / Ivy

There is a newer version: 3.2.1
Show newest version
package net.gdface.utils;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.LinkedHashSet;

import static net.gdface.utils.SimpleLog.*;
import static net.gdface.utils.ConditionChecks.checkNotNull;
/**
 * 实现接口实例的代理类 
* 应用层可以根据需要继承此类重写{@link #invoke(Object, Method, Object[])}方法, * 也可以通过注册侦听器{@link InterfaceDecoratorProbe}在方法调用时实现应用逻辑 * @author guyadong * * @param 接口类型 * @param 接口实现类型 */ public abstract class BaseInterfaceDecorator implements InvocationHandler,Delegator,InterfaceDecoratorProbe{ protected final Class interfaceClass; protected final T delegate; /** 注册的侦听器列表 */ private LinkedHashSet listeners = new LinkedHashSet<>(); /** 是否允许 {@link #beforeInvoke(Object, Method, Object[])}中断调用抛出异常 */ private final boolean allowBreak; private static boolean debug = false; public static void setDebug(boolean debug) { BaseInterfaceDecorator.debug = debug; } /** * 构造方法 * * @param interfaceClass 接口类 * @param delegate 实现接口的类,如果子类用不delegate字段可以为{@code null} */ protected BaseInterfaceDecorator(Class interfaceClass, T delegate) { this(interfaceClass,delegate,false); } /** * 构造方法 * * @param interfaceClass 接口类 * @param delegate 实现接口的类,如果子类用不delegate字段可以为{@code null} * @param allowBreak 为{@code true}时允许 {@link #beforeInvoke(Object, Method, Object[])}抛出异常 */ protected BaseInterfaceDecorator(Class interfaceClass, T delegate, boolean allowBreak) { this.interfaceClass = checkNotNull(interfaceClass, "interfaceClass is null"); this.delegate = delegate; this.allowBreak = allowBreak; } /** * 简化版构造函数
* 当delegate只实现了一个接口时,自动推断接口类型 * @param delegate */ @SuppressWarnings("unchecked") protected BaseInterfaceDecorator(T delegate) { this((Class) getOnlyInterface(delegate), delegate); } private static Class getOnlyInterface(Object delegate){ if(checkNotNull(delegate,"delegate is null").getClass().getInterfaces().length !=1){ throw new IllegalArgumentException( String.format("can't determines interface class from %s", delegate.getClass().getName())); } return delegate.getClass().getInterfaces()[0]; } protected abstract Object doInvoke(Object proxy, Method method, Object[] args) throws Throwable; /** * 执行接口方法调用,在调用前,调用成功后,调用发生异常,调用结束时执行所有注册的侦听器({@link InterfaceDecoratorProbe}) */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { beforeInvoke(proxy, method, args); Object result = doInvoke(proxy,method,args); onComplete(proxy, method, args, result); return result; } catch (InvocationTargetException e) { Throwable te = e.getTargetException(); onError(proxy, method, args, te); throw te; }catch (Throwable e) { onError(proxy, method, args, e); throw e; } finally { onDone(proxy, method, args); } } /** * 返回代理的接口类 * @return 接口类 */ public final Class getInterfaceClass() { return interfaceClass; } /** * 根据当前对象创建新的接口实例 * @return 接口实例 * @see Proxy#newProxyInstance(ClassLoader, Class[], InvocationHandler) */ public final I proxyInstance(){ return interfaceClass.cast(Proxy.newProxyInstance( interfaceClass.getClassLoader(), new Class[]{ interfaceClass}, this)); } @Override public T delegate() { return delegate; } /** * 注册侦听器
* 重复注册返回{@code false} * @param listener 要注册的侦听器 * @return 注册成功返回{@code true},否则返回{@code false} */ public boolean registerListener(InterfaceDecoratorProbe listener){ return registerListener(listener,false); } /** * 注册侦听器
* 重复注册返回{@code false} * @param listener 要注册的侦听器 * @param header 为{@code true}添加到队列头部,否则顺序添加到尾部 * @return 注册成功返回{@code true},否则返回{@code false} */ public boolean registerListener(InterfaceDecoratorProbe listener, boolean header){ if(null == listener) { return false; } synchronized (listeners) { if(!header) { return listeners.add(listener); } if(!listeners.contains(listener)) { /** * 先备份listeners,然后清空之,再将输入listener添加为第一个元素,再将添加备份的内容, * 确保listener为第一个被添加的元素 */ ArrayList copy = new ArrayList<>(listeners); listeners.clear(); listeners.add(listener); listeners.addAll(copy); return true; } return false; } } /** * 卸载指定的侦听器 * @param listener * @return 卸载成功返回{@code true},否则返回{@code false} */ public boolean unregisterListener(InterfaceDecoratorProbe listener){ return listener == null ? false : listeners.remove(listener); } /** * 顺序调用{@link #listeners}中的所有侦听器对象的 * {@link InterfaceDecoratorProbe#beforeInvoke(Object, Method, Object[])}方法, * {@link #allowBreak}为{@code true}时,允许侦听器抛出异常,中断调用,否则输出错误日志 */ @Override public void beforeInvoke(Object proxy, Method method, Object[] args) throws Exception { for(InterfaceDecoratorProbe listener:listeners){ try { listener.beforeInvoke(proxy, method, args); } catch (Exception e) { if(allowBreak) { throw e; } log(e.getMessage()); if(debug){ log(e.getMessage(),e); } } } } /** * 顺序调用{@link #listeners}中的所有侦听器对象的 * {@link InterfaceDecoratorProbe#onComplete(Object, Method, Object[], Object)}方法 */ @Override public void onComplete(Object proxy, Method method, Object[] args, Object result) { for(InterfaceDecoratorProbe listener:listeners){ try { listener.onComplete(proxy, method, args, result); } catch (Exception e) { log(e.getMessage()); if(debug){ log(e.getMessage(),e); } } } } /** * 顺序调用{@link #listeners}中的所有侦听器对象的 * {@link InterfaceDecoratorProbe#onError(Object, Method, Object[], Throwable)}方法 */ @Override public void onError(Object proxy, Method method, Object[] args, Throwable error) { for(InterfaceDecoratorProbe listener:listeners){ try { listener.onError(proxy, method, args, error); } catch (Exception e) { log(e.getMessage()); if(debug){ log(e.getMessage(),e); } } } } /** * 顺序调用{@link #listeners}中的所有侦听器对象的 * {@link InterfaceDecoratorProbe#onDone(Object, Method, Object[])}方法 */ @Override public void onDone(Object proxy, Method method, Object[] args) { for(InterfaceDecoratorProbe listener:listeners){ try { listener.onDone(proxy, method, args); } catch (Exception e) { log(e.getMessage()); if(debug){ log(e.getMessage(),e); } } } } }