• 设计模式--代理模式


      代理模式是一种结构型设计模式,它可以为其他对象提供一种代理以控制对这个对象的访问。

      所谓的代理,是指具有与被代理对象相同的接口的类,客户端必须通过代理与被代理的目标类进行交互,而代理一般在交互的过程中(交互前后),进行某些特定的处理。


    代理模式中的角色:

    1.抽象对象角色

    声明了目标类及代理类对象的共同接口,这样在任何可以使用目标对象的地方都可以使用代理对象。

    2.目标对象角色

    定义了代理对象所代表的目标对象。

    3.代理对象角色

    代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;代理对象和目标对象具有统一的接口,以便可以在任何时候替代目标对象。代理对象通常在客户端调用传递给目标对象之前或者之后,执行某些操作,而非单纯的将调用传递给目标对象。

    示例代码:

    首先定义AbstractObject类,在其中定义代理类和目标类有公有的接口operation()

    1 public abstract class AbstractObject{
    2  protected abstract void operation();
    3 }

    目标实现类:

    1 public class RealObject extends AbstractObject{
    2 
    3     @Override
    4     protected void operation() {
    5         System.out.println("do operation...");
    6     }
    7 }

    代理类:

     1 package staticproxy;
     2 
     3 public class ProxyObject extends AbstractObject{
     4 
     5     private RealObject realObject;
     6     
     7     public ProxyObject(RealObject realObject) {
     8         this.realObject=realObject;
     9     }
    10 
    11     @Override
    12     protected void operation() {
    13         System.out.println("do something before real peration...");
    14         if(realObject==null) {
    15             realObject=new RealObject();
    16         }
    17         realObject.operation();
    18         System.out.println("do something after real operation...");
    19     }
    20 }

    测试类:

    1 package staticproxy;
    2 
    3 public class ProxyTest {
    4 
    5     public static void main(String[] args) {
    6         AbstractObject proxy = new ProxyObject(new RealObject());
    7         proxy.operation();
    8     }
    9 }

     执行结果:

     总结:

    代理模式的使用场景:

    如果已有的方法在使用的时候需要对原有的方法进行改进,此时有两种方法:

    (1)修改原有的方法来适应。

    (2)采用一个代理类调用原来的方法,且对产生的结果进行控制。

    使用代理模式可以将功能划分的更加清晰,有助于后期的维护。

    以上所说的这种代理模式称为静态代理

    动态代理(也叫JDK代理)

    jdk中的动态代理通过反射类Proxy和InvocationHandler回调接口实现,要求委托类必须实现一个接口,只能对该类接口中定义的方法实现代理,这在实际边中有一定的局限性。

    见另一篇

    Cglib代理

    使用cglib[Code Generation Library]实现动态代理,并不要求委托类必须实现接口,底层采用asm字节码生成框架生成代理类的字节码。

    https://www.cnblogs.com/chinajava/p/5880887.html----cglib动态代理解释

    前提条件:

    *需要引入cglib的jar文件,由于Spring的核心包中已经包括了Cglib功能,所以也可以直接引入spring-core-3.2.5.jar

    *目标类不能为final

    *目标对象的方法如果为final/static,那么就不会拦截,即不会执行目标对象额外的业务方法

    cglib的jar包---cglib-nodep-2.2.2.jar

    目标对象,没有实现任何接口 Singer.java

     1 package CglibProxy;
     2 //目标对象,没有实现任何接口
     3 public class Singer {
     4     public void sing() {
     5         System.out.println("唱一首歌");
     6     }
     7     public void myname() {
     8         System.out.println("我叫彭于晏");
     9     }
    10 }

    子类代理工厂--ProxyFactory.java

     1 //Cglib子类代理工厂
     2 public class ProxyFactory implements MethodInterceptor{
     3 
     4     //维护目标对象
     5     private Object target;
     6     //构造函数
     7     public ProxyFactory(Object target) {
     8         this.target=target;
     9     }
    10     
    11     //创建代理类对象
    12     public Object getProxyInstance() {
    13         //1.工具类
    14         Enhancer en=new Enhancer();
    15         //2.设置父类
    16         en.setSuperclass(target.getClass());
    17         //3.设置回调函数
    18         en.setCallback(this);
    19         //4.创建子类(代理对象)
    20         return en.create();
    21     }
    22     
    23     //重写的方法        拦截
    24     @Override
    25     public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
    26         System.out.println("向观众问好");
    27         //执行目标对象的方法
    28         Object returnValue=arg1.invoke(target, arg2);
    29         System.out.println("谢谢大家");
    30         return returnValue;
    31     }
    32 }

    这里的代码也非常固定,只有标黄部分是需要自己写出

    测试

     1 package CglibProxy;
     2 
     3 public class Test {
     4     public static void main(String[] args) {
     5         //目标对象
     6         Singer target=new Singer();
     7         //代理对象
     8         Singer proxy=(Singer)new ProxyFactory(target).getProxyInstance();
     9         //执行代理对象的方法
    10         proxy.myname();
    11         proxy.sing();
    12     }
    13 }
  • 相关阅读:
    BFS 简单思想以及代码
    01、Hibernate安装配置
    WireShark——ARP 协议包分析
    eNSP之VLAN设计实验
    eNSP 交换机 路由器 PC 互连设计/实现
    Windows常用的网络命令
    01、Git安装教程(windows)
    Java IO编程——文件拷贝
    Java 多线程编程——多线程
    Java IO编程——转换流
  • 原文地址:https://www.cnblogs.com/xjs1874704478/p/10741743.html
Copyright © 2020-2023  润新知