一、代理模式:
代理模式是对象的结构模式;
代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用;
常见的代理模式分类:静态代理,jdk动态代理,
二、静态代理:
静态代理一个代理类:只能代理一种接口的类;如果代理类的业务都是一样的,就造成了大量重复代理类;
1)真实对象和代理对象共同的接口:
//抽象角色:声明真实对象和代理对象的共同接口; public interface ITicketManager { /** * 售票 */ void soldTicket(); /** * 改签 */ void changeTicket(); /** * 退票 */ void returnTicket(); }
2)真实对象实现类:
public class TicketManagerImpl implements ITicketManager { @Override public void soldTicket() { System.out.println("售票"); } @Override public void changeTicket() { System.out.println("改签"); } @Override public void returnTicket() { System.out.println("退票"); } /** * 身份验证 */ public void checkIdentity(){ System.out.println("身份验证"); } }
3)代理1:

public class StaticProxyTicketManager implements ITicketManager { ITicketManager iTicketManager;//目标对象的引用 public StaticProxyTicketManager(ITicketManager iTicketManager) { this.iTicketManager = iTicketManager; } @Override public void soldTicket() { checkIdentity(); iTicketManager.soldTicket(); } @Override public void changeTicket() { checkIdentity(); iTicketManager.changeTicket(); } @Override public void returnTicket() { checkIdentity(); iTicketManager.changeTicket(); } /** * 身份验证 */ public void checkIdentity(){ System.out.println("身份验证--------------"); } }
4)代理2:

public class LogProxy implements ITicketManager { private ITicketManager iTicketManager; public LogProxy(ITicketManager iTicketManager){ this.iTicketManager = iTicketManager; } @Override public void soldTicket() { iTicketManager.soldTicket(); log();//后置增强 } @Override public void changeTicket() { iTicketManager.changeTicket(); log(); } @Override public void returnTicket() { iTicketManager.returnTicket(); log(); } //增强 private void log() { System.out.println("日志..."); } }
5)测试:
public class Test { public static void main(String[] args) { ITicketManager tm = new LogProxy(new StaticProxyTicketManager(new TicketManagerImpl())); tm.soldTicket(); tm.changeTicket(); tm.returnTicket(); } }
6)结果:
身份验证-------------- 售票 日志... 身份验证-------------- 改签 日志... 身份验证-------------- 改签 日志...
三、jdk动态代理:
通过让代理类(DynamicProxy)实现JDK自带的java.lang.reflect.InvocationHandler接口,该接口中的invoke() 方法能够让代理类(DynamicProxy)实例在运行时调用被代理类的“对外服务”,即调用被代理类需要对外实现的所有接口中的方法,也就是完成对真实方法的调用;
缺点:需要代理的业务类有实现的接口作为参数,因为需要调用接口中定义的方法;如果没有实现接口的业务类,JDK动态代理就无能为力了;
1)接口:

public interface ITicketManager { /** * 售票 */ void soldTicket(); /** * 改签 */ void changeTicket(); /** * 退票 */ void returnTicket(); }
2)接口实现类:

public class TicketManagerImpl implements ITicketManager { @Override public void soldTicket() { System.out.println("售票"); } @Override public void changeTicket() { System.out.println("改签"); } @Override public void returnTicket() { System.out.println("退票"); } }
3)代理类:
public class DynamicProxyTicketManager implements InvocationHandler { private Object targetObject; /** * 目标的初始化方法,根据目标生成代理类 * * @param targetObject * @return */ public Object newProxyInstance(Object targetObject) { this.targetObject = targetObject; // 第一个参数,目标对象 的装载器 // 第二个参数,目标接口已实现的所有接口,而这些是动态代理类要实现的接口列表 // 第三个参数, 调用实现了InvocationHandler的对象生成动态代理实例,当你一调用代理,代理就会调用InvocationHandler的invoke方法 return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this); } /** * 反射,这样你可以在不知道具体的类的情况下,根据配置的参数去调用一个类的方法。在灵活编程的时候非常有用。 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 检查 checkIdentity(); Object ret = null; try { // 调用目标方法 ret = method.invoke(targetObject, args); // 执行成功,打印成功信息 log(); } catch (Exception e) { e.printStackTrace(); // 失败时,打印失败信息 System.out.println("error-->>" + method.getName()); throw e; } return ret; } /** * 身份验证 */ public void checkIdentity() { System.out.println("身份验证--------------"); } public void log() { System.out.println("日志..."); } }
4)测试:
public class Test { public static void main(String[] args) { DynamicProxyTicketManager dynamicProxyTicketManager=new DynamicProxyTicketManager(); ITicketManager tm=(ITicketManager) dynamicProxyTicketManager.newProxyInstance(new TicketManagerImpl()); tm.soldTicket(); tm.changeTicket(); tm.returnTicket(); } }
四、GClib动态代理:
1、无需接口就能代理类;
2、因为时生产被代理的子类,所以被final修饰的方法无法代理;
1)导包:asm-3.3.1.jar;cglib-2.2.2.jar;这两个版本测试可用;
2)被代理类:

public class TicketManager { public void soldTicket() { System.out.println("售票"); } public void changeTicket() { System.out.println("改签"); } public void returnTicket() { System.out.println("退票"); } }
3)代理类:
public class DynamicProxyTicketManager implements MethodInterceptor { private Object targetObject; /** * 目标的初始化方法,根据目标生成代理类 * * @param targetObject * @return */ public Object newProxyInstance(Object targetObject) { //代理类class文件存入本地磁盘 //System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"D:\\code"); this.targetObject = targetObject; // 创建加强器,用来创建动态代理类 Enhancer enhancer = new Enhancer(); // 为加强器指定要代理的业务类(即:为下面生成的代理类指定父类) enhancer.setSuperclass(targetObject.getClass()); // 设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方 //法进行拦 enhancer.setCallback(this); // 创建动态代理类对象并返回 Object obj = enhancer.create(); return obj; } @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { // 检查 checkIdentity(); Object ret = null; try { ret = methodProxy.invokeSuper(proxy, args); // 执行成功,打印成功信息 System.out.println(1 / 0); log(); } catch (Exception e) { e.printStackTrace(); // 失败时,打印失败信息 System.out.println("error-->>" + method.getName()); throw e; } return ret; } /** * 身份验证 */ public void checkIdentity() { System.out.println("身份验证--------------"); } public void log() { System.out.println("日志..."); } }
4)测试:
public class Test { public static void main(String[] args) { TicketManager ticketManager = new TicketManager(); DynamicProxyTicketManager dynamicProxyTicketManager = new DynamicProxyTicketManager(); TicketManager instance = (TicketManager) dynamicProxyTicketManager.newProxyInstance(ticketManager); instance.changeTicket(); instance.returnTicket(); instance.soldTicket(); } }