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

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);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy