`
ihuashao
  • 浏览: 4813128 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Groovy探索之MOP 九 Interceptor 一

阅读更多

Groovy探索之MOP 九 Interceptor 一

近几年以来,AOP(面向方面的编程)得到了广泛的应用,我们把它应用到例如打印日志、权限控制等各个方面。而在实现AOP的时候,我们一般都借助于工具,如Spring AOP等等。

当然,我们借助于工具一般都用在实现系统级的AOP上,这种实现一般都要借助于配置文档来实现。

当我们需要实现较小范围的AOP的时候,比如对有限几个类的某些方法进行AOP,这时候,我们一般不希望使用工具。原因可能是第一工具不够灵活第二需要做繁琐的配置工作。这时候,我们需要自己来实现AOP的方方面面。

Java语言一般来说,有两种方法来实现自己的AOP技术:一是通过反射技术来实现;二是使用动态代理。这两种方法在这里就不多说,但实现起来都比较复杂。

在Groovy语言中,我们可以通过Interceptor(拦截器)来实现AOP技术。使用Interceptor来实现AOP技术,技术难度就小多了,而且更加的灵活。

本系列的文字,正是来谈谈Interceptor技术的方方面面,从它怎么样拦截一个方法起,一直讲到怎么使用它来灵活多变的使用我们自己的AOP。

还是从一个简单的例子说起吧。比如,我们有如下的一个类:

class HelloWorld {

def hello()

{

println 'hello'

}

}

我们现在要拦截它的"hello"方法。

首先,我们要实现自己的拦截器类,在Groovy语言的编程中,实现自己的拦截器类很简单,就是要实现Interceptor接口,而该接口只有简简单单的三个需要实现的方法。如下所示:

class SampleInterceptor implements Interceptor{

Object beforeInvoke(Object object, String methodName, Object[] arguments)

{

if(methodName == 'hello')

{

println 'before invoke hello'

}

}

boolean doInvoke(){ true }

Object afterInvoke(Object object, String methodName, Object[] arguments,

Object result){

result

}

}

从上面的实例代码可以看出,我们的拦截器类需要实现三个方法,即"beforeInvoke"方法,用来做调用方法之前的动作;"doInvoke"方法,决定是否调用需要拦截的方法;"afterInvoke"方法,用来做调用方法之后的动作。

上面的实例代码中,我们拦截了HelloWorld类的"hello"方法,在调用该方法之前打印了"before invoke hello"这样的字样。

现在,我们就可以来测试我们的第一个拦截器类了:

def proxy= ProxyMetaClass.getInstance( HelloWorld )

proxy.interceptor= new SampleInterceptor()

proxy.use{

def helloworld= new HelloWorld()

helloworld.hello()

}

拦截器的使用也十分简单,首先是实例化一个"ProxyMetaClass"类的实例"proxy",然后把我们的拦截器类的实例赋给"proxy"对象的"interceptor"。最后,就是在"proxy"对象的"use"方法里实例化需要被拦截的类,调用它的方法。

上面代码的结果为:

before invoke hello

hello

这样就完成了一个简单的拦截任务。

我们初步认识了我们自己的一个简单的拦截器以后,就需要深入的理解拦截器的方方面面了。

首先,我们使用拦截器拦截了一个类的某个方法,就可以实际调用该方法,就像上面的例子一样,也可以实际上不调用该方法。如下所示:

class SampleInterceptor implements Interceptor{

Object beforeInvoke(Object object, String methodName, Object[] arguments)

{

if(methodName == 'hello')

{

println 'before invoke hello'

}

object

}

boolean doInvoke(){ false }

Object afterInvoke(Object object, String methodName, Object[] arguments,

Object result){

result

}

}

还是上面的拦截器类,为了不调用我们所要拦截的方法,我们做了一点改动。首先,方法"doInvoke"的返回值为"false",它能决定不调用所要拦截的方法。如果不调用所要拦截的方法,那么"beforeInvoke"方法一定要有返回值,如上面的代码返回"object"。否则会报空指针的违例。

现在,我们还是使用上面的使用过的代码来测试它:

def proxy= ProxyMetaClass.getInstance( HelloWorld )

proxy.interceptor= new SampleInterceptor()

proxy.use{

def helloworld= new HelloWorld()

helloworld.hello()

}

运行结果为:

before invoke hello

值得注意的是,在上面的例子中,我们都使用了"beforeInvoke"方法作为例子,它是用来在调用被拦截的方法之前做动作,如果要在调用被拦截的方法之后做动作,就要使用到"afterInvoke",用法两者也大体一样。

现在,我们再来看看"beforeInvoke"和"afterInvoke"方法的参数。其中,"object"是被拦截的对象,"methodName"是被拦截的方法名,"arguments"是被拦截方法的参数。下面一并做测试。

首先,我们对上面的"HelloWorld"类做稍微的改动,以便于我们的测试:

class HelloWorld {

def hello(name)

{

println "hello,$name!"

}

}

同样,我们也需要改动一下我们的拦截器类:

class SampleInterceptor implements Interceptor{

Object beforeInvoke(Object object, String methodName, Object[] arguments)

{

if(methodName == 'hello')

{

println "object: $object"

println "method name: $methodName"

println "method arguments: $arguments"

}

}

boolean doInvoke(){ true } //whether or not to invoke the intercepted

Object afterInvoke(Object object, String methodName, Object[] arguments,

Object result){

result

}

}

最后,我们来测试上面的改动:

def proxy= ProxyMetaClass.getInstance( HelloWorld )

proxy.interceptor= new SampleInterceptor()

proxy.use{

def helloworld= new HelloWorld()

helloworld.hello('world')

}

结果为:

object: mop.interceptor.basic.HelloWorld@f0eed6

method name: hello

method arguments: {"world"}

hello,world!

最后,我们还要看看"afterInvoke"方法的"result"参数,它是被拦截方法的返回值,在上面的例子中,我们都是直接把该参数返回了,表示我们不改变被拦截方法的返回值。说到这里,我们就想到了,当然,我们可以改变被拦截方法的返回值。如下所示:

class HelloWorld {

def test()

{

'hello'

}

}

我们来修改一下拦截器类:

class SampleInterceptor implements Interceptor{

Object beforeInvoke(Object object, String methodName, Object[] arguments)

{

}

boolean doInvoke(){ true }

Object afterInvoke(Object object, String methodName, Object[] arguments,

Object result){

if(methodName == 'test')

{

println result

result = 'world'

}

result

}

}

最后是测试:

def proxy= ProxyMetaClass.getInstance( HelloWorld )

proxy.interceptor= new SampleInterceptor()

proxy.use{

def helloworld= new HelloWorld()

def result = helloworld.test()

println 'after interceptor, the result: '+result

}

结果为:

hello

after interceptor, the result: world

分享到:
评论

相关推荐

    Groovy MOP

    Groovy MOP,全称Meta-Object Protocol(元对象协议),是Groovy语言的一个核心特性,它提供了一种强大的方式来扩展和修改类的行为。在Java中,我们通常需要通过继承或接口实现来扩展功能,但Groovy的MOP允许我们在...

    apache-groovy-3.0.8.zip apache官网的groovy3.0.8版本

    apache-groovy-3.0.8.zip apache官网的groovy3.0.8版本,希望大家多多下载,apache-groovy-3.0.8.zip apache官网的groovy3.0.8版本,希望大家多多下载,apache-groovy-3.0.8.zip apache官网的groovy3.0.8版本,希望...

    Groovy学习资料

    此外,Groovy还有闭包(Closure)的概念,这是Groovy强大的功能之一,它可以用来处理函数式编程任务,如数据过滤和映射。 其次,Groovy的动态特性是另一个关键知识点。Groovy可以在运行时改变类的结构,这意味着你...

    groovy和Java相互调用1

    标题中的“Groovy和Java相互调用1”指的是在编程时如何在Groovy语言环境中调用Java类,以及反之,如何在Java程序中调用Groovy类。这是一种跨语言交互的方式,特别是在混合使用Groovy和Java的项目中非常常见。 ...

    实战groovy.rar

    进一步探索Groovy的高级特性,如Meta Object Protocol (MOP)、GroovyShell、 Grape依赖管理系统等,提升编程技巧。 七、社区资源与工具 积极参与Groovy社区,利用官方文档、Stack Overflow、Groovy Slack等平台获取...

    Java调用Groovy,实时动态加载数据库groovy脚本

    1. 引入Groovy库:在Java项目中添加Groovy的相关依赖,通常是`groovy-all`,确保Java能够访问Groovy运行时环境。 2. 创建GroovyClassLoader:使用这个类加载器可以动态加载和执行Groovy脚本。它继承自Java的...

    groovy-sdk-4.0.3

    Groovy SDK 4.0.3 是一个针对Groovy编程语言的软件开发工具包,它包含了Groovy语言的运行环境和开发所需的各种组件。Groovy是一种动态、灵活的面向对象编程语言,它与Java语法兼容,但提供了更简洁的语法和更强的...

    groovy-2.3.6-installer

    Groovy是一种动态、开源的编程语言,它是Java平台上的一个JVM(Java Virtual Machine)语言。Groovy结合了Python、Ruby和Perl等脚本语言的简洁性和灵活性,并且完全兼容Java,可以无缝地与Java代码集成。在"groovy-...

    Groovy Script 入门

    1. **创建Groovy文件**:使用文本编辑器创建一个名为hello.groovy的文件,并输入以上代码。 2. **执行脚本**:打开命令行窗口,导航至包含hello.groovy文件的目录,然后输入`groovy hello`来运行脚本。 #### 四、...

    groovy 1.5.5 API

    7. **元对象协议(Meta-Object Protocol, MOP)**:Groovy的MOP是实现动态行为的关键,它允许在运行时扩展和修改类的行为。通过MOP,开发者可以实现动态方法、属性和操作。 8. **类别(Category)**:类别是一种...

    Groovy入门教程[参照].pdf

    Groovy 是一种基于 Java 语言的脚本语言,运行在 JVM 中,语法与 Java 相似,但抛弃了 Java 的一些烦琐的语法规则,提供了更加简洁和灵活的编程体验。 Groovy 的特点 1. 简洁的语法:Groovy 语法简洁,减少了代码...

    groovy入门经典,groovyeclipse 插件

    Groovy是一种动态、灵活的编程语言,它是Java平台上的一个扩展,可以无缝集成到Java项目中。Groovy的语法简洁,支持面向对象编程、函数式编程,并提供了许多现代语言特性,如闭包和动态类型。这使得Groovy成为快速...

    Groovy入门教程

    1. 在`groovy`目录下右键新建Groovy类(New -> Other -> Groovy -> Groovy Class)。 2. 编辑Groovy类,例如创建一个简单的“Hello World”程序: ```groovy public class HelloWorld { public static void main...

    groovy

    Groovy是一种基于Java平台的、动态的、强大的编程语言,它设计的目标是增强开发者的生产力。Groovy结合了Java的静态类型系统和Python、Ruby等动态语言的灵活性,使得开发者可以更加高效地编写代码。本篇文章将深入...

    Groovy 介绍 官网资源

    #### 一、Groovy简介 Groovy是一种灵活的、面向对象的编程语言,主要用于Java虚拟机(JVM)。它兼容现有的Java代码,并且能够直接调用Java类库,这使得Groovy成为扩展Java应用程序的理想选择。Groovy语言的设计灵感...

    经典Groovy入门资料

    这对于习惯于Java编程的人来说是一个很好的起点,能够快速上手并开始探索Groovy的更多特性。 总结起来,从Groovy的安装到基本使用,再到从Java到Groovy的转变,这些步骤为初学者提供了一个平滑的学习曲线,帮助他们...

    groovy-all

    Groovy是一种动态、开源的编程语言,它是Java平台上的一个重要的补充。Groovy结合了Python、Ruby和Smalltalk等语言的特性,同时保留了与Java的无缝集成能力,使得它在脚本编写、Web开发、自动化测试等领域有着广泛的...

    groovy_demo

    - **元对象协议(MOP)**:Groovy的元对象协议允许在运行时扩展对象的行为。 - **类别(Category)**:类别可以为任何类添加方法,提供一种便捷的扩展机制。 4. **Groovy的脚本支持**: - **脚本执行**:Groovy...

    groovy-3.0.7.msi

    groovy

Global site tag (gtag.js) - Google Analytics