通过代理模式 + 责任链模式实现对目标执行方法拦截和增强功能

前言

         最近需要实现一个插件功能,但是如果做成两个接口的话(即执行前和执行后),那么会降低插件的可玩性,所以需做成类似AOP的环绕通知形式,所以就使用到了责任链模式和代理模式进行实现。

介绍

代理模式(Proxy Pattern)

        定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。

        UML:

 

Java中,常见代理模式的实现有Java静态、动态代理,CGLIB动态代理,JAVAssist动态代理等等。

责任链模式(Chain of Responsibility Pattern)

       定义:为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。

在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

        UML:

可以把它理解为一个链表,每个节点上的对象都实现了同一个接口,并且在对象内部指向下一个节点对象,在开始执行第一个节点的时候,就会传递到每一个节点

常见的责任链实现有 Servlet中的Filter,SpringMVC的Intercept拦截器,AOP中的环绕通知,Mybatis的插件功能,Druid中Filter等等。

实现

实现一个简单的目标执行器执行

定义一个Executor接口,TargetExecutor实现Executor并实现execute方法,然后通过Executor进行调用,定义一个参数对象,模拟真实业务场景。

现在需要通过代理和责任链实现对Executor的execute方法进行批量增强

定义一个封装代理对象

这个对象是用来在拦截器里面手动调用执行目标方法的,这样就可以在拦截前和拦截后做一些业务处理等等。

 

1:proceed():当调用Proceed对象的proceed方法时,即执行代理对象的目标方法

2:targetObject: 为真实的执行对象(这个是为了记录真实的目标执行对象,可以直接操作目标对象)

3:targetProxy: 为真实/代理对象(第一个拦截器为真实对象,后面的就是前一个拦截器的代理对象)

4:args: 目标执行对象调用方法的参数

定义一个责任链共用接口以及生成代理对象的共用方法

责任链中的共用实现接口

 

1:intercept():

       每个拦截器都需要实现的方法,参数为Proceed对象,每个具体的拦截器可根据具体逻辑进行操作真实的Executor对象和ParamEvent参数对象

2:newProxy():

       创建目标对象的代理方法,由于这里目标执行对象是使用接口实现的方式,所以使用的是JDK的动态代理,如果是普通的类,则可以使用CGLIB动态代理生成代理类

实现代理类的具体执行方法,进行对目标对象的增强

目标执行对象方法真实执行类,当目标执行对象调用目标执行方法时,需要调用拦截器的intercept方法,由拦截器手动调用proceed方法,进入下一个拦截器,因此形成调用链路。

 

1:targetObject: 具体目标执行对象

2:targetProxy:为真实/代理对象

3:intercept:下一个链路节点对象

4:invoke: 动态代理接口执行方法,该方法里面为调用拦截器得intercept方法

创建管理责任链链路对象

用于管理和创建目标执行对象的代理对象

 

1:interceptList:所有实现链路接口的对象有序集合

2:addIntercept():添加链路节点对象方法

3:createProxy(): 创建代理对象方法,参数为target(具体执行对象),利用循环创建代理对象将所有的拦截器生成一个责任链链路。

验证

记录execute方法的运行时间拦截器

修改目标执行方法的对象参数拦截器

修改目标执行对象属性值拦截器

 

  • 查看运行结果:

 

拦截器功能实现成功!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值