/**
* 【代理模式】
* 特征:
* 代理类 与 委托类 有相同的接口;
* 代理类 负责 为委托类 预处理消息、过滤消息、把消息转发给委托类、事后处理消息等;
*
* 根据代理类的创建时期,分为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"));
* }
*
*/