java动态代理

267 阅读3分钟

一、代理模式

为其他对象提供一个代理以控制对某个对象的访问,代理类负责在被代理类执行服务前后进行预处理和后置处理,真实的服务提供者仍是被代理类。 比如一个用户类具有登陆功能,可以提供一个代理类,在不修改源代码的情况下给其加上权限认证。

二、静态代理

静态代理就是一个代理类只能为一个被代理类提供服务,以明星和经纪人举例,明星(被代理类)本人有收钱的行为,有了经纪人(代理类)就可以委托经纪人(代理类)进行收款,在此基础上经纪人可以在收款前发送卡号,收款后发送确认信息。

class Singer implements Person{  //被代理类明星
    @Override
    public void collectMoney() {
        System.out.println("明星本人收钱");
    }
}
class SingerProxy implements  Person{ //代理类 (可以理解为明星经纪人)
    private Person  person=new Singer();
    @Override
    public void collectMoney() {
        System.out.println("Before invoke collectMoney");
        person.collectMoney();
        System.out.println("After invoke collectMoney");
    }
}
public static void main(String[] args) {
    //静态代理
    SingerProxy singerProxy=new SingerProxy();
    singerProxy.collectMoney();
   }

运行结果:Before invoke collectMoney 指在执行收钱行为之前一系列预处理操作

After invoke collectMoney指在收钱后一系列后置操作

1.png

三、动态代理 Proxy

java.lang.reflect.Proxy 中提供了Proxy类来实现动态代理。动态代理可以实现一个代理类代理多个被代理类

提供了下面这一获取代理实例的静态方法

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

参数描述:

loader:定义代理类的类加载器
interfaces:代理类要实现的接口列表
h:指派方法调用的调用处理程序

java.lang.reflect包中提供了一个接口InvocationHandler

Object invoke(Object proxy, Method method, Object[] args)

参数描述:

proxy - 在其上调用方法的代理实例

method - 对应于在代理实例上调用的接口方法的 Method 实例。 Method 对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。

args - 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null。基本类型的参数被包装在适当基本包装器类(如 java.lang.Integer 或 java.lang.Boolean)的实例中

interface Person{
    void collectMoney();
}
class Singer1 implements Person{  //被代理类明星
    @Override
    public void collectMoney() {
        System.out.println("明星1本人收钱");
    }
}

class Singer2 implements Person{  //被代理类明星
    @Override
    public void collectMoney() {
        System.out.println("明星2本人收钱");
    }
}

interface Animal{
    void eat();
}
class Cat implements Animal{

    @Override
    public void eat() {
        System.out.println("猫吃饭");
    }
}

//动态代理
class ProxyHandler implements InvocationHandler{
    private Object object;
    public ProxyHandler(Object object){
        this.object=object;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before invoke"+method.getName());
        method.invoke(object,args);
        System.out.println("After invoke"+method.getName());
        return null;
    }
}
public static void main(String[] args) {
    //动态代理
    Person singer1=new Singer1();//被代理类singer1
    Person singer2=new Singer2();//被代理类singer2
    Animal cat=new Cat();//被代理类cat
    ProxyHandler proxyHandler1 = new ProxyHandler(singer1);//创建singer1的代理类的处理程序
    ProxyHandler proxyHandler2 = new ProxyHandler(singer2);//创建singer2的代理类的处理程序
    ProxyHandler proxyHandler3 = new ProxyHandler(cat);//创建singer3的代理类的处理程序

    Person singer1Proxy = (Person)Proxy.newProxyInstance(singer1.getClass().getClassLoader(), singer1.getClass().getInterfaces(), proxyHandler1);//创建singer1的代理类实例
    Person singer2Proxy = (Person)Proxy.newProxyInstance(singer2.getClass().getClassLoader(),singer2.getClass().getInterfaces(),proxyHandler2);//创建singer2的代理类实例
    Animal catProxy = (Animal)Proxy.newProxyInstance(cat.getClass().getClassLoader(), cat.getClass().getInterfaces(), proxyHandler3);//创建singer3的代理类实例

    singer1Proxy.collectMoney(); 
    singer2Proxy.collectMoney();
    catProxy.eat();
}

运行结果:

1.png