JDK动态代理
Java动态代理类位于Java.lang.reflect包下。
主要涉及到以下两个类:
1、 java.lang.reflect.InvocationHandler(处理器接口):可以通过invoke方法实现
该接口中仅定义了一个方法 Object invoke(Object obj,Method method, Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组。这个抽象方法在代理类中动态实现。
2、java.lang.reflect.Proxy:生成动态代理类和对象对真实角色的代理访问。
每次通过 Proxy 生成的代理类对象都要指定对应的处理器对象。
该类即为动态代理类,其中主要包含以下内容:
Protected Proxy(InvocationHandler h):构造函数,估计用于给内部的h赋值。
Static Class getProxyClass(ClassLoader loader, Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。
Static Object newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。
什么是Dynamic Proxy?
所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。在使用动态代理类时,我们必须实现InvocationHandler接口
示例:
接口:Subject.java
public interface Subject { public int sellBooks(); public String speak(); }
真实对象:RealSubject.java
public class RealSubject implements Subject{ @Override public int sellBooks() { System.out.println("卖书"); return 1 ; } @Override public String speak() { System.out.println("说话"); return "张三"; } }
处理器对象:MyInvocationHandler.java
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * 定义一个处理器*/ public class MyInvocationHandler implements InvocationHandler { /** * 因为需要处理真实角色,所以要把真实角色传进来 */ Subject realSubject ; public MyInvocationHandler(Subject realSubject) { this.realSubject = realSubject; } /** * * @param proxy 代理类 * @param method 正在调用的方法 * @param args 方法的参数 * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("调用代理类"); if(method.getName().equals("sellBooks")){ int invoke = (int)method.invoke(realSubject, args); System.out.println("调用的是卖书的方法"); return invoke ; }else { String string = (String) method.invoke(realSubject,args) ; System.out.println("调用的是说话的方法"); return string ; } } }
调用端:Main.java
import java.lang.reflect.Proxy; /** * 调用类*/ public class Client { public static void main(String[] args) { //真实对象 Subject realSubject = new RealSubject(); MyInvocationHandler myInvocationHandler = new MyInvocationHandler(realSubject); //代理对象 Subject proxyClass = (Subject) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Subject.class}, myInvocationHandler); proxyClass.sellBooks(); proxyClass.speak(); } }
参考:大话设计模式:面向对象程序设计23种常见设计模式通俗演义 11
代理模式-https://www.runoob.com/design-pattern/proxy-pattern.html