java的三种代理模式(静态,jdk动态,CGLIB动态)

  今天看书看到jdk和CGLIB动态代理模式,回想了下上学期学的代理模式,感觉大有不同,困惑下找了找资料才了解到java的这三种代理模式,一篇很好的博客博客链接,自己也敲了敲算是明白了。

一、静态代理模式

    这个就是学23种设计模式接触的那种了,特点是 代理者和被代理者实现同一个接口的情况下,代理者类之中同时拥有一个被代理者对象,这样子的话被代理者类中实现具体操作,代理者中实现代理逻辑,也就是通过这个对象实现被代理者应做的事情。

代码如下:

接口

package ssm.proxy;
public interface Hello {
    public void sayHello(String str);
}

接口实现类(被代理者):

package ssm.proxy;
public class HelloImpl implements Hello {
    
    @Override
    public void sayHello(String str) {
        System.out.println("hello " + str);
    }
}

代理者:

package ssm.proxy;

public class ProxyExample implements Hello {
    /**
     * 普通代理模式,代理者和被代理者同时继承接口
     * 同时, 代理者类 拥有 被代理者的 对象
     * 代理操作
     */
    private  Hello target = null;
    //1. 建立代理对象和真实对象的关系
    public ProxyExample(Hello target) {
        this.target = target;
    }
    /**
     * 2. 实现代理逻辑
     */
    @Override
    public void sayHello(String str) {
        System.out.println("before1 代理逻辑");
        target.sayHello(str);
        System.out.println("after1 代理逻辑");
    }
}

测试类(main):

package ssm.proxy;

public class TestMain {

    public static void main(String[] args){
        test1();
        //test2();
        //test3();
    }

    public static void test1(){

        Hello target = new HelloImpl();
        Hello proxy = new ProxyExample(target);
        proxy.sayHello("普通静态代理模式");

    }
    

}
测试结果:
before1 代理逻辑
hello 普通静态代理模式
after1 代理逻辑

Process finished with exit code 0

 

二、jdk动态代理

    jdk动态代理同静态一样,需要借助同一个接口才能产生代理对象,这里也使用上面接口。

    在这里我理解的:这里的JdkProxyExample类,虽然是很像上面的ProxyExample类,但是他们本质是有很大差别的了,JDKProxyExample并不是一个被代理者类,而是相当于一个工具类。

    这个工具类的作用,就是代理模式最重要的两个步骤:1、建立代理对象和真实对象的关系; 2、实现代理逻辑。

    而代理者,就应该是遵循最基本的原理,和代理者实现同一个接口,虽然没有直接写它的类,但是在测试中,我们能够通过工具类得到它。

代码如下:

jdk代理:

package ssm.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JdkProxyExample implements InvocationHandler {
    //真实对象
    private Object target = null;

    /**
     *
     * @param target 真实对象
     */
    public JdkProxyExample(Object target) {
        this.target = target;
    }

    /**
     * 1. 建立代理对象和真实对象的代理关系
     *
     *  这个函数是为了得到代理对象
     * @return 代理对象
     */
    public Object getProxyInstance(){
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), this);
    }

    /**
     * 2. 代理方法逻辑
     * @param proxy  代理对象
     * @param method  当前调度方法
     * @param args  当前方法参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println("before2 代理逻辑");
        //相当于 调用 target.sayHello()
        Object obj = method.invoke(target, args);
        System.out.println("after2 代理逻辑");
        return  obj;
    }
}

测试部分(testMain类中):

public static void test2(){
        //被代理者
        Hello target = new HelloImpl();
        JdkProxyExample jdkPE = new JdkProxyExample(target);
        //代理者
        Hello proxy = (Hello) jdkPE.getProxyInstance();
        /*
            在这一句的时候
            运行了 invoke()函数 (继承的)
            这里的proxy, 并不是简单的Hello接口实现
         */
        proxy.sayHello("JDK动态代理");

    }


测试结果:
before2 代理逻辑
hello JDK动态代理
after2 代理逻辑

Process finished with exit code 0

 

三、CGLIB动态代理

    CGLIB动态代理,与前两个不同之处在于:被代理者不需要有接口,只是一个单纯的类就可以代理。所以我新建了个类以体现出来

    CglibProxyExample类和上面JdkProxyExample类都一样是一个工具类。

代码如下:

被代理者:

package ssm.proxy;

public class HelloCglib {
    public void print(){
        System.out.println("CGLIB代理模式");
    }
}

CGLIB代理:

package ssm.proxy;

import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CglibProxyExample implements MethodInterceptor {
    /**
     * 1. 生成CGLIB 代理对象
     * @param cls
     * @return
     */
    public Object getProxy(Class cls){
        //得到 工具类对象
        Enhancer enhancer = new Enhancer();
        //设置 父类
        enhancer.setSuperclass(cls);
        //设置 代理逻辑对象 为 当前对象
        enhancer.setCallback((Callback) this);
        //返回 代理对象
        return enhancer.create();
    }

    /**
     * 2. 代理逻辑方法
     * @param proxy  代理对象
     * @param method  方法
     * @param objects  方法参数
     * @param methodProxy 代理逻辑返回
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object proxy, Method method, Object[] objects,
                            MethodProxy methodProxy) throws Throwable {
        System.out.println("before3 代理逻辑");
        Object result = methodProxy.invokeSuper(proxy, objects);
        System.out.println("after3 代理逻辑");
        return result;
    }
}

测试部分(testMain类中):

public static void test3(){
        //被代理者
        HelloCglib target = new HelloCglib();
        CglibProxyExample cglibPE = new CglibProxyExample();
        //被代理者
        HelloCglib proxy = (HelloCglib) cglibPE.getProxy(target.getClass());
        /*
            在这一句的时候
            运行了 intercept()函数 (继承的)
            这里的proxy, 并不是简单的HelloCglib对象
         */
        proxy.print();
    }

测试结果:
before3 代理逻辑
CGLIB代理模式
after3 代理逻辑

Process finished with exit code 0

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值