JDK中的动态代理是通过反射类Proxy以及InvocationHandler回调接口实现的,而CGlib不受必须实现接口类的限制,CGLib原理是动态生成被代理类的子类。
实现CGlib动态代理步骤:
- 新增一个类,实现类的方法(不实现任何接口)
public class DogImpl2
{
public void run(String dogType, float speed) {
System.out.println(dogType + " can run very fast! Can reach " + speed + " m/s");
}
public void eat(String dogType, String food) {
System.out.println(dogType + " likes to eat " + food);
}
}
2.定义Interceptor类,实现MethodInterceptor类的interceptor方法 (定义拦截器,实现代理逻辑)
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class DogInterceptor implements MethodInterceptor {
/*
* Object obj : 动态生成的代理类实例
* Method method : 上文中实体类所调用的被代理的方法引用
* Object[] args : 参数值列表
* MethodProxy proxy : 生成的代理类对方法的代理引用
*/
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
// before
System.out.println("在调用Dog接口的方法前,先做点儿别的。");
// 调用被代理类DogImpl2的方法
proxy.invokeSuper(obj, args);
// after
System.out.println("在调用Dog接口的方法后,处理下后续。");
return null;
}
}
3.调用(生成代理类,并调用)
import net.sf.cglib.proxy.Enhancer;
public class ProxyTest {
public static void main(String[] args) {
// invokation
Dog dog = new DogImpl();
DogInvokationHandler dogInvokationHandler = new DogInvokationHandler();
dog = (Dog) dogInvokationHandler.newProxy(dog,new Class[] {Dog.class});
dog.run("Gree dog", 70);
System.out.println("\n======================我是分界线======================\n");
// interceptor
DogImpl2 dogImpl = new DogImpl2();
// 定义interceptor对象
DogInterceptor dogInterceptor = new DogInterceptor();
// Enhancer:cglib的加强器,用于创建动态代理
Enhancer enhancer = new Enhancer();
// 设置要创建动态代理的类,将被代理类设置为父类
enhancer.setSuperclass(dogImpl.getClass());
// 设置回调(设置拦截器),对于代理类上的所有方法的调用,会调用callback
//callback会执行interceptor进行拦截
enhancer.setCallback(dogInterceptor);
// create动态生成代理类,并强转为父类
DogImpl2 proxy = (DogImpl2) enhancer.create();
proxy.run("博美犬", 5);
System.out.println("\n======================我是分界线======================\n");
proxy.eat("博美犬", "meat");
}
}
4.结果输出
在调用Dog接口的方法前,先做点儿别的。
Gree dog can run very fast! Can reach 70.0 m/s
在调用Dog接口的方法后,处理下后续。
======================我是分界线======================
在调用Dog接口的方法前,先做点儿别的。
博美犬 can run very fast! Can reach 5.0 m/s
在调用Dog接口的方法后,处理下后续。
======================我是分界线======================
在调用Dog接口的方法前,先做点儿别的。
博美犬 likes to eat meat
在调用Dog接口的方法后,处理下后续。