欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring07_代理模式

程序员文章站 2022-05-08 12:46:19
...

静态代理

静态代理角色分析

抽象角色 : 一般使用接口或者抽象类来实现。

真实角色 : 被代理的角色。

代理角色 : 代理真实角色 ; 代理真实角色后 , 一般会做一些附属的操作 。

客户  :  使用代理角色来进行一些操作 。

用租房子的场景

House抽象角色

public interface House {
    public void rent();
}

真实角色Landlord

public class Landlord implements House {
    public void rent() {
        System.out.println("房屋租赁");
    }
}

代理角色Proxy 

public class Proxy implements House {
    private Landlord landlord;

    public Proxy(){

    }

    public Proxy(Landlord landlord){
        this.landlord=landlord;
    }

    public void rent() {
        seeHouse();
        landlord.rent();
        pay();
    }

    //看房
    public void seeHouse(){
        System.out.println("看房");
    }

    //付租金
    public void pay(){
        System.out.println("付钱");
    }
}

客户角色

public class User {
    public static void main(String[] args) {
        Landlord landlord=new Landlord();
        Proxy proxy=new Proxy(landlord);
        proxy.rent();
    }
}

这里通过代理角色Proxy调用了Landlord的房屋租赁方法rent

动态代理

动态代理的角色和静态代理的一样,动态代理的代理类是动态生成的,静态代理的代理类是提前写好的。

动态代理分为两类 : 一类是基于接口动态代理的JDK动态代理, 一类是基于类的动态代理——cglib。

JDK的动态代理需要了解两个类InvocationHandler:调用处理程序和Proxy:代理

抽象角色House

public interface House {
    public void rent();
}

真实角色Landlord

public class Landlord implements House {
    public void rent() {
        System.out.println("房屋租赁");
    }
}

代理角色

public class ProxyInvocationHandler implements InvocationHandler {

    private House house;

    public void setHouse(House house){
        this.house=house;
    }

    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                house.getClass().getInterfaces(),this);

    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        seeHouse();
        Object invoke = method.invoke(house, args);
        pay();
        return invoke;
    }

    //看房
    public void seeHouse(){
        System.out.println("看房");
    }

    //付租金
    public void pay(){
        System.out.println("付钱");
    }
}

修改成通用的代理

public class ProxyInvocationHandler implements InvocationHandler {
   private Object target;

   public void setTarget(Object target) {
       this.target = target;
  }

   //生成代理类
   public Object getProxy(){
       return Proxy.newProxyInstance(this.getClass().getClassLoader(),
               target.getClass().getInterfaces(),this);
  }

   // proxy : 代理类
   // method : 代理类的调用处理程序的方法对象.
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       log(method.getName());
       Object result = method.invoke(target, args);
       return result;
  }

   //这里可以修改
   public void log(String methodName){
       System.out.println("执行了"+methodName+"方法");
  }

}

测试

    @Test
    public void Test1(){
        Landlord landlord=new Landlord();
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        pih.setHouse(landlord);
        House proxy = (House) pih.getProxy();
        proxy.rent();
    }