一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第18天,点击查看活动详情。
Spring中的设计模式
简单工厂模式
什么是简单工厂?
通过一个xxxFactory的一个方法,可以通过唯一标示来获取到你想要的那个抽象类的实现对象
举例说明?
抽象类:球
实现类:红球、白球、大球、小球
工厂:球工厂,方法参数(颜色,大小)
这样就可以在工厂中获取到颜色为红大小为小的红色小球。
Spring中如何体现?
Spring中的BeanFactory是简单工厂的最直接实现方式。
加入工厂:在项目启动的时候针对每个需要加入的类创建他的BeanDefinition对象,然后将其加入到Spring常量池ConcurrentHashMap中
获取:就使用ConcurrentHashMap的key进行获取。在整个项目中只要是命名为这个key的该类对象,无论是否实例化都会默认给new出一个对象赋值给它
Spring为什么要这样用?
优点:
- 松耦合
- 工厂的统一化管理可以在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;
}