指定代理是什么意思(如何理解动态代理机制)

 2025-08-22 06:27:01  阅读 106  评论 0

摘要:生活中的代理例子:比如一家美国大学,可以对全世界招生,留学中介就是代理,帮美国大学招生。代理的特点中介和他们代理的做事是一样:招生。中介是学校的代理,学校是目标。流程为,家长->中介->学校。中介是代理,需要收取费用。为什么找代理中介是专业的。家长没有办法接触

生活中的代理

例子:比如一家美国大学,可以对全世界招生,留学中介就是代理,帮美国大学招生。


代理的特点

中介和他们代理的做事是一样:招生。中介是学校的代理,学校是目标。流程为,家长->中介->学校。中介是代理,需要收取费用。

为什么找代理

中介是专业的。家长没有办法接触到学校。

开发中的代理

例子1:A类想调用C类,但是C类禁止访问,只能在AC中间创建B类作为代理。 C的结果给B,B给A。


例子2:登录需要手机验证码,我们没有能力发送短信,移动联通有能力发短信。 移动联通有子公司提供发送短信的业务,于是我们->子公司->移动联通发短信。


代理模式

代理模式的定义

为其他对象提供一种代理以控制对这个对象的访问。在某些情况下一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。


代理模式的作用

功能增强:在你原有的功能上新增加功能。控制访问:代理类不让你访问目标类。

代理的实现方式

静态代理

代理类是自己手工实现的。代理的目标是确定的。特点:实现简单,容易理解。

例子:用户购买U盘,商家代理某个品牌的U盘。商家卖U盘,厂家提供。用户(客户端)->代理类(商家)->目标(厂家)。

步骤:

创建接口实现卖U盘的方法,即厂家和商家要做的事情。创建商家类实现卖U盘的方法。创建厂家类实现卖U盘的方法。创建一个客户端类,调用商家方法去买U盘。

代码:

//厂家商家都要实现的功能
public interface UsbSaleService {
    //提供买U盘的数量,返回价格
    float sell(int i);
}
//厂家,不接受用户直接购买
class UsbFactory implements UsbSaleService{
    @Override
    public float sell(int i) {
        //厂家发货,一个2GU盘20元
        return i*20f;
    }
}
//商家,代理U盘的销售
class Taobao implements UsbSaleService{
    //指定代理的厂家
    private UsbFactory usbFactory=new UsbFactory();
    @Override
    public float sell(int i) {
        //向厂家发送订单,厂家发货
        //代理加价,一个U盘加10元,增强功能
        return usbFactory.sell(i)+i*10f;
    }
}
//用户购买
class shop{
    public static void main(String[] args) {
        //控制访问
        Taobao taobao=new Taobao();
        System.out.println(taobao.sell(5));
    }
}

静态代理优缺点: 缺点:

目标类增加,代理类会成倍的增加,即代理类数量过多。功能类增加方法后导致目标类、代理类都需要修改,影响较大。

优点:

功能增强。访问控制,解耦。

动态代理

在程序执行过程中,使用jdk反射机制,创建代理类对象,并动态的指定要代理的目标类,无需用户创建对象。

总结

如何理解动态代理机制?

复习反射

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class InflectTest {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        /*创建对象执行
        helloImpl hello=new helloImpl();
        hello.sayHello("张三");
        */
        /*通过反射执行
        Hello h=new HelloImpl();
        Method method=Hello.class.getMethod("sayHello", String.class);
        Object res=method.invoke(h,"李四");
        */
    }
}
class HelloImpl implements Hello{
    @Override
    public void sayHello(String name) {
        System.out.println("你好,"+name);
    }
}
interface Hello{
    public void sayHello(String name);
}

如何实现动态代理

如何理解动态代理机制?


如何理解动态代理机制?


如何理解动态代理机制?


如何理解动态代理机制?


//参数1:jdk提供的代理对象无需赋值
//参数2:jdk提供的目标类的方法
//参数3:目标类方法的参数
public Object invoke(Object proxy, Method method, Object[] args)    throws Throwable;
复制代码

如何理解动态代理机制?


如何理解动态代理机制?


案例一:

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

interface Moveable {
    void move();
}
public class Car implements Moveable {
    @Override
    public void move() {
        try {
            Thread.sleep(new Random().nextInt(1000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
class TimeHandler implements InvocationHandler {
    public TimeHandler(Object target) {
        super();
        this.target = target;
    }
    private Object target;
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        long starttime = System.currentTimeMillis();
        method.invoke(target);
        long endtime = System.currentTimeMillis();
        System.out.println("汽车行驶时间:" +(endtime - starttime) + "毫秒!");
        return null;
    }
}
class Test {
    public static void main(String[] args) {
        Car car = new Car();
        InvocationHandler h = new TimeHandler(car);
        Class cls = car.getClass();
        Moveable m = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h);
        m.move();
    }
}

如何理解动态代理机制?

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

interface UsbSell{
    float sell(int sum);
}
class Factory implements UsbSell{
    @Override
    public float sell(int sum) {
        return sum*100f;
    }
}
class MySellHandle implements InvocationHandler{
    private Object target;
    MySellHandle(Object target){
        this.target=target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object res=method.invoke(target,args);
        return (Float)res+(int)args[0]*5;
    }
}
public class JDKModel {
    public static void main(String[] args) {
        UsbSell usbSell=new Factory();
        InvocationHandler handler=new MySellHandle(usbSell);
        UsbSell proxy=(UsbSell) Proxy.newProxyInstance(usbSell.getClass().getClassLoader(),usbSell.getClass().getInterfaces(),handler);
        System.out.println(proxy.sell(10));
    }
}

实际开发中动态代理的应用


JDK动态代理,必须有接口。 CGLib动态代理,必须能被继承,即class不能是 final。


我在校大二期间接过私活,一元秒杀抢购系统。 这个系统有两个特点,一没有文档,二没有源码。只有一堆运行在Tomcat上的class文件和html文件。除了新增的CUID等功能外,还要调用之前人写的代码。因为不敢动之前人写的代码,所以就先反编译,然后继承重写指定方法,测试没问题后在修改AJAX的URL。上一个人不开发了,所以不用考虑代码变动问题。最主要的是发现要重写的太多了,评估了一下工作量,要继承重写几十个ServiceImpl,后来就直接用动态代理来做的。

作者:比卷帘门还能卷链接:https://juejin.cn/post/7044907218050744328

版权声明:我们致力于保护作者版权,注重分享,被刊用文章【指定代理是什么意思(如何理解动态代理机制)】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!;

原文链接:https://www.yxiso.com/zhishi/2097068.html

发表评论:

关于我们
院校搜的目标不仅是为用户提供数据和信息,更是成为每一位学子梦想实现的桥梁。我们相信,通过准确的信息与专业的指导,每一位学子都能找到属于自己的教育之路,迈向成功的未来。助力每一个梦想,实现更美好的未来!
联系方式
电话:
地址:广东省中山市
Email:beimuxi@protonmail.com

Copyright © 2022 院校搜 Inc. 保留所有权利。 Powered by BEIMUCMS 3.0.3

页面耗时0.0357秒, 内存占用1.93 MB, 访问数据库24次

陕ICP备14005772号-15