代理模式之动态代理、静态代理

17 篇文章 0 订阅
本文探讨了静态代理的定义、目的及其局限性,重点介绍了JDK动态代理的实现原理和如何通过SellProxyFactory创建动态代理对象。通过实例展示了如何利用Proxy和InvocationHandler在Java中创建代理以增强功能和控制访问。
摘要由CSDN通过智能技术生成

1.静态代理

在这里插入图片描述

  1. 定义真实对象和代理对象的公共接口
  2. 代对象内部保存对真实目标对象的引用
  3. 访问者仅能通过代理对象访问真实目标对象,不可直接访问目标对象

1.1代理模式的定义

给目标对象提供一个代理对象,代理对象包含该目标对象,并控制对该目标对象的访问。

1.2代理模式的目的:

  • 通过代理对象的隔离,可以在对目标对象访问前后增加额外的业务逻辑,实现功能增强。
  • 通过代理对象访问目标对象,可以防止系统大量地直接对目标对象进行不正确地访问,出现不可预测的后果

1.3静态代理的缺点

  • 静态代理违反了开闭原则,面对新的需求时,需要修改代理类,增加实现新的接口和方法,导致代理类越来越庞大,变得难以维护。

2.动态代理

动态代理解决的问题是面对新的需求时,不需要修改代理对象的代码,只需要新增接口和真实对象,在客户端调用即可完成新的代理。

2.1JDK Proxy实现动态代理

JDK Proxy 是 JDK 提供的一个动态代理机制,它涉及到两个核心类,分别是ProxyInvocationHandler

在这里插入图片描述
动态代理和静态代理区别不大,唯一的变动是代理对象,由代理工厂生产。

  • 如何实现一个代理工厂
  • 如何通过代理工厂动态生成代理对象
//实现一个代理工厂
// 自定义 InvocationHandler  (也可以看做是代理)
public class SellProxyFactory implements InvocationHandler {
	/** 代理的真实对象 */
    private Object realObject;
    public SellProxyFactory(Object realObject) {
        this.realObject = realObject;
    }    

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        doSomethingBefore();        
        Object obj = method.invoke(realObject, args);        
        doSomethingAfter();        
        return obj;

    }    private void doSomethingAfter() {
        System.out.println("执行代理后的额外操作...");
    }    private void doSomethingBefore() {
        System.out.println("执行代理前的额外操作...");
    }    
}

  • Object proxy:代理对象
  • Method method:真正执行的方法
  • Object[] agrs:调用第二个参数 method 时传入的参数列表值

如何通过代理工厂动态生成代理对象。

  • 生成代理对象需要用到Proxy类,它可以帮助我们生成任意一个代理对象,里面提供一个静态方法newProxyInstance。
Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h);

实例化代理对象时,需要传入3个参数:

//通过代理工厂动态生成代理对象
public class XiaoMing {
    public static void main(String[] args) {
        //真实对象和代理对象的公共接口
        ChanelFactory chanelFactory = new ChanelFactory();
        //代理类的调用处理程序,即调用接口中的方法时,会找到该代理工厂h,执行invoke()方法
        SellProxyFactory sellProxyFactory = new SellProxyFactory(chanelFactory);
        //代理工厂获取代理对象,这个对象是动态生成的,没有java源文件
        SellPerfume sellPerfume = (SellPerfume) Proxy.newProxyInstance(
            chanelFactory.getClass().getClassLoader(),
            chanelFactory.getClass().getInterfaces(),                
            sellProxyFactory);        
        sellPerfume.sellPerfume(1999.99);
    }
}
  • ClassLoader loader:加载动态代理类的类加载器
  • Class<?>[] interfaces:代理类实现的接口,可以传入多个接口
  • InvocationHandler h:指定代理类的调用处理程序,即调用接口中的方法时,会找到该代理工厂h,执行invoke()方法

JDK 动态代理的使用方法

  • 代理工厂需要实现 InvocationHandler接口,调用代理方法时会转向执行invoke()方法
  • 生成代理对象需要使用Proxy对象中的newProxyInstance()方法,返回对象可强转成传入的其中一个接口,然后调用接口方法即可实现代理

JDK 动态代理的特点

  • 目标对象强制需要实现一个接口,否则无法使用 JDK 动态代理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值