zoukankan      html  css  js  c++  java
  • Java动态代理代码快速上手

    动态代理的两个核心的点是:代理的行为 和 代理机构。

    举个例子,上大学的时候,很多同学吃午饭的时候都是叫别人带饭,有一个人H特别热心肠,想了一个办法,他在门口挂了个公示牌,每天有谁想要找人带饭就写公告牌上写下自己想吃的饭,H每次直接记下谁谁谁想吃什么饭然后去帮大家买饭。这就是一个典型代理的过程。这里代理的行为就是带饭,代理的机构就是H。而且代理行为和代理机构之间进行了解耦。

    下面,我们基于这个例子使用JDK提供的代理机制来实现代码。

    首先,我们创建一个代理行为类接口BuyLunchInt(因为可能会有很多人需要带饭,并且带不同的饭,用于继承实现)

    package proxy;
    /**
     * @Author darrenqiao
     */
    public interface BuyLunchInt {
        void buyLunch();
    }
    View Code

    接着,我们基于代理行为的接口实现代理机构(代理机构的实现是核心)

    • 主要用到两个reflection包中的两个类,Invocationhandler 和 Proxy类。
    • Proxy类通过传入的类信息创建代理实例
    • InvocationHandler则通过实现invoke方法实现代理实例方法的执行
    package proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /**
     * @Author darrenqiao
     * 基于代理的行为接口实现的代理机构类
     * 主要工作两部分:
     * 通过Proxy创建代理实例
     * 通过重写InvocationHandler类的invoke方法实现代理行为的执行
     */
    public class ProxyAgent implements InvocationHandler {
        private Object target;
    
        public Object create(Object target) {
            this.target = target;
            return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        }
    
        //实现代理机制,通过反射基于接口调用方法
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("看看谁要我帮忙带饭");
            method.invoke(target, args);
            System.out.println("呐,你的饭");
            return null;
        }
    }
    View Code

    然后,就是有哪些人需要带饭,带什么饭,就实现接口BuyLunchInt并写到公告牌configure.properties中

    package proxy;
    /**
     * @Author darrenqiao
     */
    
    public class DarrenBuyLunch implements BuyLunchInt {
        @Override
        public void buyLunch() {
            System.out.println("darren要吃炒饭");
        }
    }
    View Code
    class=proxy.DarrenBuyLunch
    View Code

    最后,在main方法中,几个步骤,先看看公告牌configure.properties上有么有需要代理的对象,有则创建代理机构并代理执行;没有则退出。

    import proxy.BuyLunchInt;
    import proxy.ProxyAgent;
    
    import java.io.*;
    import java.util.Properties;
    
    /**
     * @Author darrenqiao
     */
    public class Main {
    
        static Properties prop = new Properties();
    
        static void init(){
            try {
                //这里初始化需要代理的类
                InputStream inputStream = new BufferedInputStream(new FileInputStream("C:\zongpengq\code\testDynamicProxy\src\configure.properties"));
                prop.load(inputStream);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
            init();
            if (prop.size() == 0){
                System.out.println("今天没人要带饭");
                return;
            }
            //创建代理机构
            ProxyAgent proxyAgent = new ProxyAgent();
            for (String s : prop.stringPropertyNames()) {
                String className = prop.getProperty(s);
                Class classInfo = Class.forName(className);
                //创建具体的代理的对象
                BuyLunchInt buyLunch = (BuyLunchInt)classInfo.newInstance();
                //代理机构为代理对象创建代理实例(类似:给你安排个人代理你去做这件事)
                BuyLunchInt proxy = (BuyLunchInt)proxyAgent.create(buyLunch);
                //代理去做事
                proxy.buyLunch();
            }
    
        }
    }
    View Code

    我们看看运行的结果,如果没有人需要带饭(即把公告牌configure.properties清空),运行结果如下

    如果有人需要带饭,比如Darren,在configure.properties中进行了配置,运行结果如下

  • 相关阅读:
    一条查询SQl是怎样执行的
    MySQL45讲笔记-事务隔离级别,为什么你改了数据我看不见
    了解一下IO控制器与控制方式
    进程的同步与互斥
    预防死锁,检测死锁,避免死锁,解除死锁....
    初识Git
    剑指offer-查找数组中重复的数字
    常见的几种进程调度算法
    操作系统-进程的状态以及转换
    中断、异常、系统调用
  • 原文地址:https://www.cnblogs.com/darrenqiao/p/9270854.html
Copyright © 2011-2022 走看看