【总结】静态代理与两种动态代理及其代码实现

文章介绍了JDK和CGLIB两种动态代理的实现方式。JDK动态代理基于接口,要求委托类实现接口,通过InvocationHandler的invoke方法进行增强。CGLIB动态代理则通过继承委托类来实现,适用于没有接口的情况,使用MethodInterceptor的intercept方法进行增强。文章通过代码示例展示了两种代理模式的使用和运行结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 总结

  • JDK动态代理

    • 要求委托类必须实现接口,根据接口动态生成代理对象的字节码文件;

    • 关键类及方法:InvocationHandler(invoke)、Proxy(newProxyInstance)

    • 生成的代理类会实现委托类所实现的接口并且在实现接口中的相应方法;

    • 这些相应方法会使用super.h.invoke()方法,去调用invoketionHandler的实现类中重写的invoke()方法;

  • CGLIB动态代理

    • 要求委托类能够被继承(委托类不能被final修饰)

    • 关键类及方法:MethoInterceoptor(intercept()(invokeSuper) )、Enhancer(setSuprClass()、setCallBack()、create())

    • 生成的代理类会去继承委托类,并重写委托类的方法, 即以继承的方式去获取委托类的方法;

    • 代理类调用某方法时,该方法内会调用MethodInterceptor的实现类重写的intercept()方法;

2 代码实现

2.1 接口与其实现类代码

// 接口
public interface MyInterface {
    void myMethod1(String sentence);
    void myMethod2(String sentence);
}

// 接口实现类
public class MyInterfaceImpl implements MyInterface{

    @Override
    public void myMethod1(String sentence) {
        System.out.println("方法一运行,打印sentence:  " + sentence);
    }

    @Override
    public void myMethod2(String sentence) {
        System.out.println("方法二运行,打印sentence:  " + sentence);
    }
}

2.2 静态代理代码实现

public class MyStaticProxy implements MyInterface{
    MyInterface myInterface;
    public MyStaticProxy(MyInterface myInterface){
        this.myInterface = myInterface;
    }

    @Override
    public void myMethod1(String sentence) {
        System.out.println("myMethod1的Before增强方法运行");
        myInterface.myMethod1(sentence);
        System.out.println("myMethod1的After增强方法运行");
    }

    @Override
    public void myMethod2(String sentence) {
        System.out.println("myMethod2的Before增强方法运行");
        myInterface.myMethod2(sentence);
        System.out.println("myMethod2的After增强方法运行");
    }
}

2.3 JDK动态代理实现InvocationHandler接口

public class MyInvokeHandlerImpl<T> implements InvocationHandler {
    T t;
    public MyInvokeHandlerImpl(T t){
        this.t = t;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (method.getName().equals("myMethod1")){
            System.out.println("myMethod1的Before增强方法运行");
            method.invoke(t, args);
            System.out.println("myMethod1的After增强方法运行");
        }else if (method.getName().equals("myMethod2")){
            System.out.println("myMethod2的Before增强方法运行");
            method.invoke(t, args);
            System.out.println("myMethod2的After增强方法运行");
        }
        return "JDK代理运行完成";
    }
}


2.4 CGLIB动态代理实现MethodInterceptor接口

public class MyMethodInterceptorImpl implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        if (method.getName().equals("myMethod1")){
            System.out.println("myMethod1的Before增强方法运行");
            methodProxy.invokeSuper(o, objects);
            System.out.println("myMethod1的After增强方法运行");
        }else if (method.getName().equals("myMethod2")){
            System.out.println("myMethod2的Before增强方法运行");
            methodProxy.invokeSuper(o, objects);
            System.out.println("myMethod2的After增强方法运行");
        }
        return "CGLIB代理运行完成";
    }
}

2.5 运行结果

1 main方法

public class test {
    public static void main(String[] args) {
        MyInterface myInterfaceImpl  = new MyInterfaceImpl();

        System.out.println("*******************静态代理*******************");
        MyStaticProxy myStaticProxy = new MyStaticProxy(myInterfaceImpl);
        myStaticProxy.myMethod1("静态代理");
        myStaticProxy.myMethod2("静态代理");

        System.out.println("*******************JDK动态代理*******************");
        MyInvokeHandlerImpl<MyInterface> myInvokeHandlerImpl = new MyInvokeHandlerImpl<MyInterface>(myInterfaceImpl);
        MyInterface o = (MyInterface)Proxy.newProxyInstance(MyInterface.class.getClassLoader(), new Class[]{MyInterface.class}, myInvokeHandlerImpl);
        o.myMethod1("JDK动态代理");
        o.myMethod2("JDK动态代理");

        System.out.println("*******************CGLIB动态代理*******************");
        MyMethodInterceptorImpl myMethodInterceptor = new MyMethodInterceptorImpl();
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(MyInterfaceImpl.class);
        enhancer.setCallback(myMethodInterceptor);
        MyInterfaceImpl o1 = (MyInterfaceImpl) enhancer.create();
        o1.myMethod1("CGLib动态代理");
        o1.myMethod2("CGLib动态代理");
    }

}

2 运行结果

************静态代理 ************
myMethod1的Before增强方法运行
方法一运行,打印sentence: 静态代理
myMethod1的After增强方法运行
myMethod2的Before增强方法运行
方法二运行,打印sentence: 静态代理
myMethod2的After增强方法运行
*********JDK动态代理 *********
myMethod1的Before增强方法运行
方法一运行,打印sentence: JDK动态代理
myMethod1的After增强方法运行
myMethod2的Before增强方法运行
方法二运行,打印sentence: JDK动态代理
myMethod2的After增强方法运行
************CGLIB动态代理 ************
myMethod1的Before增强方法运行
方法一运行,打印sentence: CGLib动态代理
myMethod1的After增强方法运行
myMethod2的Before增强方法运行
方法二运行,打印sentence: CGLib动态代理
myMethod2的After增强方法运行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值