Java中的动态代理和静态代理

本文面向初接触动态代理的学者,代码贴在最后

静态代理

其实现思路:

从前有A,B商家注册到了C平台上,A提供一些初级的服务,B对A的服务进行了一些封装从而能实现更厉害的服务。

(写到这里我突然发现和SpringCloud咋这么像。。。。。)

其映射在Java中就是:

C是一个接口,A,B都实现了该接口,B中持有A的引用,B调用方法都是通过A来实现,只不过在实现前后增加了一些操作。

(和装饰者模式咋这么像。。。。。)

其实虽然实现方式是差不多的,但是其终究目的却不同:装饰着模式是增强方法而静态代理是保护和隐藏被代理对象

动态代理

实现思路:

同样有C平台和A,B商家。同样是A提供一些初级的服务,B对A的服务进行了一些封装从而能实现更厉害的服务。差别就在B对A提供的散装服务不用一个一个处理了,而是一起处理

其体现在Java代码中是这样的:

对于B类,不用去实现C接口了,而是持有一个实现C接口的A类引用(在B中要用Object,不然要转换十分麻烦,但是在调用的时候却要传入一个A类的引用),自己实现InvocationHandler接口,其就是jdk为我们提供的动态生成代码的方式:

在以下代码中:C ==Dormitory,B == DormitoryProxy(静态),DynamicDormitory(动态),A==MyDormitory

package sjms.proxy;

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

/**
 * @Author Yan1less
 * @Date 2019/5/1 15:22
 * @Description TODO
 **/
public class DynamicProxy implements InvocationHandler {

    // 这个就是我们要代理的真实对象
    private Object subject;

    //    构造方法,给我们要代理的真实对象赋初值
    public DynamicProxy(Object subject)
    {
        this.subject = subject;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //  在代理真实对象前我们可以添加一些自己的操作
        System.out.println("使用方法之前");

        System.out.println("Method:" + method);

        //    当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
        Object invoke = method.invoke(subject, args);

        //  在代理真实对象后我们也可以添加一些自己的操作
        System.out.println("使用方法之后");

        return invoke;
    }
}

 

package sjms.proxy;

/**
 * @Author Yan1less
 * @Date 2019/5/1 14:53
 * @Description 被代理类,静态代理其实和装饰这模式有点像,这其实可以类比成被装饰者
 **/
public class MyDormitory implements Dormitory{
    @Override
    public void OneFloor() {
        System.out.println("这里是一层");
    }

    @Override
    public void TwoFloor() {
        System.out.println("这里是二层");
    }

    @Override
    public void ThreeFloor() {
        System.out.println("这里是三层");
    }

    @Override
    public int FourFloor() {
        System.out.println("这里是四层");
        return 8888;
    }
}

 

package sjms.proxy;

/**
 * @Author Yan1less
 * @Date 2019/5/1 14:53
 * @Description 可以类比成装置这模式中的装饰者,不过其较动态代理麻烦的地方在于:
 *                  1.方法都要重写一遍,有点麻烦
 *                  2.构造方法传参需要类型转化
 *           最大的区别还是在与:装饰者模式主要目的是增强方法,静态代理目的是保护与隐藏被代理对象
 **/
public class DormitoryProxy implements Dormitory{

    private MyDormitory myDormitory;


    public DormitoryProxy(Dormitory dormitory) {
        if(dormitory.getClass() == MyDormitory.class){
            myDormitory = (MyDormitory)dormitory;
        }
    }

    @Override
    public void OneFloor() {
        System.out.println("抵达XX公寓");
        myDormitory.OneFloor();
    }

    @Override
    public void TwoFloor() {
        System.out.println("抵达XX公寓");
        myDormitory.TwoFloor();
    }

    @Override
    public void ThreeFloor() {
        System.out.println("抵达XX公寓");
        myDormitory.ThreeFloor();
    }

    @Override
    public int FourFloor() {
        System.out.println("抵达XX公寓");
        myDormitory.FourFloor();
        return 8888;
    }
}
package sjms.proxy;

/**
 * @Author Yan1less
 * @Date 2019/5/1 14:52
 * @Description 这是一个接口,被代理类和代理类都要实现它
 **/
public interface Dormitory {

    void OneFloor();
    void TwoFloor();
    void ThreeFloor();
    int FourFloor();

}
package sjms.proxy;


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

/**
 * @Author Yan1less
 * @Date 2019/5/1 14:50
 * @Description TODO
 **/
public class Main {
    public static void main(String[] args) {
        Dormitory dormitory = new MyDormitory();
        Dormitory proxy = new DormitoryProxy(dormitory);
        proxy.OneFloor();

        System.out.println("--------------------------------");

        DynamicProxy dynamicProxy = new DynamicProxy(dormitory);

        Dormitory a = (Dormitory)Proxy.newProxyInstance(dynamicProxy.getClass().getClassLoader(),
                dormitory.getClass().getInterfaces(),dynamicProxy
               );
        int i = a.FourFloor();
        System.out.println(i);

    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值