import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; //直接使用代理类的父类作为目标业务对象。 public class BusinessCglibProxy1 implements MethodInterceptor { private static BusinessCglibProxy1 interceptor = new BusinessCglibProxy1(); private BusinessCglibProxy1() {} //创建代理对象 public static Object getCglibProxy(Class<?> clazz) { //创建一个织入器 Enhancer enhancer = new Enhancer(); //设置父类 enhancer.setSuperclass(clazz); //设置需要织入的逻辑 enhancer.setCallback(interceptor); // 创建代理对象 //使用织入器创建子类 return enhancer.create(); } //由于CGLIB可以不需要实现接口来实现动态代理,其原理是通过字节码生成类的一个子类来完成的, //那就有可能出现需要动态代理对象不存在一个无参构造函数,那么CGLIB在生成子类并实例化时将会产生错误。 //创建带参数的代理对象 public static Object getCglibProxy(Class<?> clazz, Class<?>[] argClazz, Object[] args) { //创建一个织入器 Enhancer enhancer = new Enhancer(); //设置父类 enhancer.setSuperclass(clazz); // 设置需要织入的逻辑 enhancer.setCallback(interceptor); // 创建带参数的代理对象 //使用织入器创建子类 return enhancer.create(argClazz, args); } /** * obj:cglib动态生成的代理类实例,业务类的子类的实例 * method:业务类方法的引用 * args:调用参数数组 * proxy:代理类对业务类方法的代理引用,是业务类的方法的代理 */ @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { //obj 是cglib动态生成的代理实例,是BusinessImpl的子类的实例 System.out.println("Cglib动态代理类:" + obj.getClass().getName()); System.out.println("Before " + method.getName() + " .."); //proxy 这里是BusinessImpl的service方法Method的代理 //因为动态生成的业务类是子类或者是实现类,proxy.invokeSuper(Object obj, Object[] args) //调用的是代理类obj的父类BusinessImpl的service方法。 //那么proxy.invoke(Object obj, Object[] args)方法是做什么的,javadoc上说这个方法 //可以用于相同类中的其他对象的方法执行, //也就是说这个方法中的obj需要传入相同一个类的另一个对象,否则会进入无限递归循环。 //Object result = method.invoke(new BusinessImpl(), args); Object result = proxy.invokeSuper(obj, args); System.out.println("End "+ method.getName() + " .."); return result; } public static void main(String[] args) { BusinessImpl proxy = (BusinessImpl) BusinessCglibProxy1.getCglibProxy(BusinessImpl.class); proxy.service(); //带参数的业务类 BusinessImpl proxy1 = (BusinessImpl) BusinessCglibProxy1.getCglibProxy(BusinessImpl.class, new Class[] {String.class}, new Object[] {"jaesonchen"}); proxy1.service(); } }
* CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生成的代理对象是针对目标类扩展的
子类。
* CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操作字节码实现的,
性能比JDK强。
* CGLIB是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,
但因为采用的是继承,所以不能对final修饰的方法进行代理。
* CGLib采用非常底层的字节码技术,可以为一个类创建一个子类,并在子类中采用方法拦截的技术拦截
所有父类方法的调用,并顺势植入横切逻辑。
* 在我们实际开发当中,在使用动态代理进行方法请求拦截时,可能会需要判断调用的方法然后决定拦截
的逻辑,也就是同一个代理类在调用不同的方法时拦截的逻辑都不相同,CGLIB提供了CallbackFilter
来帮助我们实现这一功能。
输出为:
Cglib动态代理类:com.jaeson.BusinessImpl$$EnhancerByCGLIB$$981aa2a6
Before service ..
service.id = default
End service ..
Cglib动态代理类:com.jaeson.BusinessImpl$$EnhancerByCGLIB$$981aa2a6
Before service ..
service.id = jaesonchen
End service ..
相关推荐
CGlib动态代理的工作原理是通过继承被代理的目标类来创建子类,然后在子类中覆盖父类的方法,当调用这些方法时,会插入自定义的逻辑。与JDK的动态代理不同,JDK代理基于接口,如果目标类没有实现接口,就无法使用JDK...
CGlib则是Java动态代理的一种实现方式,尤其是在不提供接口的情况下,它通过生成目标类的子类来实现动态代理。 在Java中,JDK自带的动态代理机制是基于接口的,如果被代理的类没有实现任何接口,那么就无法使用JDK...
CGLIB是一个基于ASM的字节码生成库,它允许我们在运行时对字节码进行修改和动态生成。...CGLIB体现的是继承思想,所以我们需要把代理类作为我们目标类的一个子类,也就是把目标类设置为父类,代理类去继承它。
Spring AOP模块使用了CGlib作为其默认的代理机制,当目标对象没有实现接口时,Spring会自动选择CGlib进行动态代理。通过AOP,开发者可以在不修改原有代码的情况下,添加额外的功能或行为,如日志、事务控制等。...
JDK动态代理基于Java的接口实现,它要求被代理的目标对象必须实现至少一个接口。Java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口是实现JDK动态代理的关键。Proxy类提供了一个静态方法`...
总结起来,JDK动态代理适用于目标对象实现了接口的情况,而CGLIB代理则可以在没有接口的情况下进行代理。两者都可以实现运行时的代理,但适用场景不同,开发者可以根据具体需求选择适合的代理方式。在实际开发中,...
CGLib 使用字节码技术创建代理类,它比基于接口的 Java 动态代理更加灵活,因为可以代理任何非 final 类。 以下是使用 CGLib 创建动态代理的基本步骤: 1. 引入 CGLib 库。 2. 创建一个 `Enhancer` 对象,它是 ...
你可以通过`Enhancer`设置回调函数、目标对象、父类等,然后调用`enhance()`方法生成代理对象。 2. **Callback**:CGLib提供了一系列的回调接口,如`MethodInterceptor`,它允许你在代理对象的方法被调用时执行...
在Java开发中,CGLIB经常被用作AOP(面向切面编程)的底层实现,例如Spring框架就使用了CGLIB来实现对目标类的动态代理。 CGLIB是通过字节码技术来实现动态代理的。当我们的应用程序需要动态地创建一个类的实例或者...
1. **动态代理**:当无法或者不希望实现接口时,CGLib可以通过生成目标类的子类来实现动态代理,这在AOP框架中非常常见,如Spring AOP。 2. **性能提升**:在某些情况下,使用子类代理比使用接口代理(如JDK的Proxy...
使用CGLIB扩展对象行为的原理是:对目标对象进行继承扩展,为其生成相应的子类,而子类可以通过覆写来扩展父类的行为,只要将横切逻辑的实现放到子类中,然后让系统使用扩展后的目标对象的子类,就可以达到与代理...
1. **AOP编程**: 在Spring框架中,如果目标类没有实现接口,Spring就会使用CGlib来创建代理对象,以便在方法调用前后插入切面逻辑。 2. **性能优化**: 通过动态生成字节码,CGlib可以创建比反射更快的对象实例,这...
Cglib子类代理是Java动态代理的一种实现方式,它主要通过字节码技术在运行时动态创建一个目标对象的子类,以此来实现代理功能。Cglib是一个强大的高性能的代码生成库,它在许多AOP(面向切面编程)框架中被广泛应用...
在Spring框架中,CGLib被用作AOP代理的一个重要组件,特别是在没有实现接口的类上创建代理对象时,Spring会默认使用CGLib。 CGLib的工作原理是基于ASM库,ASM是一个字节码操作和分析框架,它可以用来动态生成类或...
如果目标类是final的,或者包含final方法,CGLIB则无法生成子类,这时它会退化到使用基于方法的代理,即通过动态生成实现所有接口的代理类来实现。 2. **CGLIB使用**: - 首先,你需要在项目中引入CGLIB的jar包。...
在Java中,动态代理是一种在运行时创建代理类的能力,代理类可以代替原始的目标对象执行某些额外的操作。JDK提供了java.lang.reflect.Proxy类来实现基于接口的动态代理,但若目标对象不实现接口,JDK的动态代理就...
要进行模拟,首先需要了解CGLIB代理的核心实现原理,包括代理类的生成、方法拦截和回调机制等。 1. 代理类的生成 CGLIB使用Enhancer类来生成代理对象。Enhancer的工作原理是对指定的目标类进行字节码增强,并创建该...
当JDK的动态代理(java.lang.reflect.Proxy)无法满足需求,例如目标类没有实现接口时,CGLIB就能派上用场。它通过字节码技术生成一个目标类的子类,并在这个子类中拦截方法调用,实现AOP(面向切面编程)的代理功能...
Spring AOP 默认代理策略是:如果目标对象实现了接口,则使用 jdk 动态代理,否则使用 cglib 代理。在 jdk8 之后,jdk 动态代理效率要高于 cglib 代理。 代理模式的优点是: * 可以在不改变原有目标对象的基础上,...