`

实战CGLib系列之proxy篇(一):方法拦截MethodInterceptor

 
阅读更多

本系列文章均整理自我在先前一家公司的CGLib使用总结和笔记。分享出来,希望对看到的人有所帮助,同时欢迎大家提出宝贵意见大笑。如需转载,请勿修改,且注明作者shensy及出处。

--------------------------------------

实战CGLib系列文章

本篇介绍通过MethodInterceptor和Enhancer实现一个动态代理。

一、首先说一下JDK中的动态代理

JDK中的动态代理是通过反射类Proxy以及InvocationHandler回调接口实现的,不了解的同学请参考我的这篇Blog:Java动态代理详解 http://shensy.iteye.com/blog/1698197 

但是,JDK中所要进行动态代理的类必须要实现一个接口,也就是说只能对该类所实现接口中定义的方法进行代理,这在实际编程中具有一定的局限性,而且使用反射的效率也并不是很高。

二、使用CGLib实现

使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。

下面,将通过一个实例介绍使用CGLib实现动态代理。

1、被代理类

首先,定义一个类,该类没有实现任何接口,包含两个方法。

public class ConcreteClassNoInterface {
	public String getConcreteMethodA(String str){
		System.out.println("ConcreteMethod A ... "+str);
		return str;
	}
	public int getConcreteMethodB(int n){
		System.out.println("ConcreteMethod B ... "+n);
		return n+10;
	}
}

2、拦截器

定义一个拦截器。在调用目标方法时,CGLib会回调MethodInterceptor接口方法拦截,来实现你自己的代理逻辑,类似于JDK中的InvocationHandler接口。

public class ConcreteClassInterceptor implements MethodInterceptor{
	public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable {
		System.out.println("Before:"+method);  
		Object object=proxy.invokeSuper(obj, arg);
		System.out.println("After:"+method); 
		return object;
	}
}

参数:Object为由CGLib动态生成的代理类实例,Method为上文中实体类所调用的被代理的方法引用,Object[]为参数值列表,MethodProxy为生成的代理类对方法的代理引用。

返回:从代理实例的方法调用返回的值。

其中,proxy.invokeSuper(obj,arg):

调用代理类实例上的proxy方法的父类方法(即实体类ConcreteClassNoInterface中对应的方法)

在这个示例中,只在调用被代理类方法前后各打印了一句话,当然实际编程中可以是其它复杂逻辑。

3、生成动态代理类

Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(ConcreteClassNoInterface.class);
enhancer.setCallback(new ConcreteClassInterceptor());
ConcreteClassNoInterface ccni=(ConcreteClassNoInterface)enhancer.create();

这里Enhancer类是CGLib中的一个字节码增强器,它可以方便的对你想要处理的类进行扩展,以后会经常看到它。

首先将被代理类ConcreteClassNoInterface设置成父类,然后设置拦截器ConcreteClassInterceptor,最后执行enhancer.create()动态生成一个代理类,并从Object强制转型成父类型ConcreteClassNoInterface。

最后,在代理类上调用方法:

ccni.getConcreteMethodA("shensy");
ccni.getConcreteMethodB(0);

查看控制台输出:

Before :public java.lang.String generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodA(java.lang.String)
ConcreteMethod A ... shensy
After :public java.lang.String generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodA(java.lang.String)
Before :public int generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodB(int)
ConcreteMethod B ... 0
After :public int generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodB(int)

可以看到,拦截器在调用被代理类方法前后都执行了print操作。

 

结束语

以上就是CGLib实现动态代理的一个示例,本系列后面将继续介绍CGLib的强大功能,敬请期待。

 

分享到:
评论
1 楼 小胖vs小猪 2017-05-16  
能说明一下jar包的引用情况么。

相关推荐

    cglib的动态代理需要的包

    2. `net.sf.cglib.proxy.MethodInterceptor`: 这是CGlib中用于拦截方法调用的关键接口。你需要实现这个接口,定义`intercept`方法,该方法会在代理对象调用目标方法之前和之后执行。 3. `...

    Spring cglib 中文说明

    - **net.sf.cglib.proxy.MethodInterceptor:** 最常用的回调类型,用于实现方法的拦截。它定义了一个方法: - `public Object intercept(Object object, java.lang.reflect.Method method, Object[] args, ...

    使用CGLIB模拟spring的拦截器

    而拦截器则是Spring框架中的一个重要概念,它允许我们在方法执行前后进行一些额外的操作,比如日志记录、性能监控、事务管理等。在本教程中,我们将深入探讨如何使用CGLIB库来模拟Spring的拦截器功能。 CGLIB(Code...

    CGLIB demo

    3. **MethodInterceptor**:这是CGLIB中最重要的拦截器接口,它有一个invoke方法,该方法会在目标方法执行前、后被调用,从而实现方法的拦截。 4. **Enhancer.create()**:使用Enhancer创建代理对象的关键方法。它...

    简单实现Cglib子类代理

    但大部分情况下,我们可以通过Cglib来为一个类创建子类,并在子类中拦截方法调用,添加额外的行为。 下面我们将详细讲解Cglib代理的工作原理以及如何在实际项目中使用。 1. **Cglib代理原理**: - Cglib通过ASM库...

    动态代理cglibjar包和源码

    - `net.sf.cglib.proxy.MethodInterceptor`接口定义了拦截器的方法,它的`intercept()`方法会在每次目标方法调用前被调用,我们可以在这里插入额外的业务逻辑。 - `net.sf.cglib.proxy.MethodProxy`是CGLIB用来...

    cglibjar包

    2. **方法拦截器**:CGLib使用Enhancer类来创建代理对象,可以为这些代理对象指定MethodInterceptor。当调用代理对象的方法时,实际会执行拦截器中的intercept()方法,允许开发者在方法调用前后添加自定义逻辑。 3....

    Cglib所需要的jar包

    在Java中,动态代理主要有两种方式:一是通过Java的反射API实现,二是通过第三方库如Cglib。本篇将深入探讨Cglib动态代理所需的jar包,以及它们在实际开发中的应用。 Cglib的核心jar包是`cglib-2.2.2.jar`,这是...

    cglib-nodep

    当不支持接口的类需要被代理时,Spring会使用CGlib动态创建一个目标类的子类,并在子类的方法上插入拦截代码,从而实现切面逻辑。 2. **动态代理**: 对于没有实现接口的类,JDK的java.lang.reflect.Proxy无法直接...

    Jdk动态代理和cglib动态代理原理

    `Enhancer`是增强对象的主要工具,`Callback`是一系列回调接口的基类,`MethodInterceptor`实现了具体拦截逻辑。 2. **创建代理对象**:使用`Enhancer`类,设置回调接口`MethodInterceptor`,并指定被代理的目标...

    JavaEE CGLIB字节码增强方式实现AOP编程

    1. MethodInterceptor:最常用的接口,实现这个接口的类可以拦截并处理方法调用。 2. FixedValue:返回固定值,无论目标方法如何。 3. NoOp:不做任何处理,直接调用目标方法。 **AOP切面的实现**: 在CGLIB中,...

    cglib3.1-3.3.0.rar

    这一特性使得CGlib在处理动态代理时尤其高效,特别是在Spring AOP框架中,CGlib被用来创建目标对象的代理,实现方法拦截。 CGlib的核心组件包括以下几个方面: 1. **Enhancer**:这是CGlib的主要入口点,用于创建...

    转载:cglib动态代理介绍(一)

    CGlib通过Callback接口来实现这一功能,最常见的Callback类型是MethodInterceptor,它允许我们在目标方法调用前后插入自定义逻辑。 ```java enhancer.setCallback(new MethodInterceptor() { @Override public ...

    cglib_2.2.2 动态代理jar包(包含asm_3.3.1)

    - 在生成的子类中,CGLIB会添加一个`MethodInterceptor`接口的实现,这个接口定义了`intercept`方法,该方法会在目标方法执行前、后以及异常处理时被调用,从而实现拦截逻辑。 2. **如何使用CGLIB**: - 首先,...

    CGLIB代理例子

    2. **MethodInterceptor**:这是CGLIB中定义的接口,它只有一个方法`intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable;`。当被代理的方法被调用时,CGLIB会自动调用这个...

    cglib实现动态代理依赖jar包

    CGLib会为目标类创建一个子类,并在子类中拦截父类的方法调用。这个过程包括以下步骤: 1. **生成子类字节码**:根据目标类的信息,CGLib使用ASM生成子类的字节码。 2. **加载子类**:将生成的字节码转换为Class对象...

    JDK代理和Cglib代理

    2. **MethodInterceptor接口**:类似于JDK的InvocationHandler,MethodInterceptor定义了一个`intercept()`方法,当调用代理对象的方法时会被执行。 使用Cglib代理的基本步骤如下: 1. 引入Cglib库。 2. 创建一个...

    cglib动态代理相关包

    3. MethodInterceptor:用于拦截和处理方法调用,实现intercept()方法可以自定义代理逻辑。 4. CallbackFilter:可以根据方法名或参数类型过滤需要拦截的方法。 5. MethodProxy:代理类,提供对原方法的访问。 总的...

    cglib包,源代码等

    **CGLIB(Code Generation Library)** 是一个强大的高性能的代码生成库,它可以在运行期扩展Java类与实现Java接口。CGLIB是基于ASM这个底层字节码操作框架来实现的,它广泛用于许多开源项目,特别是Spring框架中,...

Global site tag (gtag.js) - Google Analytics