jdk和cglib动态代理


代码: https://gitee.com/xuhx615/AOPDemo.git

🍓动态代理的作用

增强或拦截方法的调用

🍓切点方法

public interface Point {

    /**
     * 代理方法前调用
     * @param args 代理方法的参数
     * @return true放行;false拦截
     */
    boolean before(Object[] args);

    /**
     * 代理方法后调用
     * @param result 代理方法返回值
     * @param e 代理方法抛出的异常
     * @param args 代理方法的参数
     */
    void after(Object result, Exception e,Object[] args);
}

🍓jdk动态代理代理类(核心)

import cn.com.jdk.point.Point;
import org.springframework.util.CollectionUtils;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

public class ActiveProxy implements InvocationHandler {

    /**
     * 切点
     */
    private Point point;

    /**
     * 代理对象
     */
    private Object obj;

    /**
     * 需要增强的方法
     */
    private List<String> enhanceMethodList;

    /**
     * 是否全部增强
     */
    private boolean isAllEnhance = true;

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        Exception exception = null;
        /**
         * 判断
         * 是否全部增强
         * 如果不是全部增强,增强方法是否属于指定的方法
         */
        if (isAllEnhance || (!isAllEnhance && !CollectionUtils.isEmpty(enhanceMethodList)
                && enhanceMethodList.contains(method.getName()))) {
            boolean flag = point.before(args);
            if(flag){
                try {
                    result = method.invoke(obj, args);
                } catch (Exception e) {
                    e.printStackTrace();
                    exception = e;
                }
                point.after(result, exception, args);
            }
        }else{
            result = method.invoke(obj, args);
        }
        return result;
    }

	/**
     * 创建代理对象
     * @param clazz 代理对象的接口类clazz
     * @param obj 代理对象实例
     * @param point 切点实例
     * @param <T>
     * @return
     */
    public <T> T createObj(Class<T> clazz,T obj,Point point){
        this.obj = obj;
        this.point = point;
        T t = (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, this);
        return t;
    }

    public <T> T createObj(Class<T> clazz,T obj,Point point,boolean isAllEnhance,List<String> enhanceMethodList){
        this.isAllEnhance = isAllEnhance;
        this.enhanceMethodList = enhanceMethodList;
        return createObj(clazz,obj,point);
    }
}

🍓cglib动态代理代理类(核心)

import cn.com.cglib.point.Point;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.util.CollectionUtils;
import java.lang.reflect.Method;
import java.util.List;

public class ProxyMethodInterceptor implements MethodInterceptor {

    private Point point;

    private Object obj;

    private List<String> enhanceMethodList;

    private boolean isAllEnhance = true;

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        Object result = null;
        Exception exception = null;
        if (isAllEnhance || (!isAllEnhance && !CollectionUtils.isEmpty(enhanceMethodList) && enhanceMethodList.contains(method.getName()))) {
            boolean flag = point.before(objects);
            if(flag){
                try {
                    result = methodProxy.invoke(obj, objects);
                } catch (Exception e) {
                    exception = e;
                }
                point.after(result,exception, objects);
            }
        }else{
            result = methodProxy.invoke(obj, objects);
        }
        return result;
    }

    public <T> T createObj(T obj,Point point){
        this.point = point;
        this.obj = obj;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(obj.getClass());
        enhancer.setCallback(this);
        T t = (T) enhancer.create();
        return t;
    }

    public <T> T createObj(T obj,Point point,boolean isAllEnhance,List<String> enhanceMethodList){
        this.isAllEnhance = isAllEnhance;
        this.enhanceMethodList = enhanceMethodList;
        return createObj(obj,point);
    }
}

🍓jdk动态代理与cglib动态代理的区别

🍒表面区别
  1. jdk动态代理代理类实现的是java.lang.reflect.InvocationHandlercglib动态代理代理类实现的是org.springframework.cglib.proxy.MethodInterceptor
  2. jdk动态代理代理类使用的核心类是java.lang.reflect.Proxycglib动态代理使用的核心类是org.springframework.cglib.proxy.MethodProxy
  3. jdk动态代理代理对象必须有对应的接口和实现类,cglib动态代理代理对象则是针对类,不需要有对应的接口。
🍒理论区别
  1. JDK动态代理是实现了被代理对象的接口,Cglib是继承了被代理对象。
  2. JDKCglib都是在运行期生成字节码,JDK是直接写Class字节码,Cglib使用ASM框架写Class字节码,Cglib代理实现更复杂,生成代理类比JDK效率低。
  3. JDK调用代理方法,是通过反射机制调用,Cglib是通过FastClass机制直接调用方法,Cglib执行效率更高。

🍓Hutool动态代理

增强类:

import cn.hutool.aop.aspects.SimpleAspect;
import java.lang.reflect.Method;

public class TargetAspect extends SimpleAspect {

    @Override
    public boolean before(Object target, Method method, Object[] args) {
        System.out.println("before");
        return true;
    }

    @Override
    public boolean after(Object target, Method method, Object[] args, Object returnVal) {
        System.out.println("after");
        return super.after(target, method, args, returnVal);
    }

    @Override
    public boolean afterException(Object target, Method method, Object[] args, Throwable e) {
        System.out.println("afterException");
        return super.afterException(target, method, args, e);
    }
}

调用:

import cn.hutool.aop.ProxyUtil;

	TargetDemo proxy = ProxyUtil.proxy(new TargetDemoImpl(), new TargetAspect());
	proxy.eat("鱼");

注意: 如果项目中没有引入cglib依赖,那么ProxyUtil.proxy的返回值类型必须是代理类的接口类型,因为他走的是jdk动态代理

🍓Spring AOP

Spring AOP的底层实现是cglib动态代理。
Spring AOP请点击该博客浏览:https://blog.csdn.net/qq_34191426/article/details/125223508

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值