Spring中设计模式详解

1. 工厂设计模式

Spring使用工厂模式可以通过BeanFactory或ApplicationContext创建bean对象

两者对比:

**BeanFactory:**延迟注入(使用到某个bean的时候才会注入),相比与ApplicationContext来说会占用更少的内存,程序启动更快。

**ApplicationContext:**容器启动的时候,不管你用没用到,一次性创建所有的bean。BeanFactory仅提供了最基本的依赖注入支持,ApplicationContext扩展了BeanFactory,除了有BeanFactory的功能还有额外更多功能。

ApplicationContext的三个实现类

1.ClassPathXmlApplication:把上下文文件当成类路径资源

2.FileSystemXmlApplication:从文件系统中的XML文件载入上下文定义信息。

3.XmlWebApplicationContext:从Web系统中的XML文件载入上下文定义。

2.单例设计模式

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

使用单例模式的好处:

1.对应频繁使用的对象,可以省略创建对象所花费的时间, 这对于哪些重量级对象而言,是一笔非常可观的系统开销。

2.由于new操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻GC压力,缩短GC停顿时间。

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

**prototype:**每次获取都会创建一个新的bean实例,也就是说,连续getBean()两次,得到的是不同的Bean实例。

request(仅web应用可用): 每一次HTTP请求都会产生一个新的bean(请求bean),该bean仅在当前HTTP request内有效。

session(仅web应用可用): 每一次来自新session的HTTP请求都会产生一个新的bean(会话bean),该bean 仅在当前的HTTP session内有效。

**application/global-session(仅web应用可用):**每个web应用在启动时bean(应用bean),该bean仅在当前应用启动时间内有效。

**websocket(仅web应用可用):**每一次webscoket会话产生一个新的bean。

单例Bean存在线程安全问题吗?

单例Bean存在线程问题,主要是因为多个线程操作同一个对象的时候是存在资源竞争的。

解决方法:

1.在Bean中尽量避免定义可变的成员变量。

2.在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在ThreadLocal中

不过大部分Bean的实际都是无状态的,这种情况下,Bean是线程安全的。

3.观察者模式

观察者模式是一种对象行为型模式。它表示的是一种对象与对象之间具有依赖关系,当一个对象发生改变的时候,依赖这个对象的所有对象也会做出反应。Spring 事件驱动模型就是观察者模式很经典的一个应用。Spring 事件驱动模型非常有用,在很多场景都可以解耦我们的代码。比如我们每次添加商品的时候都需要重新更新商品索引,这个时候就可以利用观察者模式来解决这个问题。

Spring事件驱动模型的三种角色:

1.事件角色

ApplicationEvent充当事件的角色,这是一个抽象类,它继承了java.util.EventObject并实现了java.io.Serializable接口。

Spring中默认存在以下事件,他们都是对ApplicationCOntextEvent的实现:

ContextStartedEvent: ApplicationContext启动后触发的事件;

ContextStoppedEvent:ApplicatonContext停止后触发的事件;

ContextRefreshedEvent:ApplicationContext初始化或刷新完成后触发的事件;

COntextClosedEvent:ApplicationCOntext关闭后触发的事件

2.事件监听者角色

ApplicationListener 充当了事件监听者角色,它是一个接口,里面只定义了一个 onApplicationEvent()方法来处理ApplicationEventApplicationListener接口类源码如下,可以看出接口定义看出接口中的事件只要实现了 ApplicationEvent就可以了。所以,在 Spring 中我们只要实现 ApplicationListener 接口的 onApplicationEvent() 方法即可完成监听事件

3.事件发布者角色

ApplicationEventPublisher 充当了事件的发布者,它也是一个接口。ApplicationEventPublisher 接r口的publishEvent()这个方法在AbstractApplicationContext类中被实现,阅读这个方法的实现,你会发现实际上事件真正是通过ApplicationEventMulticaster来广播出去的。

Spring事件流程总结

1.定义一个事件:实现一个继承自ApplicationEvent,并且写相应的构造函数

2.定义一个事件监听者:实现Application接口,重写onApplicationEvent()方法

3.使用事件发布者发布消息:可以通过ApplicationEventPiblisher的publishEvent()方法发布消息

4.适配器模式

适配器模式就是将一个接口转化成客户想要的接口,适配器模式使接口不兼容的那些类可以一起工作

SpringAOP中的适配器模式

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

Advice 常用的类型有:BeforeAdvice(目标方法调用前,前置通知)、AfterAdvice(目标方法调用后,后置通知)、AfterReturningAdvice(目标方法执行结束后,return 之前)等等。每个类型 Advice(通知)都有对应的拦截器:MethodBeforeAdviceInterceptorAfterReturningAdviceInterceptorThrowsAdviceInterceptor 等等。

Spring 预定义的通知要通过对应的适配器,适配成 MethodInterceptor 接口(方法拦截器)类型的对象(如:MethodBeforeAdviceAdapter 通过调用 getInterceptor 方法,将 MethodBeforeAdvice 适配成 MethodBeforeAdviceInterceptor )。

Spring MVC中的适配器模式

在 Spring MVC 中,DispatcherServlet 根据请求信息调用 HandlerMapping,解析请求对应的 Handler。解析到对应的 Handler(也就是我们平常说的 Controller 控制器)后,开始由HandlerAdapter 适配器处理。HandlerAdapter 作为期望接口,具体的适配器实现类用于对目标类进行适配,Controller 作为需要适配的类。

5.装饰器模式

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

相关推荐
java_heartLake21 分钟前
设计模式之工厂方法模式
java·设计模式·工厂方法模式
aabbcc456aa30 分钟前
ubuntu安装mysql 8.0忘记root初始密码,如何重新修改密码
linux·mysql·ubuntu
自身就是太阳37 分钟前
Maven的高级特性
java·开发语言·数据库·后端·spring·maven
cyt涛1 小时前
搜索功能技术方案
mysql·elasticsearch·全文检索·canal·索引·数据同步·搜索
剩下的远方2 小时前
CentOS7 MySQL8.0 启动失败 Data Dictionary initialization failed
运维·mysql·centos
fengqing55782 小时前
mysql把某一个字段的值中的aa,替换成bb
数据库·mysql
GG编程3 小时前
Mysql 视图&存储过程&触发器
数据库·mysql
尘浮生3 小时前
Java项目实战II基于Java+Spring Boot+MySQL的服装厂服装生产管理系统的设计与实现
java·开发语言·spring boot·后端·mysql·maven·intellij-idea
胡耀超4 小时前
MyBatis-Plus插入优化:降低IO操作的策略与实践
sql·spring·mybatis
深夜吞食5 小时前
MySQL详解:数据类型、约束
数据库·mysql