用代码帮你快速上手JDK动态代理

253 阅读3分钟

代理模式主旨是分离行为

直接上码:

//有一个接口是这个,接口里有一个行为是移动
public interface Moveable{
    void move();
}

有一个类现在要去实现这个行为

class Tank implements Moveable{
    @Override
    public void move() {
       System.out.println(">>>>>>坦克开始移动>>>>>>喀拉喀拉");
    }
}

平时我们要让坦克移动直接调用move方法就可以,现在我们要开始打仗了,要求坦克移动前要检查设备 。在不改变坦克类的前提下如何实现?别说静态代理,打仗了我不只要让坦克move还要飞机,大炮也move呢?

那我现在直接用代理类帮我去对行为进行增强

class ProxyObject implements InvocationHandler {
    Object object;
    public ProxyObject(Object object) {
        this.object = object;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("----开始检查设备------");
        //等同于 tank.move();
        method.invoke(this.object,args);
        System.out.println("----到达目的地-------");
        return null;
    }
}

首先就是实现InvocationHandler并重写invok方法,invok方法里的实现你的增强行为

method.invoke(this.object,args);这个调用就是调用坦克类里的移动,this.object就是坦克类,method.invoke就是等同于坦克类的move(),args就是调用这个方法参数,我们的坦克里move()是没有参数的。

你可以理解为method.invoke(this.object,args)等同于tank.move()

现在让我们的坦克跑起来吧

public static void main(String[] args) {
       /**先给我一个tank**/
       Moveable tank = new Tank();
       
       /**tank给我们JDK的InvocationHandler让他帮我们对tank的move行为进行增强**/
       InvocationHandler plusMove = new ProxyObject(tank);
       
       /**传入tank的类加载器,接口,增强方法。拜托jvm去造一个拥有增强行为的tank类**/
       Moveable plusTank = (Moveable) Proxy.newProxyInstance(tank.getClass().getClassLoader(),tank.getClass().getInterfaces(),plusMove);
       
       /**拿着jvm造好的tank调用下增强后的行为**/
       plusTank.move();
       
        /*----开始检查设备------
           >>>>>>坦克开始移动>>>>>>喀拉喀拉
           ----到达目的地-------*/
   }

tank.getClass().getClassLoader()我这里为了方便大家理解就传入的坦克类加载器,其实JAVA加载器分三类,对于我们写的代码里的类都是用的应用程序加载器加载的,所以这里可以替换为ClassLoader.getSystemClassLoader()

好了,这就是1.0版本的坦克大战,为了获得大家关注。我放一版完全体代码大家感受下

class TestA{
    public static void main(String[] args) {
        Moveable person = ProxyObject.getStub(new Person());
        Moveable tank = ProxyObject.getStub(new Tank());
        person.move();
        System.out.println("-------->>>>>><<<<<<<<----------");
        tank.move();
        System.out.println("-------->>>>>><<<<<<<<----------");
        person.fight();
        System.out.println("-------->>>>>><<<<<<<<----------");
        tank.fight();
    }

}
class ProxyObject implements InvocationHandler {
    Object object;
    public ProxyObject(Object object) {
        this.object = object;
    }
    static public<T> Moveable getStub(T serviceImpl){
        return (Moveable) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),serviceImpl.getClass().getInterfaces(),new ProxyObject(serviceImpl));
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("----开始------");
        method.invoke(this.object,args);
        System.out.println("----结束-------");
        return null;
    }
}
class Person implements Moveable{
    @Override
    public void move() {
        System.out.println("_我方__(士兵)脑淤血死了——得得得");
    }

    @Override
    public void fight() {
        System.out.println("(士兵)交战中————哒哒哒哒哒哒哒哒哒哒哒");
    }
}
class Tank implements Moveable{
    @Override
    public void move() {
        System.out.println("_我方__(坦克)开始移动————喀拉喀拉");
    }

    @Override
    public void fight() {
        System.out.println("(坦克)交战中————得得得得得得得得");
    }
}
interface Moveable{
    void move();
    void fight();
}

初来乍到,希望各位大大多多互动,谢谢