• 代理模式


    给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。

    使用代理模式的优点:

    可以实现中介隔离,客户类可以使用代理对象在客户类和委托对象之间起到中介的作用(代理类和委托类实现相同接口)。遵循开闭原则,可以通过代理类扩展委托类的功能。

    静态代理:

    服务类接口:

    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可以代理没有实现接口的类。

  • 相关阅读:
    SQL Server 2005高级程序设计
    SQL语言艺术
    无益的程序
    Django Ajax动态图形监控
    C/C++ Qt 基本文件读写方法
    Django 实现统计网站访问状态
    Python 实现 WebSocket 通信
    Django Admin后台定制简单监控页
    Django Ajax 实现Web命令行执行
    C/C++ Qt QThread 线程组件应用
  • 原文地址:https://www.cnblogs.com/avalon-merlin/p/10515373.html
Copyright © 2020-2023  润新知