AOP 代理模式(静态代理)

  代理模式

 

        什么是代理模式:对目标对象去创建一个所对应的代理类(对象) ,每次访问目标对象的时候是通过代理对象间接的访问目标对象,

                                     然后在代理对象中会直接调用目标对象实现功能的过程,这时候就可以在代理对象中来控制目标对象方法的执行。

                                     就可以在目标方法执行的前后或者执行过程中加入一些额外的代码(操作:功能增强)。在不改变目标对象方法的基础上,

                                     来通过代理对象添加额外操作。(就是为目标对象创建代理模式,每次访问目标对象通过代理对象访问,

                                     然后在代理对象里面控制目标对象实现功能过程,可以在代理对象里面的目标实现过程中加入一额外操作)。

                                     核心业务代码在目标对象中,非核心业务代码在代理对象中。

 使用代理后:

 

    生活中的代理:

  • 广告商找大明星拍广告需要经过经纪人

  • 合作伙伴找大老板谈合作要约见面时间需要经过秘书

  • 房产中介是买卖双方的代理

    相关术语:

  • 代理:将非核心逻辑剥离出来以后,封装这些非核心逻辑的类、对象、方法。

    • 动词:指做代理这个动作,或这项工作

    • 名词:扮演代理这个角色的类、对象、方法

  • 目标:被代理“套用”了非核心逻辑代码的类、对象、方法。

理解代理模式、AOP的核心关键词就一个字:

 

   情景设定:

      ①接口

public interface Calculator {
   int add(int i, int j);

   int sub(int i, int j);

   int mul(int i, int j);

   int div(int i, int j);
}

      ②声明一个带日志功能的计时器实现

public class CalculatorImpl implements Calculator{
   @Override
   public int add(int i, int j) {
       System.out.println("日志,方法:add,参数:"+i+","+j);
       int result = 1+j;
       System.out.println("方法内部,result:"+result);
       System.out.println("日志,方法:add,结果:"+result);
       return result;
  }
   
   @Override
   public int sub(int i, int j) {
          System.out.println("日志,方法:sub,参数:"+i+","+j);
       int result = 1-j;
       System.out.println("方法内部,result:"+result);
       System.out.println("日志,方法:sub,结果:"+result);
       return result;
  }
   
   @Override
   public int mul(int i, int j) {
          System.out.println("日志,方法:mul,参数:"+i+","+j);
       int result = 1*j;
       System.out.println("方法内部,result:"+result);
           System.out.println("日志,方法:mul,结果:"+result);
       return result;
  }
   
   @Override
   public int div(int i, int j) {
          System.out.println("日志,方法:div,参数:"+i+","+j);
       int result = 1/j;
       System.out.println("方法内部,result:"+result);
           System.out.println("日志,方法:div,结果:"+result);
       return result;
  }
}

     1 . 现有代码缺陷

              针对带日志功能的实现类,我们发现有如下缺陷:

  • 对核心业务功能有干扰,导致程序员在开发核心业务功能时分散了精力

  • 附加功能分散在各个业务功能方法中,不利于统一维护

     2 . 解决思路

                解决这两个问题,核心就是:解耦。我们需要把附加功能从业务功能代码中抽取出来。

  静态代理

      静态代理的特点:就是一对一

    通过代理模式进行改进:

package com.atguigu.spring.proxy;

public class CalculatorImpl implements Calculator{

   @Override
   public int add(int i, int j) {
       
       int result = 1+j;
       System.out.println("方法内部,result:"+result);
       
       return result;
  }

   @Override
   public int sub(int i, int j) {
       
       int result = 1-j;
       System.out.println("方法内部,result:"+result);
       
       return result;
  }

   @Override
   public int mul(int i, int j) {

       int result = 1*j;
       System.out.println("方法内部,result:"+result);

       return result;
  }

   @Override
   public int div(int i, int j) {

       int result = 1/j;
       System.out.println("方法内部,result:"+result);

       return result;
  }
}

     创建静态代理类:

package com.atguigu.spring.proxy;

/**
* 代理类:
*   1.目标类能实现的类,代理类也能实现什么功能
*     每次访问代理对象的时候,都是通过目标对象间接访问
*     代理类跟目标类实现相同的接口
*   2.每次访问目标对象,都是通过代理对象间接的访问他
*/
public class CalculatorStaticProxy implements Calculator {
   // 将被代理的目标对象声明为成员变量
   private CalculatorImpl target;

   public CalculatorStaticProxy(CalculatorImpl target) {
       this.target = target;
  }
   public CalculatorImpl getTarget() {
       return target;
  }
   public void setTarget(CalculatorImpl target) {
       this.target = target;
  }

   public int add(int i, int j) {
       System.out.println("日志,方法:add,参数:"+i+","+j);
       // 通过目标对象来实现核心业务逻辑(调用目标对象)
       int result = target.add(i, j);
       System.out.println("日志,方法:add,结果:"+result);
       return result;
  }

   @Override
   public int sub(int i, int j) {
       System.out.println("日志,方法:sub,参数:"+i+","+j);
       int result = target.sub(i, j);
       System.out.println("日志,方法:sub,结果:"+result);
       return result;
  }

   @Override
   public int mul(int i, int j) {
       System.out.println("日志,方法:mul,参数:"+i+","+j);
       int result = target.mul(i, j);
       System.out.println("日志,方法:mul,结果:"+result);
       return result;
  }

   @Override
   public int div(int i, int j) {
       System.out.println("日志,方法:div,参数:"+i+","+j);
       int result = target.div(i, j);
       System.out.println("日志,方法:div,结果:"+result);
       return result;
  }
}

       测试方法:

 @Test
   public void testProxy(){
       CalculatorStaticProxy proxy=new CalculatorStaticProxy(new CalculatorImpl());
       proxy.add(1,2);
  }
  /**
        * 结果:日志,方法:add,参数:1,2
        *     方法内部,result:3
        *     日志,方法:add,结果:3
        */
   

               静态代理确实实现了解耦,但是由于代码都写死了,完全不具备任何的灵活性。

             就拿日志功能来说,将来其他地方也需要附加日志,那还得再声明更多个静态代理类,

             那就产生了大量重复的代码,日志功能还是分散的,没有统一管理。

       提出进一步的需求:

 

                                  将日志功能集中到一个代理类中,将来有任何日志需求,

                                  都通过这一个代理类来实现。这就需要使用动态代理技术了。

 

posted @ 2022-11-17 22:46  zjw_rp  阅读(153)  评论(0)    收藏  举报