代理模式的一些理解

代理模式(相关文件在最下方)

静态代理

  • 接口:例如:租房子
  • 真实角色:向代理角色发出信息,例如,房东:要出租房子
  • 代理角色:收到真实角色信息,并做一些附属操作,例如:中介:带顾客看房,收取中介费等
  • 客户:从代理角色处实现目标,例如:面向中介租房,不再是面向房东
  • 一般原业务代码不进行修改,要增添新功能只需要在增加一个代理角色,用来增加新功能,而不需要更改原业务代码
  • 代理模式降低了耦合性,实现了分工,但是增加了代码量,因为不仅要加入新代码还有调用老代码
    ###动态代理
  • 动态代理和静态代理角色相同
  • 动态代理的代理类是动态生成的,不需要我们直接写好
  • 动态代理分为两大类:1.基于接口的动态代理;2.基于类的动态代理
    a.基于接口:JDK的动态代理
    b.基于类:cglib
    c.java字节码实现:javasist(使用较多,快速简单的改变类的结构,生成动态类)
  • invoke(proxy:代理对象,method:代理对象调用的被代理对象的方法的方法名,args:方法的参数,如果没有参数就是null)
    invoke返回一个实例类。
    ###个人理解(静态代理和动态代理的比较看 spring-08-proxy项目中的demo2和demo4)
    首先,采用代理模式是为了降低耦合性,进行业务分工,当公共业务发生扩展时方便集中管理。
    代理模式又分为两类:静态代理 、 动态代理(利用反射)
  • 动态代理角色和静态代理抽象出来的角色 所做的工作相同,但一个是动态生成代理对象(一对多:一个代理角色类对应多个真实角色类),一个是静态生成(一对一)
  • **********静态代理********** 虽然降低了耦合性,并进行了业务分工,但是因为是采用的重写被代理对象的所有方法的方式,一个真实角色就要对应一个代理角色,是一对一的关系,
    导致代码量成倍增加(动态代理是多个真实角色对应一个代理角色,是多对一的关系,所以降低了代码量)
  • 例如,有一个UserService接口,定义了10个方法:
    不采用代理模式时:应该定义一个UserServiceImpl用来实现接口UserService里的方法
  • 采用静态代理时:同样定义了一个实现类UserServiceProxy用来实现接口UserService里的方法,!!!但是,该实现类是!重写!!UserServiceImpl中
    的方法,并不是直接重头实现接口里的方法,
    可查看spring-08-demo2里写的代理角色的方法。

  • 采用动态代理时:定义一个实现类ProxyInvocationHandler,!!!!实现接口InvocationHandler!!!这个与静态代理不同,接口InvocationHandler
    只有一个Invoke方法,只需重写invoke方法,当通过生成的动态代理对象调用被代理的对象时,动态代理是进行自动调用invoke方法实现,而不是需要在该类中重写所有方法,只需invoke里获得 method.invoke方法的值即可

  • **********动态代理**********不仅降低了耦合性,进行了程序分工,并且不增加代码量,是动态生成的
  • 动态代理-代理角色类的工作:
    1.该类 实现InvocationHandler接口:public class 代理角色名字 implements InvocationHandler{具体内容}
    2.定义被代理的接口(被代理的对象),并为接口(对象)设置set方法:

    private Object target;

    public void setTarget(Object target) {this.target = target;}

    因为是动态代理,所以设为Object类型,使用时通过set方法注入
    3.生成代理对象:

    public Object getProxy(){return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this);}

    代理对象既可以调用被代理对象的全部方法,又可以在调用被代理对象的方法时调用新增方法
    4.编写invoke方法

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {新增方法;Object result = method.invoke(target, args); return result;新增方法;}

    invoke方法时动态代理的灵魂,当生成了代理对象,用代理对象调用被代理对象的方法时,会自动调用invoke方法,分别传入invoke(,,)的三个参数:1.代理对 象; 2.调用的方法; 3.传入给方法的参数(无参数默认传入null) 其中 :result = method.invoke(target, args); return result;是调用被代理 程序的方法,在其上下文中可按需求增添新的方法进去
  • 动态代理-客户端的工作(使用动态代理的方法):
    1.生成真实角色(不可以是接口),例如:

    UserServiceImpl 真实角色名 = new UserServiceImpl();

    2.初始化代理角色(固定代码):
    定义的代理角色类名 pih = new 定义的代理角色类名(); 例如spring-08的demo4的ProxyInvocationHandler类
    3.为代理角色设置要代理的对象(使用代理角色类中写入的set方法):

    pih.setTarget(真实角色名); 则真实角色被代理角色pih代理

    4.动态生成 代理对象(是一个类)

    UserService proxy = (UserService) pih.getProxy();

    真实对象类的类型 代理对象名 = (真实对象类的类型) 代理角色.getProxy(),getProxy()为代理角色类中生成代理对象的方法。 5.使用 代理对象 调用 被代理对象(真实角色) 的方法:

    proxy.update();

    ,proxy为代理对象名,update为被代理对象的原方法,这里会传入Invoke的三个参数为:proxy,update,null 当使用代理对象调用被代理对象的方法时,代理对象为自动调用代理角色类中写好的Invoke()方法,分别传入invoke方法三个参数:代理对象、方法名、方法的参 数。 在invoke方法里,会自动调用被代理对象的原方法和新写入Invoke里的方法。

相关文件下载
spring-study:
链接:https://pan.baidu.com/s/1YWbZJ_EGWyJInxBtR9c1UQ
提取码:bjfu

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值