b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

代理模式及其优缺点的分析

电脑杂谈  发布时间:2020-04-02 10:18:43  来源:网络整理

c# aop的实现有哪些_aop实现方案优缺点_spring aop代理实现

代理模式的最典型应用是AOP. 本文主要介绍代理模式的几种实现模式: 静态代理和动态代理. 在这里,动态代理可以分为jdk代理和Cglib代理. 此外,本文还将对此进行讨论. 比较了几种代理模型的优缺点.

顾名思义,代理用于代表被请求者处理相关事务. 代理对象通常委派被请求者的所有权利. 客户端访问代理对象就像访问被请求者一样. 尽管代理对象最终仍可以访问被请求者,但它可以在请求之前或之后执行某些操作. 多余的工作或客户的请求是非法的,直接拒绝了客户的请求. 下图显示了代理模型的简化图:

代理模式的作用:

静态代理模式也是上图中描述的模式. 从图中可以看出,SubjectProxy存储一个ISubject实例. 当客户端调用SubjectProxy的request()方法时,它不仅会做其他工作. 它还调用ISubject实例的request()方法. 这是这三个类的简单实现:

public interface ISubject {
  void request();
}
public class SubjectImpl implements ISubject {
  @Override
  public void request() {
    System.out.println("request SubjectImpl.");
  }
}
public class SubjectProxy implements ISubject {
  private ISubject target;
  public SubjectProxy(ISubject target) {
    this.target = target;
  }
  @Override
  public void request() {
    System.out.println("before safety check.");
    target.request();
    System.out.println("after safety check.");
  }
}

c# aop的实现有哪些_spring aop代理实现_aop实现方案优缺点

您可以看到在调用代理对象的方法之前和之后,代理对象都会打印相关语句. 这是一个客户请求的示例:

public class Client {
  @Test
  public void testStaticProxy() {
    ISubject subject = new SubjectImpl();
    ISubject proxy = new SubjectProxy(subject);
    proxy.request();
  }
}

运行上述用例,可以获得以下结果:

before safety check.
request SubjectImpl.
after safety check.

从客户端访问方法可以看出,客户端获得了实现ISubject接口的实例,并且它调用的request()方法实际上是代理对象的request()方法. 此代理方法称为静态代理,该代理方法也是最有效的一种,因为已经编写了所有类,并且客户端仅需要获取代理对象并执行它即可.

尽管静态代理更有效,但它也具有不可避免的缺陷. 可以看出,当客户端调用代理对象时,它使用由代理对象和代理对象实现的接口. 我们可以将此接口理解为定义特定业务需求的实现规范. 如果存在其他业务需求(例如数据修改),则该需求与当前需求平行且没有交叉,但是在正常业务之外执行的安全验证工作与当前需求一致. 以下是我们用于此数据修改业务的实现代码:

spring aop代理实现_c# aop的实现有哪些_aop实现方案优缺点

public interface IUpdatable {
  void update();
}
public class UpdatableImpl implements IUpdatable {
  @Override
  public void update() {
    System.out.println("update UpdatableImpl.");
  }
}
public class UpdatableProxy implements IUpdatable {
  private IUpdatable updatable;
  public UpdatableProxy(IUpdatable updatable) {
    this.updatable = updatable;
  }
  @Override
  public void update() {
    System.out.println("pre safety check.");
    updatable.update();
    System.out.println("after safety check.");
  }
}

以下是客户端代码:

public class Client {
  @Test
  public void testStaticProxy() {
    ISubject subject = new SubjectImpl();
    ISubject proxy = new SubjectProxy(subject);
    proxy.request();
    
    IUpdatable updatable = new UpdatableImpl();
    IUpdatable proxy = new UpdatableProxy(updatable);
    proxy.update();
  }
}

可以看出,要实现相同的对象代理功能(安全性验证),静态代​​理方法需要为每个接口实现一个代理类,并且这些代理类中的代码几乎相同. 这可能会导致大型系统中的重大维护问题.

①jdk代理商

所谓的jdk代理是指使用jdk提供的相关类来实现代理模型aop实现方案优缺点,主要有两个类: InvocationHandler和Proxy. 实现代理模式时,仅需要实现InvocationHandler接口. 以下是实现此接口的示例:

aop实现方案优缺点_spring aop代理实现_c# aop的实现有哪些

public class SafetyInvocationHandler implements InvocationHandler {
  private Object target;
  public SafetyInvocationHandler(Object target) {
    this.target = target;
  }
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("before safety check.");
    Object result = method.invoke(target, args);
    System.out.println("after safety check.");
    return result;
  }
}

以下是客户端调用方法:

public class Client {
  @Test
  public void testDynamicProxy() {
    ISubject subject = new SubjectImpl();
    ISubject proxySubject = (ISubject) Proxy.newProxyInstance(Client.class.getClassLoader(), new Class[]{ISubject.class}, new SafetyInvocationHandler(subject));
    proxySubject.request();
    IUpdatable updatable = new UpdatableImpl();
    IUpdatable proxyUpdatable = (IUpdatable) Proxy.newProxyInstance(Client.class.getClassLoader(), new Class[]{IUpdatable.class}, new SafetyInvocationHandler(updatable));
    proxyUpdatable.update();
  }
}

您可以看到客户端在调用代理对象时使用相同的SafetyInvocationHandler. 在这里,jdk代理实际上使用反射为每个需要代理的对象创建一个InvocationHandler实例. 调用目标对象时aop实现方案优缺点,它将首先调用代理对象,然后在代理对象的逻辑中请求目标对象. 这就是为什么可以将目标对象实例保存在代理类中的原因,例如上述的SafetyInvocationHandler,该类声明了一个Object类型属性来保存目标对象实例.

jdk代理解决了静态代理需要为每个业务接口创建代理类的问题. 尽管使用反射创建代理对象的效率略低于静态代理,但在现代高速jvm中也可以接受. 在Spring的AOP代理中,默认情况下是使用jdk代理实现的. jdk代理的局限性在这里很明显,也就是说,需要成为代理的对象必须实现一个接口. 如果代理对象没有实现任何接口,或者代理业务方法没有相应的接口,我们可以使用另一种方法来实现它,即Cglib代理.

②Cglib代理

c# aop的实现有哪些_aop实现方案优缺点_spring aop代理实现

Cglib代理是最强大的代理方法,因为它不仅解决了静态代理需要创建多个代理类的问题,而且还解决了jdk代理需要通过代理对象来实现以实现接口的问题. 对于需要代理的类,如果可以为其创建一个子类并在该子类中编写相关的代理逻辑,因为“父类的子类实例”可以在进行调用时直接调用该子类对象的实例. 达到代理的效果. Cglib代理的原理实际上是动态生成代理类的子类字节码. 由于其字节码是根据jvm的已编译类文件的规范编写的,因此可以由jvm正常加载和运行. 这就是为什么Cglib代理不需要为每个代理类编写代理逻辑的原因. 此处应注意,根据Cglib的实现原理,由于它通过创建子类字节码来实现代理,因此,如果将代理类的方法声明为最终类型,则Cglib代理将无法正常工作,因为无法使用final Type方法. 覆盖. 这是使用Cglib代理的示例:

/**
 * 被代理类
 */
public class Suject {
  public void request() {
    System.out.println("update without implement any interface.");
  }
}
/**
 * 代理类
 */
public class SafetyCheckCallback implements MethodInterceptor {
  @Override
  public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    System.out.println("before safety check.");
    Object result = methodProxy.invokeSuper(o, objects);
    System.out.println("after safety check.");
    return result;
  }
}

以下是客户端访问方法:

public class Client {
  @Test
  public void testCglibProxy() {
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(Suject.class);
    enhancer.setCallback(new SafetyCheckCallback());
    Suject proxy = (Suject) enhancer.create();
    proxy.request();
  }
}

您可以看到,首先在客户端代码中创建了一个Enhancer对象,并且设置了父类和代理回调类对象. Enhancer对象为目标类创建相关的子类字节码,并将代理代码嵌入到子类字节码中.

本文主要详细介绍了代理模式的三种实现模式,并比较了每种代理模式的优缺点. Spring主要使用动态代理模式来实现方面编程. 读者在这里可能会有一个问题,即在上面的代理代码中,根据实现的不同,客户端代码有些侵入性,例如静态代理客户端需要入侵代理类实例,jdk代理需要入侵代理类. Cglib代理需要插入子类和子类对象创建代码. 从理论上讲,客户端仅需要获取目标对象(无论它是否是代理),然后调用其相关方法即可实现特定功能. 这实际上是工厂方法的强大功能,因为工厂方法封装了对象的创建. 对象的特定创建过程可以根据特定业务进行处理. 客户只需要依靠工厂类来调用相关方法. 这也解释了为什么Spring IoC容器是AOP代理的自然支持,因为它将对象创建过程留给了容器.


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-161139-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...