zoukankan      html  css  js  c++  java
  • 代理模式

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

    使用代理模式的优点:

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

    静态代理:

    服务类接口:

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

  • 相关阅读:
    SqlServer Alwayson 搭建排错记录(一)
    SqlServer图形数据库初体验
    SqlServer报错:主体“dbo”不存在
    IIS重叠回收
    No module named 'revoscalepy'问题解决
    SqlServer查询文件组被占用情况
    SqlServer作业指定目标服务器
    [持续更新]UnsatisfiedLinkError常见问题及解决方案
    Android加载SO库UnsatisfiedLinkError错误的原因及解决方案
    _set_invalid_parameter_handler异常处理函数
  • 原文地址:https://www.cnblogs.com/avalon-merlin/p/10515373.html
Copyright © 2011-2022 走看看