Spring AOP的实现原理--CGLIB动态代理

2020-07-17  本文已影响0人  码而优则仕

Spring AOP的实现原理--CGLIB动态代理

CGLIB(Code Generation Library)

JDK 动态代理需要代理类实现接口--生成动态代理类的时候需要传入被代理类实现的接口。

CGLIB核心类或接口讲解:

Callback回调接口

package net.sf.cglib.proxy;

public interface Callback {
}

MethodInterceptor接口继承自Callback 接口具有回调功能,相当于 JDK动态代理里面的 InvocationHandler

package net.sf.cglib.proxy;

import java.lang.reflect.Method;
//用于拦截方法调用
public interface MethodInterceptor extends Callback {
//该拦截方法前三个参数和 JDK动态代理的 InvocationHandler接口中的invoke(Object proxy, Method method, //Object[] args) 相同
//   /** @param proxy  Object proxy:真实的代理对象(不是被代理对象)。
     * @param method Method method:表示的是目标对象(被代理对象)的方法的实例
     * @param args   Object[] args:方法里面需要用到的参数 
     MethodProxy CGLIB生成代替Method的动态代理Method对象**/
    Object intercept(Object var1, Method var2, Object[] var3, MethodProxy var4) throws Throwable;
}

核心类:Enhancer

package net.sf.cglib.proxy;
public class Enhancer extends AbstractClassGenerator {

//通过公共的或者静态的 create 方法就能创建出对应的动态代理实例来
  public static Object create(Class type, Callback callback) {
        Enhancer e = new Enhancer();
        e.setSuperclass(type);
        e.setCallback(callback);
        return e.create();
    }

    public static Object create(Class superclass, Class[] interfaces, Callback callback) {
        Enhancer e = new Enhancer();
        e.setSuperclass(superclass);
        e.setInterfaces(interfaces);
        e.setCallback(callback);
        return e.create();
    }

CGLIB使用:

Aspect

public class AlipayMethodInterceptor implements MethodInterceptor {

    /**
     *
     * @param o 真实的代理对象(非被代理对象)
     * @param method 表示的是目标对象(被代理对象)的方法的实例
     * @param args 方法里面需要用到的参数
     * @param methodProxy CGLIB生成代替Method的动态代理Method对象
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        beforePay();
        //执行被代理类的方法逻辑
        Object result = methodProxy.invokeSuper(o,args);
        afterPay();
        return result;
    }

    private void afterPay() {
        System.out.println("支付给商家");
    }

    private void beforePay() {
        System.out.println("从招商银行取款");
    }
}
public class CglibUtil {

    public static <T> T createProxy(T targetObject, MethodInterceptor methodInterceptor) {
        return (T) Enhancer.create(targetObject.getClass(), methodInterceptor);
    }
}
 CommonPayment commonPayment = new CommonPayment();
JdkDynamicProxyUtil.newProxyInstance(commonPayment, handler);
        AlipayMethodInterceptor alipayMethodInterceptor = new AlipayMethodInterceptor();
        CommonPayment commonPaymentProxyWithCglib = CglibUtil.createProxy(commonPayment, alipayMethodInterceptor);
        commonPaymentProxyWithCglib.pay();

输出:

从招商银行取款
个人名义或者公司名义都可以走这个支付通道
支付给商家

JDK动态代理和CGLIB

实现机制:

JDK动态代理的优势:

CGLIB的优势:

被代理对象无需实现接口,能实现代理类的无侵入。

Spring AOP 的底层机制:

CGLIB和JDK动态代理共存

默认策略,如果目标Bean实现了接口则使用JDK,否则使用CGLIB

上一篇 下一篇

猜你喜欢

热点阅读