java静态代理、动态代理实现

一、代理模式概念

  • 定义:

    为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在被代理的对象和目标对象之间起到中介的作用。*例如,你(真实角色)要打官司(抽象角色)告张三(真实角色)偷了你家的鸡蛋,你请了一个律师(代理角色),那这个律师就相当于你的代理对象,你这个被代理的对象就只需要坚定张三就是偷了你家鸡蛋的核心需求就行了,准备资料、向法官提交资料等琐碎的是你的代理对象律师会帮你搞定。

  • 角色:

    抽象角色: 包含真实角色需要实现的核心业务的接口或者类
    真实角色: 实现抽象角色的类
    代理角色: 代理真实角色的类,对真实角色进行业务扩展

  • 优点:

(1)解耦合、高扩展性: 添加新的需求不需要修改原来的代码
(2) 职责清晰: 真实角色只需要实现自身的核心业务,而不需要考虑其他非自身职责的需求

  • 静态代理和动态代理的区别:

静态代理是在编译前已经确定的代理关系,动态代理是通过反射在程序运行中 生成的代理关系。


二、代理模式分类

1、 静态代理

下面通过打官司的例子来实现静态代理模式:
抽象角色:打官司
真实角色:原告
代理角色:律师

(1)抽象角色:

/**
 * @Author 吕小白
 * @Interface Lawsuit
 * @Description: 抽象角色:打官司
 * @Date 2021/8/27 16:21
 * @Version 1.0
 **/
public interface Lawsuit {
//    打官司的诉求
    public void  appeal(String testimony);
}

(2)真实角色:

/**
 * @Author 吕小白
 * @ClassName Plaintiff
 * @Description:真实角色:原告
 * @Date 2021/8/27 16:25
 * @Version 1.0
 **/
public class Plaintiff implements Lawsuit{
//    实现抽象角色的业务,提出你的诉求
    @Override
    public void appeal(String testimony) {
        System.out.println(testimony);
    }
}

(3)代理角色

/**
 * @Author 吕小白
 * @ClassName Lawyer
 * @Description:代理角色:律师
 * @Date 2021/8/27 16:28
 * @Version 1.0
 **/
public class Lawyer implements Lawsuit{
//    被代理的对象
    private Lawsuit target;
    public Lawyer(Lawsuit target) {
        this.target = target;
    }
//实现抽象角色的业务
    @Override
    public void appeal(String testimony) {
//        实现真实角色需求前
        before();
//        实现真实角色的需求
        target.appeal(testimony);
//        实现真实角色需求后
         after();
    }
//    代理对象扩展的业务
    public void before(){
        System.out.println("打官司前准备资料");
    }
    public void after(){
        System.out.println("打完官司收费");
    }
}

(4)测试运行

public class MainTest {
    public static void main(String[] args) {
//        创建真实对象:原告
        Plaintiff plaintiff = new Plaintiff();
//        创建代理对象:律师
        Lawyer lawyer = new Lawyer(plaintiff);
        lawyer.appeal("状告张三偷了鸡蛋");
    }
}

2、 动态代理

下面是提供接口基于JDK实现的动态代理两个关键类和接口:

(1)Proxy类:newProxyInstance(ClassLoader loader, Object<?>[] interfaces, InvocationHandler h)

  • loader: 类加载器
  • interfaces: 真实角色的接口数组
  • h: InvocationHandler接口的实现类对象

(2)InvocationHandler接口:invoke(Object proxy, Methoh method, Object[] args)

代码实现: 下面继续引用上面的例子,抽象角色和真实角色保持不变

1、代理角色代码:

public class DynamicProxy implements InvocationHandler {
//    要被代理的真实对象
    private Object target;
    public DynamicProxy(Object target) {
        this.target = target;
    }
//获取代理对象
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //        实现真实角色需求前
         before();
//        调用方法
        Object result = method.invoke(target, args);
        //        实现真实角色需求后
        after();
        return result;
    }
    //    代理对象扩展的业务
    public void before(){
        System.out.println("打官司前准备资料");
    }
    public void after(){
        System.out.println("打完官司收费");
    }
}

2、测试代码:

public class MainTest {
    public static void main(String[] args) {
//        创建真实对象:原告
        Lawsuit plaintiff = new Plaintiff();
//        创建代理对象:律师
        DynamicProxy dynamicProxy = new DynamicProxy(plaintiff);
        Lawsuit proxy = (Lawsuit) dynamicProxy.getProxy();
        proxy.appeal("张三偷了鸡蛋");

    }
}


快乐可以靠自己创造

加油吧!少年

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

讨厌令狐冲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值