SpringAOP静态代理

1、本篇博客的背景和目的

目前我本人正在学习SpringFramework的知识,这也是这个专栏的主题。我前面的几篇博文中,简单的认识了一下SpringFramework,记录了SpringFramework的环境搭建,记录了SpringIOC如何加载配置文件,记录了SpringIOC三种Bean对象的实例化方法。还记录了SpringIOC手动装配(注入)的方法之一:set方法注入。还有另外三个不太常用的SpringIOC手动注入的方法。其实目前大部分都使用的是自动注入的方法,手动注入使用的不多。就算是使用手动注入的方法,使用的主流也是:set方法注入。自动注入的方法主要是使用两个注解,@Autowired注解或者是@Resource注解。两个注解我都记录到了。还记录了如何使用SpringIOC扫描器,SpringIOC中Bean对象的作用域和生命周期,SpringTask的概念和简单使用。本篇博客我记录一下SpringAOP的静态代理的概念和简单使用。

2、我的上一篇博文

我的上一篇博文记录的是SpringTask的概念和简单使用,链接如下:

SpringTask定时任务的概念和简单使用_你是我的日月星河的博客-CSDN博客https://blog.csdn.net/weixin_46281472/article/details/125239290?spm=1001.2014.3001.5501

3、SpringAOP的概念和需要学习的相关知识

首先我粘贴一张图片,展示一下SpringAOP的学习方向,如下所示:

SpringAOP静态代理_第1张图片

如上图所示,SpringAOP的代理模式分为两种,分别是静态代理和动态代理。其实我们工作中真正使用的比较多的是动态代理。动态代理呢,又分为JDK动态代理和CGLIB动态代理(这种需要引入第三方的依赖)。

首先我们先了解一下什么是代理模式:代理模式是JAVA开发中一种比较常见的设计模式;它的设计目的是  旨在为服务类和客户类之间插入其他功能,插入的功能对于调用者来说是透明的,起到伪装控制的作用;

打个比方吧:比如租房子,房客,中介,房东;对应于代理模式中也就是:客户类,代理类,委托类(被代理类)。

为某一个对象(委托类)提供一个代理(代理类),用来控制对这个对象的访问。委托类和代理类有一个共同的父类或者父接口;代理类会对请求做预处理,过滤,将请求分配给指定对象;

生活中类似代理的情况有很多啊:婚庆公司,租房中介,律师事务所;

代理模式有两个设计原则:

1、代理类 与  委托类  具有相似的行为(共同)

2、代理类增强委托类的行为;

常见的代理模式有:静态代理,动态代理;

4、静态代理的概念

介绍一下静态代理

为某一个对象提供一个代理,代理角色是固定的,是为了控制对这个角色的访问;代理类和委托类有共同的父类或者是父接口,这样在任何使用委托类对象的地方都可以使用代理对象替代;代理类负责请求的预处理,过滤,将请求分派给委托类处理,以及委托类执行完请求后的后续处理;

代理的三要素:有共同的行为(父接口,比如租房吧);目标角色(实现行为,比如有房子的人);代理角色(租房中介  也是实现行为,增强目标角色行为);

三要素可以理解为:  谁委托谁做什么事情;

静态代理的特点:

1、目标角色固定;可以说是委托类固定。

2、在应用程序执行前就得到目标角色;

3、代理对象会增强目标对象的行为;

4、有可能存在多个代理,引起“ 类爆炸” (缺点)(比如说吧,租房要有一个代理,结婚要有一个代理,租车要有一个代理     代理太多了)

5、静态代理的简单代码实现

静态代理其实真正使用的不多,真正使用的是动态代理。所以这里我就不做很复杂的代码实现了。

SpringAOP静态代理_第2张图片

如上图所示,我们首先创建一个 RentHouse接口,这个接口就是我们的共同行为   

共同行为RentHouse接口的代码如下:

package com.dcy.statics;

/*
这个是父类或者是父接口   也就是委托类和代理类共同的行为
 */
public interface RentHouse {

    public void toRentHouse();

    public String toRentHouse2(String name);
}

 里面有两个方法,后面的代理类和委托类都需要继承实现这个接口。

然后就是我们的委托类(也就是想要出租房子的人) You,代码如下:

package com.dcy.statics;

/*
静态代理
下面这个是我们的 目标对象  也就是 委托类
 */
public class You implements RentHouse{
    @Override
    public void toRentHouse() {
        System.out.println("我要租一个两室一厅");
    }

    @Override
    public String toRentHouse2(String name) {
        System.out.println(name+"要第二次租房");
        return "好的吧";
    }
}

很明显,上面的委托类继承实现了共同行为接口RentHouse。

然后就是我们的代理类(也就是租房中介)Agency,代码如下:

package com.dcy.statics;

/*
静态代理
这个是代理类  实现行为,还要增强目标对象的行为,
 */
public class Agency implements RentHouse{

    private RentHouse target;

    //下面我们需要提供一个有参构造,传递我们的目标对象
    public Agency(RentHouse target) {
        this.target = target;
    }
    @Override
    public void toRentHouse() {
        //下面这句话也是增强了行为
        System.out.println("这里是中介");
        target.toRentHouse();
        System.out.println("准备合同");
    }

    @Override
    public String toRentHouse2(String name) {
        return null;
    }
}

上面是代理类,类似于租房中介,代替房东行使一定的权力。既然是代理类,肯定和委托类是有相同的行为的,那么也是需要继承实现共同行为接口RentHouse的。既然是代理类,那么它究竟是谁的代理呢?为了体现它是谁的代理这一点,我们在代理类中加入了一个私有的成员变量,类型是RentHouse类型(共同行为接口),然后加入了一个有参构造,用来初始化这个私有成员变量。私有成员变量初始化以后,我们就可以在代理类的方法里面使用这个私有成员变量(也就是委托类对象,因为委托类对象实现了共同行为接口)的方法行为。

最后我们在Main方法里面进行一下简单的测试,代码如下所示:

package com.dcy.statics;

public class Starter {
    public static void main(String[] args) {
        You you=new You();
        Agency agency=new Agency(you);
        agency.toRentHouse();
    }
}

运行结果如下所示:

SpringAOP静态代理_第3张图片

我们需要明白的一点是:代理类最终调用的还是我们委托类中的方法;这一点是很容易从我上面简单的示例代码中看出来的。

如果我们的委托类有很多想要代理的事情,那么就需要有多个接口,有多个代理类;这明显是很麻烦的,也是静态代理的缺点,多以静态代理我们真正是不用的,用的是动态代理。

上述的例子是非常简单的例子,具体的使用肯定是很复杂的;

但是我们一般也是不使用静态代理的;

6、我的下一篇博文

下一篇博文我介绍一下真正使用的动态代理,链接如下所示:

你可能感兴趣的:(记录学习SpringMVC,SpringFramework,java,spring,代理模式)