JDK动态代理
利用反射,创建代理对象,从而实现对原目标对象的增强功能。
import java.lang.reflect.Proxy;
public class JDKProxy {
/**
* 目标接口
*/
static interface Drink{
void drink();
}
/**
* 目标对象
*/
static class Dog implements Drink{
@Override
public void drink() {
System.out.println("喝水...");
}
}
public static void main(String[] args) {
// 代理对象
Dog dogTarget = new Dog();
Drink o = (Drink) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), new Class[]{Drink.class}, (proxy, method, args1) -> {
// proxy代理对象本身
// method代理的方法
// args代理的参数
// 功能增强
System.out.println("增强的功能...");
// 原功能
return method.invoke(dogTarget, args1);
});
// 增强方法
o.drink();
}
}
缺点:对象需要实现接口,从而代理对象和原对象是平级的关系。
CGLIB动态代理
通过反射 + 继承代理对象类,实现对代理对象的方法增强。
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 CglibProxy {
/**
* 目标对象
*/
static class Drink {
void drink() {
System.out.println("喝水...");
}
}
public static void main(String[] args) {
Drink target = new Drink();
Drink o = (Drink) Enhancer.create(Drink.class, new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("增强功能...");
// return method.invoke(target, objects); // 这个利用的反射
return methodProxy.invokeSuper(o, objects); // 这个不是利用的反射
}
});
o.drink();
}
}
缺点:代理对象class类型不能是final的,增强的方法也不能是final的。
参考
“满级”架构师“满老师”带你扒框架源码--黑马程序员Spring视频教程,全面深度讲解spring5底层原理_哔哩哔哩_bilibili