动态代理

java写框架、改底层等,"动态代理"必不可少

本人不怎么爱写博客,原因在于觉得浪费时间。 —
但是今天朋友内推我面试。这才意识到自己没有底子给别人看是莫大的后悔啊
不多说了,以后我发现什么新奇的东西、探索类的知识,跟大家分享出来

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.util.ClassUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 代理对象忽略某些方法
 *
 * @author 草先生
 */
@Slf4j
public class MethodProxy<T> implements MethodInterceptor {


    private T target;
    private CallBack<T> callBack;

    public MethodProxy(T proxyTarget) {
        this.target = proxyTarget;
    }

    public T getProxyIgnoreSetMethodNames(String... ignoreMethodNames) {
        this.callBack = (t, method, args) -> {
            for (String ignoreMethodName : ignoreMethodNames) {
                if (Objects.equals(ignoreMethodName.intern(), method.getName().intern())) {
                    return null;
                }
            }
            return method.invoke(target, args);
        };

        return getT();
    }

    public T getProxyIgnoreSetMethod() {
        // 忽略所有的set方法
        PropertyDescriptor[] descriptors = BeanUtilsBean.getInstance().getPropertyUtils().getPropertyDescriptors(target);
        List<String> ignoreMethodNames = Stream.of(descriptors)
                .map(PropertyDescriptor::getWriteMethod)
                .filter(Objects::nonNull)
                .map(Method::getName)
                .map(String::intern)
                .collect(Collectors.toList());

        this.callBack = (t, method, args) -> {
            if (ignoreMethodNames.contains(method.getName().intern())) {
                return null;
            }
            return method.invoke(target, args);
        };
        return getT();

    }

    public T getProxy(CallBack<T> callBack) {
        this.callBack = callBack;
        return getT();
    }

    private T getT() {
        // 创建代理对象
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.target.getClass());
        enhancer.setCallback(this);

        // 如果针对class创建失败,则只针对接口创建代理
        try {
            //noinspection unchecked
            return (T) enhancer.create();
        } catch (Exception e) {
            enhancer = new Enhancer();
            Class<?>[] allInterfacesForClass = ClassUtils.getAllInterfaces(this.target);
            enhancer.setInterfaces(allInterfacesForClass);
            enhancer.setCallback(this);
            //noinspection unchecked
            return (T) enhancer.create();
        }
    }


    @Override
    public Object intercept(Object obj, Method method, Object[] args, org.springframework.cglib.proxy.MethodProxy proxy) throws Exception {
        return callBack.call(target, method, args);
    }


    public interface CallBack<T> {
        /**
         * 代理拦截的方法,需要用户自己实现
         */
        Object call(T target, Method method, Object[] args) throws Exception;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值