/** * 【代理模式】 * 特征: * 代理类 与 委托类 有相同的接口; * 代理类 负责 为委托类 预处理消息、过滤消息、把消息转发给委托类、事后处理消息等; * * 根据代理类的创建时期,分为2种: * 静态代理类: * 程序运行前,代理类就已经存在; * 动态代理类: * 程序运行时,运用反射机制动态创建代理类; */
/** * 【静态代理类】 * public interface HelloService{ * String echo(String msg); * } * * // 委托类 * public class HelloServiceImpl implements HelloService{ * public String echo(String msg){ * return "echo:"+msg; * } * } * * // 代理类 * public class HelloServiceProxy implements HelloService{ * private HelloService helloService; * * public HelloServiceProxy(HelloService helloService){ * this.helloService=helloService; * } * * public String echo(String msg){ * System.out.println("before calling echo()"); * String result=helloService.echo(msg); * System.out.println("after calling echo()"); * return result; * } * } * * public static void main(String args[]){ * HelloService helloService=new HelloServiceImpl(); * HelloService helloServiceProxy=new HelloServiceProxy(helloService); * System.out.println(helloServiceProxy.echo("hello")); * } */
/** * 【动态代理类】 * java.lang.reflect包中的 Proxy、InvocationHandler 提供了 生成动态代理类的能力; * * public class Proxy implements java.io.Serializable { * // 创建 动态代理类 * public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) throws IllegalArgumentException{} * * // 创建 动态代理类的实例 * public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)throws IllegalArgumentException{} * } * * public interface InvocationHandler { * public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; * } * * 【Proxy创建的代理类有如下特点】 * 1、public、final、非抽象 * 2、继承 java.lang.reflect.Proxy * 3、名称以 $Proxy 开头 * 4、实现 参数中interfaces 指定所有接口 * 5、都有一个 public的构造方法,构造方法有一个 InvocationHandler类型的参数 * 6、Proxy.isProxyClass 判断一个类是否为动态代理类 * * 【Proxy创建的代理实例有如下特点】 * 1、每个动态代理类实例 都与 一个InvocationHandler实例 关联 * 2、Proxy.getInvocationHandler 返回与 代理类实例 关联的InvocationHandler实例 * 3、当程序调用 代理类实例的方法时,会调用 与 代理类实例关联的InvocationHandler实例的 invoke方法 * * * public interface HelloService{ * String echo(String msg); * } * * // 委托类 * public class HelloServiceImpl implements HelloService{ * public String echo(String msg){ * return "echo:"+msg; * } * } * * // 代理工厂 * public class HelloServiceProxyFactory { * * public static <T> T getHelloServiceProxy(final Object object, final Class<?>... interfaces) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { * MyHandler myHandler = new MyHandler(object); * * // 第1种方式创建代理类实例 * Class<?> proxyClass = Proxy.getProxyClass(object.getClass().getClassLoader(), interfaces); * Constructor<?> constructor = proxyClass.getConstructor(new Class[]{InvocationHandler.class}); * T newInstance = (T) constructor.newInstance(myHandler); * return newInstance; * * // 第2种方式创建代理类实例 * T newProxyInstance = (T) Proxy.newProxyInstance(o.getClass().getClassLoader(), interfaces, myHandler); * return newProxyInstance; * } * * static class MyHandler implements InvocationHandler{ * * private Object object; * * public MyHandler(){} * * public MyHandler(Object o){ * this.object = o; * } * * @Override * public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { * System.out.println("before calling "+method); * Object result=method.invoke(object, args); * System.out.println("after calling "+method); * return result; * } * * } * } * * public static void main(String args[]) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { * HelloService helloService=new HelloServiceImpl(); * HelloService helloServiceProxy= HelloServiceProxyFactory.getProxyInstance(helloService, HelloService.class); * System.out.println(helloServiceProxy.getClass().getName()); * System.out.println(helloServiceProxy.echo("Hello")); * } * */