JDK自从1.3版本开始,就引入了动态代理,JDK的动态代理用起来非常简单,但是它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口的类可以使用CGLIB包。
CGLIB是一个强大的高性能的代码生成包。它被许多AOP的框架(例如Spring AOP)使用,为他们提供方法的interception(拦截)。Hibernate也使用CGLIB来代理单端single-ended(多对一和一对一)关联。EasyMock通过使用模仿(moke)对象来测试java代码的包。它们都通过使用CGLIB来为那些没有接口的类创建模仿(moke)对象。
CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。
下面的图显示了和CGLIB包和一些框架和语言的关系。
Spring AOP和Hibernate同时使用JDK的动态代理和CGLIB包。Spring AOP,如果不强制使用CGLIB包,默认情况是使用JDK的动态代理来代理接口。
CGLIB包对代理那些没有实现接口的类非常有用。它是通过动态的生成一个子类去覆盖所要代理类的不是final的方法,并设置好callback,则原有类的每个方法调用就会转变成调用用户定义的拦截方法(interceptors)。
net.sf.cglib.proxy.Callback接口在CGLIB包中是一个很关键的接口,所有被net.sf.cglib.proxy.Enhancer类调用的回调(callback)接口都要继承这个接口。 用net.sf.cglib.proxy.MethodInterceptor接口是最通用的回调(callback)类型,它经常被基于代理的AOP用来实现拦截(intercept)方法的调用。
net.sf.cglib.proxy.MethodInterceptor能够满足任何的拦截(interception )需要,但是某些特殊情况下可能使用过度。为了简化和提高性能,CGLIB包提供了一些专门的回调(callback)类型。例如:
net.sf.cglib.proxy.FixedValue 为提高性能,FixedValue回调对强制某一特别方法返回固定值是有用的。
net.sf.cglib.proxy.NoOp NoOp回调把对方法调用直接委派到这个方法在父类中的实现。
net.sf.cglib.proxy.LazyLoader 当实际的对象需要延迟装载时,可以使用LazyLoader回调。一旦实际对象被装载,它将被每一个调用代理对象的方法使用。
net.sf.cglib.proxy.Dispatcher 和LazyLoader不同的是,当代理方法被调用时,装载对象的方法也总要被调用。
net.sf.cglib.proxy.ProxyRefDispatcher 和Dispatcher不同的是,它可以把代理对象作为装载对象方法的一个参数传递。
为了更好的使用代理,我们可以使用自己定义的MethodInterceptor类型回调(callback)来代替net.sf.cglib.proxy.NoOp回调。当对代理中所有方法的调用时,都会转向MethodInterceptor类型的拦截(intercept)方法,在拦截方法中再调用底层对象相应的方法。
例一:
public class MyClass {
public void method() {
System.out.println("MyClass.method()");
}
}
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodProxy;
import net.sf.cglib.proxy.MethodInterceptor;
public class Test {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MyClass.class);
enhancer.setCallback( new MethodInterceptorImpl() );
MyClass my = (MyClass)enhancer.create();
my.method();
}
private static class MethodInterceptorImpl implements MethodInterceptor {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println(method);
proxy.invokeSuper(obj, args);
return null;
}
}
}
相关推荐
在Java开发中,动态代理和CGLIB代理是两种常见的面向切面编程(AOP)实现方式,它们都用于在不修改原有代码的情况下,增强或扩展对象的功能。本篇文章将深入探讨JDK动态代理和CGLIB代理的区别,以及它们在实际应用中...
下面我们将详细讲解Cglib代理的工作原理以及如何在实际项目中使用。 1. **Cglib代理原理**: - Cglib通过ASM库动态生成一个子类,这个子类继承自目标类,并重写其中的方法。 - 在生成的子类中,每个被代理的方法...
这个实例将深入探讨如何利用Spring来创建和管理定时任务,并结合动态代理技术来增强功能。我们将从以下几个方面进行讲解: 1. **Spring定时任务基础** - **Spring Task**:Spring Task是Spring框架中的一个模块,...
Spring AOP提供了两种主要的代理方式:JDK动态代理和CGLIB代理。前者要求目标对象实现至少一个接口,而后者则通过继承目标类来创建代理。Spring会根据目标对象是否实现接口自动选择合适的代理方式。 1. JDK动态代理...
- `Java动态代理模式.docx`可能详细讲解了动态代理模式的原理和实现,包括如何创建代理对象和实现`InvocationHandler`。 - `动态代理详解.docx`则可能深入讨论了Java动态代理的细节,包括实际应用场景和常见问题。...
在Java中,有两种实现动态代理的方式:`java.lang.reflect.Proxy`类和`java.util.function.InvocationHandler`接口,以及JDK动态代理;另一种是基于CGLIB或ASM等第三方库的字节码操作,实现类级别的代理。 1. JDK...
- 在Spring AOP中,有两种动态代理方式:JDK动态代理和CGLIB代理。JDK代理适用于目标对象实现了一个或多个接口的情况,而CGLIB代理则在目标对象没有接口或者接口数量多且复杂时使用。 - Spring会根据目标对象是否...
在Java中,有两种主要的动态代理实现方式:JDK动态代理和CGLIB动态代理。JDK动态代理基于接口实现,它要求被代理的对象必须实现至少一个接口;而CGLIB则是通过字节码技术生成一个类的子类来实现代理,因此即使目标类...
在Java中,有两种主要的动态代理实现方式:JDK动态代理和CGLIB动态代理。本讲解主要聚焦于JDK动态代理。 JDK动态代理是通过java.lang.reflect包中的Proxy和InvocationHandler两个类来实现的。Proxy类提供了创建动态...
在Spring中,CGLIB用于为那些没有实现接口的类创建动态代理。当Spring管理的bean需要被代理以实现AOP功能,如事务管理、性能监控等,但该bean又没有实现任何接口时,CGLIB就会派上用场。CGLIB通过字节码技术生成一个...
这种方法尤其适合于那些已经定义了清晰接口的服务,而对那些没有接口或者接口不完善的类,Spring提供了CGLIB代理作为替代方案。通过灵活运用这些技术,我们可以极大地提高代码的可维护性和可扩展性。
AOP的核心是代理,Spring提供了两种代理方式:JDK动态代理和CGLIB代理。JDK动态代理基于接口,当目标对象实现了接口时使用;而CGLIB代理则是在运行时动态创建目标类的子类,适用于未实现接口的目标对象。 拦截器...
4. **接口代理**:如果我们的目标类实现了接口,我们可以使用JDK动态代理创建代理实例。`Proxy.newProxyInstance()`方法接受一个类加载器、接口数组和一个`InvocationHandler`,在调用代理对象的方法时,实际调用的...
课程中会详细讲解CGLib的实现,包括`Enhancer`类的使用和`MethodInterceptor`的`intercept`方法,这是CGLib代理逻辑执行的关键。 3. **Spring AOP核心类解析**: - `AopNamespaceHandler`负责处理AOP相关的XML命名...
3. **CGLIB代理**:当被代理的对象没有实现接口时,JDK的动态代理无法工作。这时可以使用第三方库如CGLIB(Code Generation Library)。CGLIB是一个强大的高性能的代码生成库,它能在运行期扩展Java类与实现Java接口...
4. JDK动态代理和CGLIB动态代理:在Spring框架中,AOP代理可以是JDK动态代理或CGLIB代理。JDK动态代理基于接口,只能代理实现了接口的类。CGLIB代理通过继承的方式实现代理,可以代理没有实现接口的类。Spring会自动...
Spring框架默认使用Java动态代理机制创建代理对象,为接口方法提供代理。如果被代理的类不是接口,则自动切换为使用CGLIB进行代理。 在实现原理中,提供了在认证接口调用时记录操作次数和判断操作有效性的使用场景...
有两种类型的代理:JDK动态代理和CGLIB代理。JDK代理用于实现了接口的目标对象,而CGLIB代理则用于没有接口或需要额外功能(如方法覆盖)的情况。 6. **实战应用**:在实际项目中,我们可能会创建一个名为`...
2. **Spring AOP简介**:讲解Spring框架如何提供AOP支持,包括基于代理的AOP(JDK动态代理和CGLIB代理)和基于注解的AOP。 3. **创建切面**:演示如何定义一个切面类,该类包含通知方法,这些方法将在特定的连接点...
Spring AOP支持两种动态代理技术:JDK动态代理和CGLIB代理。 JDK动态代理是Java自带的动态代理实现,它要求被代理的对象必须实现一个接口。代理类和被代理类都实现了相同的接口,然后通过Java反射机制中的Proxy类和...