shz.spring.CglibProxy Maven / Gradle / Ivy
The newest version!
package shz.spring;
import org.springframework.cglib.core.DebuggingClassWriter;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import shz.core.*;
import shz.core.msg.ServerFailureMsg;
import java.lang.reflect.Method;
import java.util.function.Function;
@SuppressWarnings("unchecked")
public final class CglibProxy implements MethodInterceptor {
public static final class Param {
public final Object proxy;
public final Object bean;
public final Method method;
public final Object[] args;
public final MethodProxy methodProxy;
Param(Object proxy, Object bean, Method method, Object[] args, MethodProxy methodProxy) {
this.proxy = proxy;
this.bean = bean;
this.method = method;
this.args = args;
this.methodProxy = methodProxy;
}
}
private final T bean;
private final Function executor;
private CglibProxy(T bean, Function executor) {
this.bean = bean;
this.executor = executor;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) {
Class> dCls = method.getDeclaringClass();
if (dCls == Object.class) {
switch (method.getName()) {
case "hashCode":
return System.identityHashCode(proxy);
case "equals":
return proxy == args[0];
default:
try {
return AccessibleHelp.accessible(method).invoke(bean, args);
} catch (Exception e) {
throw PRException.of(e);
}
}
}
Object invoke = executor.apply(new Param(proxy, bean, method, args, methodProxy));
Class> rt = method.getReturnType();
if (rt == void.class || rt == Void.class) return null;
if (invoke == null) {
if (rt.isPrimitive()) throw notMatch(dCls.getTypeName(), method.getName());
return null;
}
if (!AccessibleHelp.canCast(invoke.getClass(), rt)) {
Object cast = FieldSetter.cast(invoke, TypeHelp.toClass(method.getGenericReturnType()));
if (cast == null) throw notMatch(dCls.getTypeName(), method.getName());
return cast;
}
return invoke;
}
private PRException notMatch(String typeName, String methodName) {
return PRException.of(ServerFailureMsg.fail("类:%s,方法:%s返回值与代理类不匹配", typeName, methodName));
}
public static T getProxy(T bean, Function executor, String path) {
if (NullHelp.nonBlank(path)) System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, path);
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(bean.getClass());
enhancer.setUseCache(false);
enhancer.setCallback(new CglibProxy<>(bean, executor));
return (T) enhancer.create();
}
public static T getProxy(T bean, Function executor) {
return getProxy(bean, executor, null);
}
}