使用CGLIB enhancer实现类的增强

mac2024-05-19  28

今天在读spring源码的时候,比较深入如的研究了一下@Configuration注解。发现@Configurtion注解的类,实际实现了CGLIB动态代理,这个后续会写一篇博客专门说明。这里简单的记录下CGLIB动态代理的使用。

 一、使用CGLIB代理需要注意的问题

如果类是抽象类,只能调用已实现方法方法,如果调用抽象方法的时候会报java.lang.AbstractMethodError。 要增强的类不能是final类,否则会报java.lang.IllegalArgumentException: Cannot subclass final class。 不能增强类的private方法,否则无法通过编译。

 

二、代码测试

我使用的spring的CGLIB,用法上和普通的CGLIB大同小异。

目标类,即需要增强的类。

package com.evan.service; public class Car { public void driveCar(){ System.out.println("汽车正在行驶..."); } }

 实现MethodInterceptor接口。

package com.evan.interceptor; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class MyMethodInterceptor implements MethodInterceptor { public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { //输出Object o的类类型. System.out.println(o.getClass()); //得到调用方法名称. System.out.println(method.getName()); //得到被代理类(父类)的方法的名称. System.out.println(methodProxy.getSuperName()); System.out.println("汽车打火,开始启动..."); Object returnValue = methodProxy.invokeSuper(o, null); System.out.println("汽车熄火,停车..."); return returnValue; } }

 测试类:

package com.evan.test; import com.evan.interceptor.MyMethodInterceptor; import com.evan.service.Car; import org.springframework.cglib.proxy.Enhancer; public class EnhancerTest { public static void main(String[] args) { Enhancer enhancer=new Enhancer(); //设置要通过enhancer创建的代理类的 父类 类型。 enhancer.setSuperclass(Car.class); enhancer.setCallback(new MyMethodInterceptor()); //通过enhancer去创建一个类,实际上我们是看不到的。 Car car = (Car)enhancer.create(); car.driveCar(); } }

运行结果:

class com.evan.service.Car$$EnhancerByCGLIB$$bd90a6bb driveCar CGLIB$driveCar$0 汽车打火,开始启动... 汽车正在行驶... 汽车熄火,停车...

 

最新回复(0)