动态代理

概述

a想访问c,但不让直接访问c,而b能访问c,所以a访问b,b再访问c,这样a间接就访问了c

  1. 功能增强: 给其他人的类添加功能,不能直接修改对方的代码,可以通过代理增加点功能
  2. 控制访问: 代理类不让你访问目标,例如商家不让你直接访问厂家

静态代理

  1. 代理类是手工实现的,自己创建一个java类,表示代理类
  2. 同时你所要代理的目标类是确定的

优缺点

优点

  1. 实现简单
  2. 容易理解【用户,商家(代理卖U盘),厂家(卖u盘)】

缺点

  1. 当目标类增加了,代理类成倍增加 ,每个代理商家都要卖不同的目标,这样就nxn成指数性增长
  2. 若 售卖u盘接口增加方法,那么所有创建的代理类,厂家都得改,不灵活

实现步骤

  1. 创建一个接口,定义卖u盘的方法,表示你的厂家和商家正在做的事
  2. 创建厂家类,实现步骤1的接口
  3. 创建商家类,就是代理,实现步骤1的接口,并进行精美的包装
  4. 创建客户类,调用商家的方法买u盘

动态代理

简述: 动态代理就是不动原本的代码,对其代码进行调用,并增强功能

在静态代理中目标类有很多时,可以使用动态代理,可以避免静态代理的缺点,动态代理中目标类,代理类即使很多,就算增加了接口的功能,也不影响代理类和目标类

动态代理: 在程序执行过程中,使用jdk的反射机制,创建代理类对象,并动态的指定要代理目标类,而且不用创建对象,就可以执行对应的方法
在java中,创建对象需要创建类文件,编译为class文件,再通过构造方法创建对象,而动态代理不需要创建类文件,直接就通过构造方法直接创建对象

例1

该程序通过创建一个代理任务接口( 卖U盘),厂家实现这个接口,重写卖U盘的具体操作,创建代理类【创建一个方法,传参目标对象,返回一个代理类对象】,在测试类Test里面创建目标类对象,拿代理类ProxySell.method()返回一个代理类对象,用代理类对象调用其代理任务方法sell(),返回目标类sell()的返回值。

代理类

package 动态代理;  
import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Method;  
import java.lang.reflect.Proxy;  
  
//代理类  
public class ProxySell {  
    //这里创建一个方法,用来接收工厂类,自动创建代理类,返回代理类的对象  
    public static SellDrive method(Factory factory) {  
  
        // Proxy.newProxyInstance()方法,创建一个代理类对象,返回值是一个Object对象(代理对象)  
        // 参数1:代理类的加载器(负责向内存加载对象的),参数2: 代理任务数组  参数3 创建一个(调用处理器)InvocationHandler匿名内部类 ,用实现接口的引用接收  
        //强转Object为代理类  
  
        SellDrive s = (SellDrive) Proxy.newProxyInstance(ProxySell.class.getClassLoader(), new Class[]{SellDrive.class}, new InvocationHandler() {  
            @Override  
            //参数1:代理类对象  参数2:目标类中的方法,jdk提供method对象的, 参数3:目标类中方法的参数  
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
                //自己要增加的功能  
  
                //判断要代理的任务,并作出不同的处理(中间商加价)  
                if (method.getName().equals("sell")) { //当然这里只要代理一个任务,所以也可以不用判断  
                    System.out.println("多卖二十");  
                }  
  
                //上面代理商做完附加的功能,后面加上厂家(目标类)所要执行的功能  
  
                //   该方法method.invoke() ,可以执行某个目标类中的方法    参数1:目标对象 ,参数2:目标的方法参数  
                //也就是说现在执行的是目标类Factory类中的method方法  
                return method.invoke(factory, 2);  
            }  
        });  
        //返回一个代理类对象  
        return s;  
    }  
}

例2

例3

有人找杨超唱歌,杨超越找中介公司,中介公司找代理(接口)帮他准备

执行流程 创建类 1. 代理任务接口 2.客户实现代理接口,3.代理工具(传值客户对象(接口的实现类)),返回一个接口实现类



posted @ 2025-01-20 00:20  加油酱  阅读(21)  评论(0)    收藏  举报