脑子有点混乱。
代理分为动态代理和静态代理,但是主要角色都一样,主要有四个
- 主题接口
- 主题实现类
- 代理类
- 代理调用
以汽车为例,我们希望通过增加一个代理来记录汽车的驾驶时间,首先构写一个Movealbe接口,再写汽车类实现该接口,重写其中方法:
接着便是代理类的实现,代理类需要和主题实现类一样实现同一个接口,这样代理类才能调用主题类的功能,同时在代理类中我们需要有一个成员变量来接收主题实现类对象,这样重写方法的时候才能调用其实现类已经实现的代码逻辑,实现调用:
这里在构造方法中接收了主题实现类的接口类型参数,将其赋到成员变量当中,在重写接口方法的时候同时对其调用,上下加入时间的统计,最后在main方法我们通过创建代理类并且将主题实例传入即可:
在这里我们可以看到,代理类对接口方法的兼容并不是很好,这里只单一的抒写了接口中的run方法,考虑一下,如果还需要添加一个给汽车加油的方法将怎么样?
那么接口的实现类需要重写加油方法,代理方法也需要重写加油方法,因为他们继承都是同一个接口(这里接口命名不规范):
我们可以用动态代理优化代理类的代码,代理类不再和主题实现类一样实现同一个接口,转而实现的是InvocationHandler,实现该接口后这个代理类需要重写invoke方法,这个方法的作用相当于一个媒介,我们后面使用生成的代理对象调用其对应方法的时候都会转为调用invoke方法:
这里invoke方法的参数有两个,一个是主题实体类,也就是被代理对象,第二个是代理对象方法调用时传入的参数。
这里我并没有区分方法具体是哪个,而是都做了时间统计。
接下来便是调用,首先还是创建被代理对象实体,接着便是通过该实体创建上面所写的handler,来处理自己的代理逻辑,
最后便是生成代理实例,通过Proxy的newInstance方法创建,该方法需要三个参数才能确定所生成的实例类型,前两个参数分别为主题实体类加载器和主题实体类继承的接口,最后一个是对应的handler,生成以后还要对其类型转换一下,转换成主题类实现的接口类的类型: