代理模式之动态代理

静态代理的缺点是只能代理一个主题接口,后期想增加代理,还得修改
而动态代理是一个代理工作器可以代替多个“代理主题”代理工作,核心逻辑还是被代理者们来实现,只要代理工作一样,这个代理工作器就可以代理。
要求:
1、编写代理类,实现InvocationHandler接口,重写invoke方法
2、用Proxy.newProxyInstance创建代理对象
3、方法调用
主题接口和实现类:


public interface TestA {
    void runA();
}
public class ImplA implements TestA {
    @Override
    public void runA() {
        System.out.println("我是A接口的实现类,我在运行我重写的runA方法.....");
    }
}

public interface TestB {
    void runB();
}
public class ImplB implements TestB {
    @Override
    public void runB() {
        System.out.println("我是B接口的实现类,我在运行我重写的runB方法.....");
    }
}

代理类:

public class Handle implements InvocationHandler {
    private Object object;

    public Handle(Object object) {
        this.object = object;
    }

    /**
     *
     * @param proxy 代理者对象
     * @param method 被代理者要执行的方法
     * @param args 被代理者执行方法需要的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(proxy.getClass().getName()+"开始执行代理工作...");
        System.out.println(method.getName()+"开始执行....");
        Object value = method.invoke(object,args);
        System.out.println(method.getName()+"执行结束");
        System.out.println(proxy.getClass().getName()+"执行代理工作结束");
        return value;
    }
}

测试类:

public class Test {
   public static void main(String[] args) {
       //执行代理impA的工作
       TestA a = new ImplA();
       ClassLoader classLoader = a.getClass().getClassLoader();
       Class<?>[] interfaces = a.getClass().getInterfaces();
       Handle handle = new Handle(a);
       /**
        * newProxyInstance的三个参数
        * 1、被代理者的类加载器
        * 2、被代理者实现的接口们
        * 3、代理者的对象
        */
       TestA testA = (TestA) Proxy.newProxyInstance(classLoader, interfaces, handle);
       testA.runA();
       System.out.println("===============================");
       //执行代理impB的工作
       TestB b = new ImplB();
       ClassLoader classLoaderB = b.getClass().getClassLoader();
       Class<?>[] interfacesB = b.getClass().getInterfaces();
       Handle handleB = new Handle(b);
       /**
        * newProxyInstance的三个参数
        * 1、被代理者的类加载器
        * 2、被代理者实现的接口们
        * 3、代理者的对象
        */
       TestB testB = (TestB) Proxy.newProxyInstance(classLoaderB, interfacesB, handleB);
       testB.runB();
   }

}

测试结果:

E:\Java\jdk\bin\java.exe "-javaagent:E:\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=61915:E:\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath E:\Java\jdk\jre\lib\charsets.jar;E:\Java\jdk\jre\lib\deploy.jar;E:\Java\jdk\jre\lib\ext\access-bridge-64.jar;E:\Java\jdk\jre\lib\ext\cldrdata.jar;E:\Java\jdk\jre\lib\ext\dnsns.jar;E:\Java\jdk\jre\lib\ext\jaccess.jar;E:\Java\jdk\jre\lib\ext\jfxrt.jar;E:\Java\jdk\jre\lib\ext\localedata.jar;E:\Java\jdk\jre\lib\ext\nashorn.jar;E:\Java\jdk\jre\lib\ext\sunec.jar;E:\Java\jdk\jre\lib\ext\sunjce_provider.jar;E:\Java\jdk\jre\lib\ext\sunmscapi.jar;E:\Java\jdk\jre\lib\ext\sunpkcs11.jar;E:\Java\jdk\jre\lib\ext\zipfs.jar;E:\Java\jdk\jre\lib\javaws.jar;E:\Java\jdk\jre\lib\jce.jar;E:\Java\jdk\jre\lib\jfr.jar;E:\Java\jdk\jre\lib\jfxswt.jar;E:\Java\jdk\jre\lib\jsse.jar;E:\Java\jdk\jre\lib\management-agent.jar;E:\Java\jdk\jre\lib\plugin.jar;E:\Java\jdk\jre\lib\resources.jar;E:\Java\jdk\jre\lib\rt.jar;F:\IdeaProjects\testProxy\out\production\testProxy dynamicProxy.Test
com.sun.proxy.$Proxy0开始执行代理工作...
runA开始执行....
我是A接口的实现类,我在运行我重写的runA方法.....
runA执行结束
com.sun.proxy.$Proxy0执行代理工作结束
===============================
com.sun.proxy.$Proxy1开始执行代理工作...
runB开始执行....
我是B接口的实现类,我在运行我重写的runB方法.....
runB执行结束
com.sun.proxy.$Proxy1执行代理工作结束

Process finished with exit code 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值