这里仅介绍JDK动态代理和Cglib
JDK动态代理:
public interface IPerson {
void findLove();
}
public class Zhangsan implements IPerson {
public void findLove() {
System.out.println("张三要求:肤白貌美大长腿");
}
}
public class ZhaoLiu implements IPerson {
public void findLove() {
System.out.println("赵六要求:有车有房学历高");
}
}
//下面是实现一个JDK版本的动态代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkMeipo implements InvocationHandler {
private IPerson target;//动态代理之所以是动态,是不管目标对象是啥,都可以代理,静态代理只能代理指定对象,只能硬编码实现。
public IPerson getInstance(IPerson target){
this.target = target;
Class<?> clazz = target.getClass();
//下面这个方法是JDK动态代理的核心方法
return (IPerson) Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object result = method.invoke(this.target,args);
after();
return result;
}
private void after() {
System.out.println("双方同意,开始交往");
}
private void before() {
System.out.println("我是媒婆,已经收集到你的需求,开始物色");
}
}
//测试
public class Test {
public static void main(String[] args) {
JdkMeipo jdkMeipo = new JdkMeipo();
IPerson zhangsan = jdkMeipo.getInstance(new Zhangsan());
zhangsan.findLove();
IPerson zhaoliu = jdkMeipo.getInstance(new ZhaoLiu());
zhaoliu.findLove();
}
}
Cglib动态代理:
public class Zhangsan{
public void findLove() {
System.out.println("张三要求:肤白貌美大长腿");
}
}
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CGlibMeipo implements MethodInterceptor {
public Object getInstance(Class<?> clazz) throws Exception{
//相当于Proxy,代理的工具类
//这里是继承写法,直接是继承出了一个新的类。
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
before();
Object obj = methodProxy.invokeSuper(o,objects);
after();
return obj;
}
private void before(){
System.out.println("我是媒婆,我要给你找对象,现在已经确认你的需求");
System.out.println("开始物色");
}
private void after(){
System.out.println("OK的话,准备办事");
}
}
//测试
public class Test {
public static void main(String[] args) {
Customer obj = (Customer) new CGlibMeipo().getInstance(Customer.class);
System.out.println(obj);
obj.findLove();
}
}
JDK动态代理和Cglib动态代理的区别:
1),JDK动态代理实现了被代理对象的接口,Cglib代理继承了被代理对象。
2),JDK动态代理和Cglib动态代理都在运行期生成字节码,JDK动态代理直接写Class字节码,
Cglib代理使用ASM框架写Class字节码,Cglib的实现更复杂,所以生成代理类比JDK动态代理效率低。
3),JDK动态代理调用代理方法是通过反射机制调用的,Cglib代理是通过FastClass机制直接调用方法的。
Cglib采用了FastClass机制,它的原理很简单:为代理类和被代理类各生成一个类,这个类会为代理类或被代
理类的方法分配一个index(int类型);这个index当做一个入参,FastClass就可以直接定位要调用的方法
并直接调用,省去了反射调用,所以调用效率比JDK代理通过反射调用高。