cglib之设置回调过滤器
1
问题缘起
在学习开源框架jfinal的过程中,尤其是研究其拦截器的实现时,遇到AOP的问题,然后逐步引导着自己学习Java的动态代理,认识到一个强大的工具包:cglib。
在上一篇文章《使用cglib创建Java代理以及调用的结果分析》中,我们学习了cglib创建Java代理的实现方式,通过Enhancer来创建监听对象,从而对方法进行拦截。
如下为main
方法中,对Writer
类进行动态代理的过程。其中WriterInterceptor
实现了net.sf.cglib.proxy.MethodInterceptor
接口
1 | Enhancer enhancer = new Enhancer(); |
在学习cglib的过程中,遇到一个新的概念:回调函数,以及回调过滤器。
回调
Java中也有回调,但是笔者个人碰到回调这个词,第一个想到的是javascript中的回调,将函数作为参数传递给另一个函数:如下所示:
1 | function myDisplayer(some) { |
而Java中的回调是怎么回事呢?
我们知道Java中参数不能传递函数,那么又是如何实现回调的呢?
如下代码是一种实现回调的逻辑:通过只有一个函数的接口,在对象中保存一个接口对象,在指定方法内部调用接口对象的方法,从而实现回调机制:
1 | package com.qw.callback; |
1 | package com.qw.callback; |
执行结果:
1 | 回调函数被执行啦... |
cglib的回调过滤
借助cglib,可以实现给某个类的所有方法或部分方法设置回调函数,可以实现修改函数返回结果,添加过滤器等功能。
一个实现样例如下:
有要被过滤的类Writer
,他它有三个方法,如下:
1 | package com.qw.cglib; |
回调过滤器的实现,如下,通过实现net.sf.cglib.proxy.CallbackFilter
接口,其中的accept
方法可以指定设置类的过滤数组时,某个方法在过滤数组中的索引:
1 | package com.qw.cglibfilter; |
过滤器使用方式:
1 | Enhancer enhancer = new Enhancer(); |
上述代码中,TargetInterceptor
是我们上一篇文章中的方法拦截器类,这里不再赘述。NoOp
类表明什么操作也不做(可以看看下面的运行结果来体会一下),TargetResultFixed
实现了net.sf.cglib.proxy.FixedValue
接口,可以修改函数的返回值。
我们先来看看运行结果:
1 | doWork |
代码补充
TargetResultFixed
类的代码:
1 | package com.qw.cglibfilter; |