静态代理:对某个具体接口做特定的加强!

动态代理:只要一个实现类,实现了任意一个接口,并且想对这个接口里的方法进行增强,

只需要一个代理对象,就可以统筹兼顾所有这样的实现类。

这个代理对象的职责一般是单一的,用来打日志,或者鉴权啥的。

能够在不侵入源代码的情况下,做到对实现类接口方法的增强

引言:

我们从一个例子引入:

我们现在有一个bigstar,实现了star接口。

star接口内定义的就是我们bigstar所需要加强的方法。

star接口内有一个sing的方法,如下

但是我们bigstar在唱歌之前还需要一个人来帮我准备场地,但是我又不想动star的代码,大明星怎么可能会来准备场地呢。我们需要一个代理。

静态代理

具体代码怎么写呢?

只需要一个代理,也实现star接口来增强方法就可以了

(streambuffer流中就是用的这一套)

可以看到,我们在没有改变Bigstar的代码下,成功实现了准备场地的增强方法。

而且这个代理类不仅能够对Bigstar起作用,对任何一个实现了star接口的方法都能够起作用。

静态代理的优点:简单,编译时就已经确定,无性能损耗

缺点-->假设有另一个舞者来的话,不能复用创建场地的代码,只能为舞者单独写一个创建场地的代理

如果有100个人想要创建场地,就需要写100个代理类,会让类爆炸!

动态代理应运而生!

动态代理三要素:

实现类

接口

InvocationHandler(动态代理处理器)

接口、实现类和静态代理一样,我们已经有了star和bigstar

注意,这里的target是object类型,target的意思是我们需要代理的对象,比如bigstar

运行结果是一样的。

动态代理这样使用,可以看到代码相对复杂。

但是动态代理的好处就是可以复用,比如说要新来一个舞者,只需定义一个接口一个具体类,将star改为dancer,bigstar改为bigdancer即可

例1

--现在来到我们的项目之中,该如何完成线程池策略报警

目的:在原有用户自定义线程池拒绝策略下,增加报警功能(比如说输出到日志上)

可以看到,reject方法被final修饰,不能重写。

但是很巧的是,下面的handle(线程池拒绝策略处理器)是一个接口,已有四种线程池拒绝策略的实现类!

我们需要对其进行加强,补上报警功能。

代理模式呼之欲出!

静态代理 or 动态代理?

由于是单纯对线程池拒绝策略的拓展,并不会涉及到其他的东西,相当于我们只对bigstar进行服务,使用静态代理显然是更好的选择!

可以类似我们上面给bigstar的静态代理,写出一个样板代码

注意,我们要代理的实际上是RejectedExecutionHandlr,这里对线程池做继承是为了拓展线程池的方法(其实也是一种代理方式,利用继承来做代理)

代理类接口,在调用原来的拒绝策略处理器前先调用beforereject

测试没有问题,最大线程数加上阻塞队列长度为5,拒绝3次,所以说刚好是两次拒绝。

为什么要选择override set方法,而不是直接如同我们之前的静态代理(装饰器模式)一样,在原有的处理器上做包装?就像这样

原因:我们要做的是动态线程池,需要支持可以动态调整拒绝策略,所以说需要重写set方法,让我们后面可以更换。

根据新的配置文件中的rejecthandle来进行更换。

--------------------拓展1-----------------

lambda表达式实现静态代理

(这个代理类是匿名的,如果只会在这里被使用可以做成匿名函数更加简单)

可以直接省去定义新的代理对象的步骤,直接用lambda表达式,更简洁明了。

--------------------拓展2---------------------

JDK 动态代理为什么不能对类进行代理,只能对接口做代理?

原因:因为代理对象已经继承了Proxy类,无法再继承我们想要的类(像SupportRejectPoolExecutor那样)

同理:抽象类也是类,做不了代理

mybatis没有实现类,怎么做到的动态代理?

前面提到,动态代理的三要素为:

实现类

接口

InvocationHandler(动态代理处理器)

而在实际应用中,我们往往是通过mapper接口加上注解上写sql来实现的。

mybatis没有实现类,怎么做到的动态代理?

可以注意到,我们是有接口的,直接对接口上的注释提取拿到sql,新建一个代理对象,但是这个代理对象不需要调用实现类的方法,只需要解析sql,调用jdbc,解析数据库传回来的结果便可。整个流程中不需要实现类。

第一次写博客,大家多多海涵。

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐