net.gdface.utils.InterfaceNonimplDecorator Maven / Gradle / Ivy
package net.gdface.utils;
import static net.gdface.utils.ConditionChecks.checkNotNull;
import java.lang.reflect.Method;
import java.util.Hashtable;
import java.util.Map;
/**
* 实现在实例上代理调用接口
* @author guyadong
*
* @param 接口类型
*/
public class InterfaceNonimplDecorator extends BaseInterfaceDecorator{
protected final Map invokeMethods = new Hashtable<>();
private final boolean lenient;
/**
* 构造方法
*
* @param interfaceClass 接口类
* @param delegate 实现接口方法的实例
* @param lenient 是否为宽容模式---允许接口方法返回类型为void,但对应的代理方法返回类型不为void
*/
public InterfaceNonimplDecorator(Class interfaceClass, Object delegate, boolean lenient) {
super(interfaceClass, checkNotNull(delegate,"delegate is null"));
this.lenient = lenient;
try {
compile(interfaceClass,delegate);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
/**
* 构造方法
*
* @param interfaceClass 接口类
* @param delegate 实现接口方法的实例
*/
public InterfaceNonimplDecorator(Class interfaceClass, Object delegate) {
this(interfaceClass, delegate, true);
}
private static boolean isVoid(Class>type){
return Void.class.equals(type) || void.class.equals(type);
}
/**
* 创建接口方法与代理对象调用对应的方法的映射,如果找不到抛出异常
* @param interfaceClass
* @param delegate
* @throws NoSuchMethodException
*/
protected void compile(Class interfaceClass, Object delegate) throws NoSuchMethodException{
Class extends Object> delegateClass = delegate.getClass();
for(Method im:interfaceClass.getMethods()){
// 接口方法参数
Class>[] parameterTypes = im.getParameterTypes();
// 接口方法返回类型
Class> imReturnType = im.getReturnType();
// 根据接口方法查找代理类对应的代理方法
Method dm = delegateClass.getMethod(im.getName(), parameterTypes);
if(!imReturnType.isAssignableFrom(dm.getReturnType())){
if(lenient && isVoid(imReturnType)){
// 允许接口方法返回类型为void,但对应的代理方法返回类型不为void
// DO NOTHING
}else {
throw new NoSuchMethodException(String.format("Mismatch return type with %s,%s",dm,im));
}
}
invokeMethods.put(im, delegateClass.getMethod(im.getName(), parameterTypes));
}
}
@Override
protected Object doInvoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = invokeMethods.get(method).invoke(delegate, args);
// 接口方法返回类型为void,但代理方法返回值不为null时,返回null
return (result != null && isVoid(method.getReturnType())) ? null : result;
}
}