在JDK动态代理中必须提供接口才能使用,在一些不用提供接口的环境中,只能采用第三方技术,比如CGLIB动态代理。它的优势在于不需要提供接口明知要一个非抽象类就可以实现动态代理,下面是一个小的例子:
非抽象类:
public class ReflectServiceImpl {
public void sayHello(String name) {
System.out.println("Hello"+name);
}
}
CGLIB动态代理代码
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
1. @desc CGLIB代理不需要提供接口,只要一个非抽象类就能实现代理
2. */
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);
//定义代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("调用真实对象之前");
//CGLIB反射调用真实对象的方法
Object res = methodProxy.invokeSuper(proxy, args);
System.out.println("调用真实对象之后");
return res;
}
}
说明: 列表内容这里用了CGLIB的加强者Enhancer,通过设置超类的方法(setSuperclass),然后通过setCallback方法设置哪个类
是它的代理类,其中,参数为this就意味着是当前对象,那就要求用this这个对象实现接口MethodIntercepter的方法--interceot,
然后返回代理对象。那么此时当前类的intercept方法就是其代理逻辑方法,其参数内容注释已做说明,CGLIB是通过这句代码完成的
Object res = methodProxy.invokeSuper(proxy, args);
测试类
public class TestCglibProxy {
public static void main(String[] args) {
CglibProxyExample cpe = new CglibProxyExample();
ReflectServiceImpl rsi = (ReflectServiceImpl)cpe.getProxy(ReflectServiceImpl.class);
rsi.sayHello("牛皮");
}
}
运行结果: