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代理

posted @ 2023-02-22 17:29  平凡的人生不平凡的梦  阅读(255)  评论(0)    收藏  举报