Java代理模式(动态和静态)

什么是代理模式?

那么什么是代理呢?

日常生活中的代理

这个中介学校就是代理,就是第三方在学校和家长之间赚取费用

而且,现在这种模式,会比平时家长直接找学校多收取了中介费

这笔中介费,就是代理的增强 

那么我们为什么需要找中介?为什么需要找代理呢?

日常生活需要中介

 开发中需要代理

此时b就是代理

 生活中开发程序的代理情况

 举例

 代理模式的作用

 我们之前上外国大学的例子,中介代理收取的中介费,就是增强

实现代理的方式——静态代理和动态代理

静态代理

自己实现静态代理 

定义一个接口表示规范

现在市场里有金士顿这个牌子,所以要遵守市场规范

这是目标类,表示u盘的厂家,因为要在这个市场,所以需要遵守市场规范(要实现接口)
但是此时厂家不和用户买卖(因为用户买的太少了)
现在当作大家都只买一个u盘,一个u盘85元

 但是用户确实是需要u盘,厂家不直销,应该找一些之间代理的商铺去购买,但是商铺也要遵守市场规范

package com.LALALA.shangjia;


import com.LALALA.factory.UsbKingFactory;
import com.LALALA.service.UsbShell;

//代理类,现在我们的淘宝要做金士顿的代理,但是也要遵守市场规范
public class TaoBao implements UsbShell {
    //首先告诉大家自己是誰的代理
    private UsbKingFactory factory = new UsbKingFactory();

    //这里真正的向用户卖u盘,但是自己没法造,就要联系厂家
    @Override
    public float shell(int amount) {
        float price = factory.shell(amount);//联系厂家,获得厂家的售价
        //商家做代理肯定需要加价钱
        price = price + 25;//商家每个u盘赚取25元
        
        //返回给用户自己卖多少钱
        return price;
    }
}

最后就是用户向淘宝商家购买u盘

package com.LALALA;

import com.LALALA.shangjia.TaoBao;

public class ShopMain {



    public static void main(String[] args) {
        //要先找到一个淘宝商家
        TaoBao taoBao = new TaoBao();

        //调用淘宝的方法进行购买
        float price = taoBao.shell(1);
        System.out.println("by taobao buy u price::::"+price);
    }
}                

此时输出

完成了一套静态代理的流程

 这就实现了淘宝对用户的访问控制(不让你去品牌工厂购买)

这就实现了淘宝对用户的方法增强(比起去工厂买,多收了25块)

注意:实现目标类的方法之后,都属于增强的功能

我们在目标类中写一个验证

譬如现在淘宝卖给你u盘后,给了一张优惠卷也属于是功能增强

 现在的测试:

 淘宝(代理类)的加钱和返回优惠卷都是方法的增强,但是u盘制造(目标类)还是厂家完成的

 

 静态代理的缺点

我们不仅可以淘宝代理金士顿u盘,微商也可以

微商只挣1块钱

 用户在微商这边购买

 

 但是制造u盘的厂家也可能不止一个

同样也会有代理

 

 

缺点一:增加了一个厂家,代理要成倍的增长

 如果市场有了一个新规范

 缺点二:此时我们的所有代理和厂家都要进行更改

 如何解决这些问题呢?

可以使用动态代理

动态代理

动态代理的定义

 什么是动态代理?

 

在我们之前写的静态代理的 代理类中,我们需要每个代理类都要写死一个自己代理的是哪个目标类,而我们现在的动态代理可以动态的指定要给哪个目标类创建代理,在程序执行的时候才会创建代理类的对象

动态代理的分类(分为有接口的情况和没有接口的情况)

 复习Method类

 定义一个简单的接口和实现类,目标是想说hello加名字

 

 此时会成功输出

但是我们想利用反射机制执行sayhello方法

 再使用method.invoke就可以了

但是这个方法中有两个参数,应该填写什么呢?

 所以第一个参数要指出要执行哪个对象的方法(我们上面new过了接口),第二个参数填写参数值(直接写名字,例如张三李四),最后返回的也是一个对象

 此时我们的method已经找到了要执行哪个方法,所以只要填写对象和参数就可以了

 如果这个接口有其他的实现类也想这样子执行可不可以呢?

 

 

 可以,只需要再new一个实现类并且invoke就可以了

此时通过invoke就可以执行任意对象实现类中的sayhello方法了

实现动态代理的三个类

这三个类都是干什么的?

InvocationHandler

 我们需要把在代理类中增加的语句写在这个接口的方法里

 其中method就是我们上面复习的,找到了某个对象的某个方法,args就是这个方法里需要的参数

但是这些都是JDK会帮我们做的,不用我们进行赋值

用起来还是比较简单的

Method

 factoy就是service2(在准备反射的时候被new好了)

amount就是李四(填写方法执行的参数)

.sell就是method.(在之前使用了.getMethod获取了我们指定的方法名称,存在method这个对象里了)

主要是实现InvocationHandler里的调用目标方法,要写在InvocationHandler里面

 Proxy

 这玩意就是我们之前用户去找淘宝店的功能

最后返回的对象当成之前的淘宝店使用就好了,但是现在的这东西是个对象类型,所以在使用时还需要把他转换为我们需要的接口类型

动态代理的实现

步骤

第一步

第二步 

第三步

package com.LALALA.handler;

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


//动态代理必须实现InvocationHandler的接口,完成代理类要做的功能(调用目标方法,功能增强)
public class MyShellHandler implements InvocationHandler {

    private Object target;
    //传入的是谁,就赋值给谁,方便method使用
    public MyShellHandler(Object target) {
        //给目标对象赋值
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //先把原本静态的代理类内代码复制过来看看
        //float price = factory.shell(amount);//联系厂家,获得厂家的售价

        //定义一个res对象接收method.invoke的执行结果
        Object res = null;


        //现在我们知道要执行哪个方法(method),也知道执行的参数填写(args),那么对哪个对象执行呢?
        //我们现在是动态代理,需要从外面传入,传入哪个就执行哪个,就很动态
        res = method.invoke(target,args);




        //商家做代理肯定需要加价钱
        //price = price + 25;//商家每个u盘赚取25元

        //判断并且增强
        if (res!=null){
            Float price = (Float) res;
            price = price + 25;
            res = price;
        }

        System.out.println("give you money 10yuan");

        //返回给用户自己卖多少钱
        
        //现在返回res就可以了
        return res;
    }
}

第四步

创建代理对象,但是代理对象里面需要参数,所以要创建目标对象,和handler对象

 准备工作好了,现在创建代理对象并且填入参数

 现在Proxy是一个对象,要强制转换为我们想用的接口进行使用

 

 测试成功

 动态代理执行的流程图

 所以动态代理可以干什么?

 

 

 

 现在假设我们没办法动用GongNeng类的源文件,但是我感觉它的pring方法不好,应该返回的是结果的2倍,学习完动态代理就可以完成了

  测试成功

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值