「Spring」Spring中使用的设计模式(一)

82 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第18天,点击查看活动详情

Spring中的设计模式

简单工厂模式

什么是简单工厂?

通过一个xxxFactory的一个方法,可以通过唯一标示来获取到你想要的那个抽象类的实现对象

举例说明?

抽象类:球

实现类:红球、白球、大球、小球

工厂:球工厂,方法参数(颜色,大小)

这样就可以在工厂中获取到颜色为红大小为小的红色小球。

Spring中如何体现?

Spring中的BeanFactory是简单工厂的最直接实现方式。

加入工厂:在项目启动的时候针对每个需要加入的类创建他的BeanDefinition对象,然后将其加入到Spring常量池ConcurrentHashMap中

获取:就使用ConcurrentHashMap的key进行获取。在整个项目中只要是命名为这个key的该类对象,无论是否实例化都会默认给new出一个对象赋值给它

Spring为什么要这样用?

优点:

  1. 松耦合
  2. 工厂的统一化管理可以在Spring中增添很多扩展功能。比如各种的aware方法,Bean的初始化方法等。这也是Spring能集合各种框架进行统一开发的根本

工厂方法

什么事工厂方法?

也可以称为抽象工厂设计模式。通俗的讲就是工厂的工厂。

工厂方法将具体的对象的实例下放到具体的工厂去实现,而这个工厂的工厂要做的就是告诉这些工厂如何协调实现。

举例说明?

抽象类:球

抽象工厂:色彩工厂、材质工厂

实现类:塑料红球、玻璃白球

所以调用者需要先实例化出来具体的色彩工厂和材质工厂的对象,才能实例出来具体的实现类。

目的就是在球的颜色和材质的基础上扩宽功能的时候能更加方便。比如扩宽球的形状

Spring中如何实现?

Spring中有一个接口叫做FactoryBean

Spring为什么要这么用?

我们在将业务抽离出来形成抽象工厂的时候,Spring也在想怎么管理这些工厂。所以就建立了一个工厂的工厂

打个比方:Mapper文件,我们用的时候发现@Mapper注解的相关xml我们可以使用@select@update注解直接进行操作。那么我们将Mapper作为一个工厂。那么Spring就将Mapper、Service、Controller的生产厂商叫做工厂的工厂来统一化管理这些工厂都具有依赖注入的功能

单例模式

什么是单例模式?

老生长谈了,就是这个对象只提供一个实例供所有的逻辑使用。

举例说明?

在开发OA系统的时候,总是会有直属上级的概念。直属上级一般只有一个,这个时候针对这个用户的直属上级对象就只能获取一个,无论什么时候都只能获取到的是同一个

实现上:

  • 禁止外部调用构造方法
  • 获取对象的时候判断对象是否存在,存在则返回原本的

Spring如何使用单例模式?

1、在类的创建上可以增加注解@Scope来标明该类以后管理的模式是什么样的,其中可以用到的参数是:

  • singleton:每次都是同一个对象
  • prototype:每次都是不同的对象
  • request:每次的请求都是一个对象-web
  • session:每个请求的session相同就是一个对象-web
  • application:每个应用程序创建和销毁进行管理(WebServlet)-web

2、在项目启动Spring将每个类加载到Spring池中的时候会根据这个参数的结果来加入对应的池

3、获取的时候

    @Nullable
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        //从一级缓存Bean池中使用beanName获取对象
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                //从二级缓存Bean池中使用beanName获取对象
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    //缓存Bean池都获取不到就获取这个BeanName对应的工厂类
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        //使用工厂类获取这个对象并放入一级二级缓存中
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }