Spring中的用到的设计模式

工厂模式

Spring使用工厂模式可以通过 BeanFactory 或 ApplicationContext 创建 bean 对象, 根据传入一个唯一的标识来获得Bean对象 。

单例模式

在我们的系统中,有一些对象其实我们只需要一个,比如说:线程池、缓存、对话框、注册表、日志对象、充当打印机、显卡等设备驱动程序的对象。事实上,这一类对象只能有一个实例,如果制造出多个实例就可能会导致一些问题的产生,比如:程序的行为异常、资源使用过量、或者不一致性的结果。

使用单例模式的好处:

  • 对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销;
  • 由于 new 操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻 GC 压力,缩短 GC 停顿时间。

Spring 中 bean 的默认作用域就是 singleton(单例)的。除了 singleton 作用域,Spring 中 bean 还有下面几种作用域:

  • prototype : 每次请求都会创建一个新的 bean 实例。
  • request : 每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。
  • session : 每一次HTTP请求都会产生一个新的 bean,该bean仅在当前 HTTP session 内有效。
  • global-session: 全局session作用域,仅仅在基于portlet的web应用中才有意义,Spring5已经没有了。Portlet是能够生成语义代码(例如:HTML)片段的小型Java Web插件。它们基于portlet容器,可以像servlet一样处理HTTP请求。但是,与 servlet 不同,每个 portlet 都有不同的会话

Spring 实现单例的方式:

<bean id="userService" class="top.snailclimb.UserService" scope="singleton"/>
@Scope(value = "singleton")

代理模式

代理模式的定义:代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。

Spring AOP 就是基于动态代理的,如果要代理的对象,实现了某个接口,那么Spring AOP会使用 JDK Proxy ,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候Spring AOP会使用 Cglib ,这时候Spring AOP会使用 Cglib 生成一个被代理对象的子类来作为代理 。

模板模式

模板方法模式是一种行为设计模式,它定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。 模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤的实现方式。

Spring 中 jdbcTemplate 、 hibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。一般情况下,我们都是使用继承的方式来实现模板模式,但是 Spring 并没有使用这种方式,而是使用Callback 模式与模板方法模式配合,既达到了代码复用的效果,同时增加了灵活性。

观察者模式

观察者模式是一种对象行为型模式。它表示的是一种对象与对象之间具有依赖关系,当一个对象发生改变的时候,这个对象所依赖的对象也会做出反应。Spring 事件驱动模型就是观察者模式很经典的一个应用。Spring 事件驱动模型非常有用,在很多场景都可以解耦我们的代码。

Spring 的事件流程总结

  1. 定义一个事件: 实现一个继承自 ApplicationEvent ,并且写相应的构造函数;
  2. 定义一个事件监听者:实现 ApplicationListener 接口,重写 onApplicationEvent() 方法;
  3. 使用事件发布者发布消息: 可以通过 ApplicationEventPublisher 的 publishEvent() 方法发布消息。

适配器模式

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。

解决一个类实现接口时无需实现接口的中所有方法

  1. 接口的实现类一般实现接口就要实现所有方法,但是有时候并不需要亲自实现所有方法,所以就出现了矛盾。
  2. 适配器模式 使用一个抽象类去实现接口的部分方法,其他方法留给继承该抽象类的子类去实现,这样一来该子类就可以选择实现接口的部分方法。
  3. 注:适配器模式下 子类还是拥有 接口的所有方法(继承思想),子类是抽象类的子类也是接口的实现类。

Spring AOP中的适配器模式

我们知道 Spring AOP 的实现是基于代理模式,但是 Spring AOP 的增强或通知(Advice)使用到了适配器模式,与之相关的接口是 AdvisorAdapter 。

Advice 常用的类型有: BeforeAdvice(目标方法调用前,前置通知)、 AfterAdvice (目标方法调用后,后置通知)、 AfterReturningAdvice (目标方法执行结束后,return之前)等等。每个类型Advice(通知)都有对应的拦截器: MethodBeforeAdviceInterceptor 、 AfterReturningAdviceAdapter 、 AfterReturningAdviceInterceptor 。Spring预定义的通知要通过对应的适配器,适配成 MethodInterceptor 接口(方法拦截器)类型的对象(如: MethodBeforeAdviceInterceptor 负责适配 MethodBeforeAdvice )。

装饰者模式

装饰者模式可以动态地给对象添加一些额外的属性或行为。相比于使用继承,装饰者模式更加灵活。简单点儿说就是当我们需要修改原有的功能,但我们又不愿直接去修改原有的代码时,设计一个Decorator套在原有代码外面。其实在 JDK 中就有很多地方用到了装饰者模式,比如 InputStream 家族, InputStream 类下有 FileInputStream (读取文件)、 BufferedInputStream (增加缓存,使读取文件速度大大提升)等子类都在不修改 InputStream 代码的情况下扩展了它的功能。

策略模式

定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。

Spring的事务管理,PlatformTransactionManager代表事务管理接口,但是它不知道底层如何管理事务,它只要求事务管理,提供l开始事务(getTransaction(),commit(),rollback()三个方法,但是如何实现则交给具体实现类来完成不同的实现类代表不同的事务管理策略。

参考资料