代理模式
给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。
使用代理模式的优点:
可以实现中介隔离,客户类可以使用代理对象在客户类和委托对象之间起到中介的作用(代理类和委托类实现相同接口)。遵循开闭原则,可以通过代理类扩展委托类的功能。
静态代理:
服务类接口:
1 public interface OriginService { 2 3 String doSomeThing(); 4 }
委托类:
1 public class OriginWorker implements OriginService { 2 3 @Override 4 public String doSomeThing() { 5 System.out.println("do something"); 6 return "i am origin worker"; 7 } 8 }
代理类:
1 public class OriginWorkerProxy implements OriginService{ 2 3 private OriginService originService; 4 5 public OriginWorkerProxy(OriginService originService) { 6 this.originService = originService; 7 } 8 9 @Override 10 public String doSomeThing() { 11 System.out.println("pre"); 12 return originService.doSomeThing(); 13 } 14 }
测试方法:
1 public class Main { 2 3 public static void main(String[] args) { 4 OriginWorker originWorker = new OriginWorker(); 5 OriginWorkerProxy originWorkerProxy = new OriginWorkerProxy(originWorker); 6 originWorkerProxy.doSomeThing(); 7 } 8 }
可以实现编程阶段对类的功能进行扩展,但是使用的时候需要创建代理类,不易管理,接口改变,代理类也需要变动。
动态代理:(JDK、CGLIB)
JDK动态代理:
动态代理类:
1 public class DynamicProxyHandler implements InvocationHandler { 2 3 private Object object; 4 5 public DynamicProxyHandler(Object object) { 6 this.object = object; 7 } 8 9 @Override 10 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 11 System.out.println("pre"); 12 Object result = method.invoke(object, args); 13 System.out.println("after"); 14 return result; 15 } 16 }
测试类:
1 public class DynamicProxyMain { 2 3 public static void main(String[] args) { 4 OriginService originWorker = new OriginWorker(); 5 OriginService proxy = (OriginService) Proxy 6 .newProxyInstance(OriginService.class.getClassLoader(), new Class[] { OriginService.class }, new DynamicProxyHandler(originWorker)); 7 proxy.doSomeThing(); 8 } 9 }
jdk动态代理需要委托类实现接口才可以。
CGLIB:
代理类:
1 public class CglibProxy implements MethodInterceptor { 2 3 private Object target; 4 5 public Object getInstance(final Object object) { 6 this.target = object; 7 Enhancer enhancer = new Enhancer(); 8 enhancer.setSuperclass(this.target.getClass()); 9 enhancer.setCallback(this); 10 return enhancer.create(); 11 } 12 13 @Override 14 public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { 15 System.out.println("pre"); 16 Object result = methodProxy.invoke(target, objects); 17 System.out.println("after"); 18 return result; 19 } 20 }
测试类:
1 public class CglibDynamicMain { 2 3 public static void main(String[] args) { 4 OriginWorker originWorker = new OriginWorker(); 5 CglibProxy cglibProxy = new CglibProxy(); 6 OriginWorker workerProxy = (OriginWorker) cglibProxy.getInstance(originWorker); 7 workerProxy.doSomeThing(); 8 } 9 }
Cglib根据委托类动态生成一个子类,代理委托类,所以不可以代理final修饰的类。Cglib可以代理没有实现接口的类。