Proxy Pattern
代理模式:强调隐藏目标对象;如果需改修改已有的方法,可以通过代理的方式来扩展该方法
例如需要增强A类/对象的create()方法
public class A implements Itf{
public void create(){...}
}
1.静态代理:代理对象和被代理对象实现相同接口或继承相同父类
public class AProxy implements Itf{
private Itf objectA;
AProxy(Itf objectA){
this.objectA=objectA;}
public void create(){
//do other things
objectA.create();}
}
使用:
相比new A().create() 以下用法能增强create()方法
A a=new A();
AProxy aProxy=new AProxy(a);
aProxy.create();
2.动态代理(JDK代理/接口代理):动态的生成代理接口及其实现类,被代理/目标对象所属类一定要实现接口
2.1反射写法,本质就是反射调用方法并在此期间增强
Itf a=new A();
Method method=A.class.getMethod("create");
//do other things
method.invoke(a);
2.2JDK代理
Itf a=new A();
Object aProxy=Proxy.newProxyInstance(A.class.getClassLoader(),A.class.getInterfaces(),new InvocationHandler(){
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
//do other things
method.invoke(a);//如果Itf有多个实现类,则被增强的方法就是这里的实现类对象a的方法
}
});//获得a的代理对象
((Itf)aProxy).create();
jdk代理的实现原理:
https://cloud.tencent.com/developer/article/1336135#:~:text=%E9%A6%96%E5%85%88%E6%88%91%E4%BB%AC%E5%85%88%E6%9D%A5%E8%AE%B2%E4%B8%80%E4%B8%8BJDK%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%E7%9A%84%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86%201.%E6%8B%BF%E5%88%B0%E8%A2%AB%E4%BB%A3%E7%90%86%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%BC%95%E7%94%A8%EF%BC%8C%E7%84%B6%E5%90%8E%E8%8E%B7%E5%8F%96%E4%BB%96%E7%9A%84%E6%8E%A5%E5%8F%A3%202.JDK%E4%BB%A3%E7%90%86%E9%87%8D%E6%96%B0%E7%94%9F%E6%88%90%E4%B8%80%E4%B8%AA%E7%B1%BB%EF%BC%8C%E5%90%8C%E6%97%B6%E5%AE%9E%E7%8E%B0%E6%88%91%E4%BB%AC%E7%BB%99%E7%9A%84%E4%BB%A3%E7%90%86%E5%AF%B9%E8%B1%A1%E6%89%80%E5%AE%9E%E7%8E%B0%E7%9A%84%E6%8E%A5%E5%8F%A3,3.%E6%8A%8A%E8%A2%AB%E4%BB%A3%E7%90%86%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%BC%95%E7%94%A8%E6%8B%BF%E5%88%B0%E4%BA%86%204.%E9%87%8D%E6%96%B0%E5%8A%A8%E6%80%81%E7%94%9F%E6%88%90%E4%B8%80%E4%B8%AAclass%E5%AD%97%E8%8A%82%E7%A0%81%205.%E7%84%B6%E5%90%8E%E7%BC%96%E8%AF%91
3.Cglib代理(子类代理):动态生成用于代理的子类,所以被代理/目标对象所属类不能是final修饰,底层使用字节码构造子类(ASM)
A a=new A();
Enhancer enhancer=new Enhancer();
enhancer.setClassLoader(A.class.getClassLoader());
enhancer.setSuperclass(A.class);
enhancer.setCallback(new MethodInterceptor(){
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//do other things
method.invoke(a);}});
Object aProxy=enhancer.create();
((A)aProxy).create();
在spring AOP中
如果目标对象有实现接口,用JDK代理
如果目标对象没有实现接口,用Cglib代理
浙公网安备 33010602011771号