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

net.gdface.utils.InterfaceContainer 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.LinkedHashSet;
import java.util.Set;

import static net.gdface.utils.SimpleTypes.getRawClassOfSuperPamamType;
import static net.gdface.utils.SimpleLog.log;

/**
 * 实现接口实例的级联容器 
* @param 接口类型 * @author guyadong * */ public class InterfaceContainer { private final Set listeners = new LinkedHashSet(); private final Class interfaceClass; private boolean skipOnError = true; private boolean logOnError = false; /** * 接口容器实例 */ public final I container; /** * */ @SuppressWarnings("unchecked") protected InterfaceContainer() { interfaceClass = (Class) getRawClassOfSuperPamamType(getClass())[0]; if(!interfaceClass.isInterface()){ throw new IllegalArgumentException("param I must be interface"); } // 创建侦听器窗口接口实例 container = proxyInstance(); } public InterfaceContainer(Class interfaceClass) { Assert.notNull(interfaceClass, "interfaceClass"); if(!interfaceClass.isInterface()){ throw new IllegalArgumentException("param I must be interface"); } this.interfaceClass = interfaceClass; // 创建侦听器窗口接口实例 container = proxyInstance(); } /** * 根据当前对象创建新的接口实例{@link Proxy} * @return */ private final I proxyInstance(){ return interfaceClass.cast(Proxy.newProxyInstance( interfaceClass.getClassLoader(), new Class[]{ interfaceClass}, new Handler())); } /** * 将接口实例加入容器 * @param listener */ public void register(I listener){ if(listener != null){ synchronized (this) { listeners.add(listener); } } } /** * 从容器中删除指定的接口实例 * @param listener */ public void unregister(I listener){ if(listener != null){ synchronized (this) { listeners.remove(listener); } } } /** * 设置当执行容器中的接口实例有异常抛出时的动作
* 为{@code true}时跳过继续执行下一个容器
* 为{@code false}时抛出异常 * @param skipOnError 当调用抛出异常时是否忽略 * @return 当前实例 */ public InterfaceContainer setSkipOnError(boolean skipOnError) { this.skipOnError = skipOnError; return this; } /** * 设置当执行容器中的接口实例有异常抛出时是否日志输出(仅当skipOnError为true时有效) * @param logOnError 当调用抛出异常时是否输出日志 * @return 当前实例 */ public InterfaceContainer setLogOnError(boolean logOnError) { this.logOnError = logOnError; return this; } private class Handler implements InvocationHandler{ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { for(I listener:listeners){ try { method.invoke(listener, args); } catch (InvocationTargetException e) { Throwable te = e.getTargetException(); if(skipOnError){ if(logOnError){ //拦截所有异常,保证不影响其他的Listener运行 log("ERROR:"+te.getMessage(), te); } continue; } throw te; }catch (Throwable e) { throw e; } } return null; } } }