Java动态代理简单实例:老板与秘书

Java动态代理是Java中比较晦涩难懂的一个部分,虽然看了一些别人的博客之后觉得自己大体明白了,但是事非经过不知难,自己写的时候却产生了诸多疑问。

本文用尽可能简单的例子来说明Java动态代理的机制。

例子共四个部分:

1. ReadFile接口(批改文件)

2. Boss类,委托类,能够批改文件

3. Secretary类,没有实现ReadFile接口,用Secretary可创建代理类,“代理”Boss批改文件(创建出来的代理类对象就是main函数中的secretary1)

4. Main类


1. ReadFile接口

public interface ReadFile {
    public void read();
}

2. Boss类,实现了ReadFile接口,可以批改文件

public class Boss implements ReadFile {

    @Override
    public void read() {
        System.out.println("I'm reading files.");
    }

}

3. Secretary类,不是代理类,但利用这个类能创建出代理类

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class Secretary implements InvocationHandler {

    private Object object;
    
    public Secretary(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println("I'm secretary.");
        Object result = method.invoke(object, args);

        return result;
    }

}

Secretary类中有一个变量object用来存boss对象,因为接下来Secretary要代理Boss做的事,因此先要把boss对象先保存起来。

Secretary类如果想代理Boss做的事,即调用Boss类的方法,必须实现InvocationHandler,重载invoke方法,然后在invoke函数中调用Boss类的方法。

我们看到invoke函数中有一句method.invoke(object, args),代理类就是用这种方式调用委托类的方法。


4. Main类

import java.lang.reflect.Proxy;

public class Main {

    public static void main(String[] args) {
        ReadFile boss = new Boss();

        InvocationHandler handler = new Secretary(boss);

        ReadFile secretary = (ReadFile) Proxy.newProxyInstance(
                boss.getClass().getClassLoader(),
                boss.getClass().getInterfaces(),
                handler);
        
        secretary.read();
    }
}
整个函数的执行流程如下:

先是创建了一个boss对象,

然后创建一个handler对象,

然后利用handler构造出一个能调用boss方法的对象secretary,这个secretary就是代理类对象

执行最后一句时,代理类的public Object invoke(...)方法被调用,代理类在此处调用委托类的方法,method.invoke()先打印I'm secretary,再调用boss对象的方法read()。



secretary每调用一次read()时都会执行public Object invoke(...),显而易见传入的第二个参数method即read(),第三个参数args即传入read()的参数(这里没有)。


实现了InvocationHandler的Secretary类并不能直接调用委托类的方法,handler对象只是一个handler,只有当handler对象用newProxyInstance方法包裹成secretary对象后,才具有调用boss方法的能力。

既然说secretary是由handler包裹而成的,那secretary是什么类型的呢?

        System.out.println(secretary.getClass().getName());

类型是$Proxy0




如果文章中存在问题请及时指正。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值