动态代理的两个核心的点是:代理的行为 和 代理机构。
举个例子,上大学的时候,很多同学吃午饭的时候都是叫别人带饭,有一个人H特别热心肠,想了一个办法,他在门口挂了个公示牌,每天有谁想要找人带饭就写公告牌上写下自己想吃的饭,H每次直接记下谁谁谁想吃什么饭然后去帮大家买饭。这就是一个典型代理的过程。这里代理的行为就是带饭,代理的机构就是H。而且代理行为和代理机构之间进行了解耦。
下面,我们基于这个例子使用JDK提供的代理机制来实现代码。
首先,我们创建一个代理行为类接口BuyLunchInt(因为可能会有很多人需要带饭,并且带不同的饭,用于继承实现)
package proxy; /** * @Author darrenqiao */ public interface BuyLunchInt { void buyLunch(); }
接着,我们基于代理行为的接口实现代理机构(代理机构的实现是核心)
- 主要用到两个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; } }
然后,就是有哪些人需要带饭,带什么饭,就实现接口BuyLunchInt并写到公告牌configure.properties中
package proxy; /** * @Author darrenqiao */ public class DarrenBuyLunch implements BuyLunchInt { @Override public void buyLunch() { System.out.println("darren要吃炒饭"); } }
class=proxy.DarrenBuyLunch
最后,在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(); } } }
我们看看运行的结果,如果没有人需要带饭(即把公告牌configure.properties清空),运行结果如下
如果有人需要带饭,比如Darren,在configure.properties中进行了配置,运行结果如下