- 前言
再来补充一个CGLIB的动态代理, JDK动态代理必须提供接口才能使用, 在一些不能提供接口的环境中, 只能采用其他第三方技术, 比如CGLIB。它的优势在于不需要提供接口, 只要一个非抽象类就能实现动态代理。
- 包结构
- 代码实现
Hello.java
package proxy.cg;
public class Hello {
public void sayHello(String name)
{
System.out.println("Hello: " + name);
}
}
CglibProxyExample.java
package proxy.cg;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxyExample implements MethodInterceptor {
/**
* 生成 CGLIB 代理对象
* @param cls -- Class 类
* @return Class 类的 CGLIB 代理对象
*/
public Object getProxy(Class cls)
{
// CGLIB enhancer 增强类对象
Enhancer enhancer = new Enhancer();
// 设置增强类型
enhancer.setSuperclass(cls);
// 定义代理逻辑对象为当前对象, 要求当前对象实现 intercept 方法
enhancer.setCallback(this);
// 生成并返回代理对象
return enhancer.create();
}
/**
* 代理逻辑方法
* @param o 代理对象
* @param method 方法
* @param args 方法参数
* @param methodProxy 方法代理
* @return 代理逻辑返回
* @throws Throwable 异常
*/
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("调用真实对象前");
// CGLIB 反射调用真实对象方法
Object result = methodProxy.invokeSuper(o, args);
System.out.println("调用真实对象后");
return result;
}
}
这里使用了CGLIB的加强者 Enhancer, 通过设置超类(个人理解超类就是父类)的方法(setSuperclass), 然后通过 setCallback 方法设置那个类为它的代理类。 其中, 参数为 this 就意味着是当前对象, 实现 intercept 方法, 然后返回对象。
Test.java
package proxy.cg;
import net.sf.cglib.proxy.Enhancer;
public class Test {
public static void main(String[] args)
{
Enhancer enhancer = new Enhancer();
CglibProxyExample cg = new CglibProxyExample();
Hello hello = (Hello) cg.getProxy(Hello.class);
hello.sayHello("你好");
}
}
- 程序运行效果
- 总结
不难发现JDK 的动态代理与 CGLIB 是很相似的, 它们都是通过 getProxy() 方法生成代理对象, 制定代理的逻辑类。 而代理逻辑类要实现一个接口的一个方法, 这个接口定义的方法就是代理对象的逻辑方法, 它可以控制真实对象的方法, skr~。