设计模式之----代理模式
代理模式
1. 什么是代理模式?
代理模式是GoF四人组提出的23种设计模式之一。
若一个类T不能或不适合让另外一个类C直接访问,或者,类T在不修改自身源码的前提下,想增强业务逻辑功能,
此时,就可以通过一个中间类P来完成这些需求。那么,这个中间类P就称为代理类,而类T则称为目标类。
换个角度思考,那就是说,客户类C若想与目标类T打交道,那么都需要通过代理类P来完成。即客户类只能与代理
类P发生直接的联系。代理类P的对象可以代表目标类T与客户类打交道。
2. 代理模式中的角色
目标类 代理类 客户类
3. 代理模式的目的
1)为了保护和隐藏某一个类,可以使用代理模式
2)在不修改某个类的源码的前提下,为了增强某个类的功能,可以使用代理模式
4. 代理模式的分类
根据代理类创建的时间的不同,或者说,根据代理关系确立的时机的不同,可以将代理模式分为两类
1)静态代理
2)动态代理
动态代理又根据实现技术的不同,可以分为若干类,例如:
1)JDK的动态代理:
原理: Proxy底层利用接口创建了代理类对象, 当内存中已经有时,会创建一个副本,, 自定义类为委托类....
使用要求:.有接口才能使用代理
①自定义类实现(实现委托类), 需实现InvocationHandler 接口实现委托功能(对方法进行挑选过滤增强)
1//创建委托类 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 // jdk自带的proxy委托需实现InvocationHandler接口 6 public class BookProxy implements InvocationHandler { 7 private BookDao bookDao;//目标类对象 8 public BookProxy(BookDao bookDao) { 9 super(); 10 this.bookDao = bookDao; 11 } 12 // proxy 代理类(一般不用,使用错误会导致死循环) 13 // Method 方法(反射中的方法对象) 14 // args 传参 15 @Override 16 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 17 // TODO Auto-generated method stub 18 if (method.getName().equals("insert")) { 19 //使用实现类对象用反射调用方法 20 Object invoke = method.invoke(bookDao,args); 21 return invoke; 22 } 23 return null; 24 } 25 }
②main方法中使用Proxy.newProxyInstance方法获取代理类
public class Demo { public static void main(String[] args) { IbookDao instance = (IbookDao)Proxy.newProxyInstance( //返回值为一个代理类对象 (强转为接口) Demo.class.getClassLoader(), //目标类的类加载器 BookDao.class.getInterfaces(), //目标类的实现接口 new BookProxy(new BookDao()));//委托类对象 instance.insert(); //调用接口中的方法,(实现类中的方法) } }
③目标类中实现接口
public class BookDao implements IbookDao { .....//实现IbookDao中的方法 }
2)CGLIB动态代理:
原理 :底层创建一个实现类的子类对象
使用要求: 导入cglib包
①:自定义类(实现委托类). 实现MethodInterceptor接口(此接口实现了callback回调接口,标识作用)
public class Cglib implements MethodInterceptor{ private BookDao book; //目标类对象 public Cglib(BookDao book) { super(); this.book = book; } //obj代理类对象 // method 反射方法 // args 参数 // proxy 实现方法的代理类对象 @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { // TODO Auto-generated method stub method.invoke(book, args); return null; } }
②main调用 需自己创建调用类对象及方法
public class Demo { public static void main(String[] args) { BookDao book= new BookDao(); //目标类 Cglib cglib = new Cglib(book); //委托类 //此类需要自己创建 BookDao bookDao = (BookDao)CreateProxy.newProxyInstance( //返回值即为目标类的子类对象 BookDao.class, //实现类的字节码文件对象 cglib); //委托类对象 bookDao.delet(); } }
③创建调用类,与方法..方法名与Proxy中的一样
public class CreateProxy { public static Object newProxyInstance(Class class1, MethodInterceptor cglib) { //新建增强器对象 Enhancer enhancer = new Enhancer(); //设置父类,,,即目标类 enhancer.setSuperclass(class1); //设置委托类 enhancer.setCallback(cglib); //创建并返回 return enhancer.create(); } }
3)Javassist动态代理
............