动态代理设计模式[Spring AOP原理(核心模式)]-----附静态代理

1,反射与代理设计模式 
代理设计模式的核心本质在于:1个接口有两个子类,一个负责真实业务,一个负责其他的辅助业务 
2 , 动态代理类绑定真实 对象 
java提供的动态代理实现

//主体接口
interface ISubject{
    public void eat(String food,int num);
}

//真实操作类
class Subject implements ISubject{

    @Override
    public void eat(String food, int num) {
        System.out.println("吃了"+num+"份"+food);
    }

}
//动态代理类[伪代理],想使用动态代理必须实现此接口
class ProxySubject implements InvocationHandler{

    private Object target;

    //动态代理绑定真实业务对象 返回动态代理对象
    public Object bind(Object target){
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    public void eatParpre(){
        System.out.println("准备食物");
    }

    public void eatClear(){
        System.out.println("吃完啦,刷盘子");
    }

    //Spring的Aop核心就是使用的动态代理
    //method存储的是真实业务对象的方法对象[eat方法对象]
    //args参数 此处应该是我传递的 "鸡腿", 20 看下图
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        this.eatParpre();
        //使用反射调用核心业务方法
        Object ret = method.invoke(target, args);
        this.eatClear();
        return ret;
    }

}

public class ProxyTest {

    public static void main(String[] args) {
        //调用
        ISubject subject = (ISubject)new ProxySubject().bind(new Subject());
        //subject调用eat的时候会触发代理对象调用invoke方法,在invoke方法里使用反射调用真实业务方法
        subject.eat("鸡腿", 20);
    }
}

运行结果:
准备食物
吃了20份鸡腿
吃完啦,刷盘子

静态代理模式:

例子场景:打架 
如: 
桃花岛比武抢亲之战 —— 郭靖与欧阳克 
华山论剑正邪之战 —— 北丐洪七公和西毒欧阳峰 
小朋友梦想之战 —— 奥特曼与铠甲勇士 

这些战斗之中,都要打架,但是打架之前需要有一些前期准备,打架(实战)工作由目标对象实现,而前期的准备(练功)工作则由代理对象实现。

静态代理实现方式一

真实打架行为接口:

public interface IRealFight{
    void fight();
}
  • 1
  • 2
  • 3

抢亲之战:

public class QiangQinFightImpl implements IRealFight{

    @Override
    public void fight(){
        System.out.println("郭靖和欧阳克战斗!");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

正邪之战:

public class GoodEvilFightImpl implements IRealFight{

    @Override
    public void fight(){
        System.out.println("北丐洪七公和西毒欧阳锋战斗!");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

梦想之战

public class DreamFightImpl implements IRealFight{

    @Override
    public void fight(){
        System.out.println("奥特曼和铠甲勇士战斗!");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

真实战斗代理类 
以上的战斗都需要提前练功,练功的准备由代理类实现

public class ProxyVirtualFight implements IRealFight{

    //需要给我一个目标对象
    private IRealFight targetFight;

    //给了我一个目标对象
    public ProxyVirtualFight(IRealFight targetFight){
        this.targetFight = targetFight;
    }

    /** * 我来负责全程打架,包括前期练功和实际战斗 */
    @Override
    public void fight(){
        //前期练功
        System.out.println("战斗双方正在练功,请不要打扰我们!!!");
        //实际战斗开始
        targetFigth.fight();
        //战斗结束
        System.out.println("这场战斗结束了.");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

观众需求: 
观众想要看他们自己想要的任意一场战斗

public class Client{

    public static void main(String[] args){
        //=====广场大妈,我们想要看【抢亲之战】=====
        //1.战斗对象准备好了
        QiangQinFightImpl qiangQin = new QiangQinFightImpl();
        //2.代理对象也准备好了
        ProxyVirtualFight proxy1 = new ProxyVirtualFight(qiangQin);
        //3.开始战斗
        proxy1.fight();

        //=====二B青年,我们想要看【正邪之战】=====
        //1.战斗对象准备好了
        GoodEvilFightImpl goodEvil = new GoodEvilFightImpl();
        //2.代理对象也准备好了
        ProxyVirtualFight proxy2 = new ProxyVirtualFight(goodEvil);
        //3.开始战斗
        proxy2.fight();     

        //=====祖国花朵,我们想要看【梦想之战】=====
        //1.战斗对象准备好了
        DreamFightImpl dream = new DreamFightImpl();
        //2.代理对象也准备好了
        ProxyVirtualFight proxy3 = new ProxyVirtualFight(dream);
        //3.开始战斗
        proxy3.fight(); 
    }
}

一、中介隔离作用

  代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合

或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用, 其特征是

代理类与委托类有同样的接口。代理模式是常用的java设计模式。

表现形式如下:

            《动态代理设计模式[Spring AOP原理(核心模式)]-----附静态代理》

       以上一张图就是当初对代理模式的认识。


二、开闭原则,增加功能,

     现在有了进一步的认识。代理类不仅仅是一个隔离客户端和委托类的中介。我们还可以借助代理来在

增加一些功能,而不需要修改原有代码,严重的复合开闭原则哦。

    代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。

代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的

对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。

     就是这样,真正的业务功能还是有委托类来实现,但是在实现业务类之前的一些公共服务。例如

在项目开发中我们没有加入缓冲,日志这些功能,后期想加入,我们就可以使用代理来实现,而没有

必要打开已经封装好的委托类。

三、代理的分类

    根据以上对代理的理解,对于代理的具体实现,我们有不同的方式,如果按照代理的创建时期,

代理类可以分为两种。:静态代理、动态代理。
    静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的

.class文件就已经存在了。 
    动态代理:在程序运行时,运用反射机制动态创建而程。

    原文作者:AOP
    原文地址: https://blog.csdn.net/ld395353765/article/details/81006499
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞