SpringSpringBoot系列之Spring中涉及的9种设计模式【七】
1. 总览
Spring中涉及的设计模式:
1. 简单⼯⼚(⾮23种设计模式中的⼀种)
2. ⼯⼚⽅法
3. 单例模式
4. 适配器模式
5. 装饰器模式
6. 代理模式
7. 观察者模式
8. 策略模式
9. 模版⽅法模式
2. 详细介绍
2.1 简单⼯⼚(⾮23种设计模式中的⼀种)
实现⽅式:
BeanFactory。Spring中的BeanFactory就是简单⼯⼚模式的体现,根据传⼊beanName来获得Bean对象,先从缓存中取,缓存中没有再创建。
实质:
由⼀个⼯⼚类根据传⼊的参数,动态决定应该创建哪⼀个产品类。
实现原理:
bean容器的启动阶段:
读取bean的xml配置⽂件,将bean元素分别转换成⼀个个的BeanDefinition对象。
然后通过BeanDefinitionRegistry将这些bean注册到beanFactory中,保存在它的⼀个ConcurrentHashMap中。
将BeanDefinition注册到了beanFactory之后,在这⾥Spring为我们提供了⼀个扩展的接⼝,允许我们通过实现接⼝
BeanFactoryPostProcessor 在此处来插⼊我们定义的代码。典型的例⼦就是:PropertyPlaceholderConfigurer,我们⼀般在配置数据库的dataSource时使⽤到的占位符的值,就是它注⼊进去的。
容器中bean的实例化阶段:
实例化阶段主要是通过反射或者CGLIB对bean进⾏实例化,在这个阶段Spring⼜给我们暴露了很多的扩展点:
各种的Aware接⼝,⽐如 BeanFactoryAware,对于实现了这些Aware接⼝的bean,在实例化bean时Spring会帮我们注⼊对应的BeanFactory的实例。
BeanPostProcessor接⼝,实现了BeanPostProcessor接⼝的bean,在实例化bean时Spring会帮我们调⽤接⼝中的⽅法。
InitializingBean接⼝,实现了InitializingBean接⼝的bean,在实例化bean时Spring会帮我们调⽤接⼝中的⽅法。
DisposableBean接⼝,实现了BeanPostProcessor接⼝的bean,在该bean死亡时Spring会帮我们调⽤接⼝中的⽅法。
设计意义:
松耦合。可以将原来硬编码的依赖,通过Spring这个beanFactory这个⼯⼚来注⼊依赖,也就是说原来只有依赖⽅和被依赖⽅,现在我们引⼊了第三⽅——spring这个beanFactory,由它来解决bean之间的依赖问题,达到了松耦合的效果。
bean的额外处理。通过Spring接⼝的暴露,在实例化bean的阶段我们可以进⾏⼀些额外的处理,这些额外的处理只需要让bean实现对应的接⼝即可,那么spring就会在bean的⽣命周期调⽤我们实现的接⼝来处理该bean。
2.2 ⼯⼚⽅法
实现⽅式:springboot aop
FactoryBean接⼝。
实现原理:
实现了FactoryBean接⼝的bean是⼀类叫做factory的bean。其特点是spring会在使⽤getBean()调⽤获得该bean时,会⾃动调⽤该bean 的getObject()⽅法,所以返回的不是factory这个bean,⽽是这个Ojbect()⽅法的返回值。
例⼦:
典型的例⼦有spring与mybatis的结合。
<bean id="sqlSessionFactory"class="batis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:l"/>
<property name="mapperLocation" value="classpath:config/mappers/master/**/.xml"/>
</bean>
说明:
因为SqlSessionFactoryBean实现了FactoryBean接⼝,所以返回的不是 SqlSessionFactoryBean 的实例,⽽是它的Object() 的返回值。
2.3 单例模式
Spring中依赖注⼊的Bean实例默认是单例的。
Spring的依赖注⼊(包括lazy-init⽅式)都是发⽣在AbstractBeanFactory的getBean⾥。getBean的doGetBean⽅法调⽤getSingleton 进⾏bean的创建。
getSingleton()⽅法源码:
总结:
单例模式定义:保证⼀个类仅有⼀个实例,并提供⼀个访问它的全局访问点。
HandlerAdatper根据Handler规则执⾏不同的Handler。
实现过程:
DispatcherServlet根据HandlerMapping返回的handler,向HandlerAdatper发起请求,处理Handler。
HandlerAdapter根据规则到对应的Handler并让其执⾏,执⾏完毕后Handler会向HandlerAdapter返回⼀个ModelAndView,最后由HandlerAdapter向DispatchServelet返回⼀个ModelAndView。
实现意义:
HandlerAdatper使得Handler的扩展变得容易,只需要增加⼀个新的Handler和⼀个对应的HandlerAdapter即可。
因此Spring定义了⼀个适配接⼝,使得每⼀种Controller有⼀种对应的适配器实现类,让适配器代替controller执⾏相应的⽅法。这样在扩展Controller时,只需要增加⼀个适配器类就完成了SpringMVC的扩展了。
2.5 装饰器模式
实现⽅式:
Spring中⽤到的包装器模式在类名上有两种表现:⼀种是类名中含有Wrapper,另⼀种是类名中含有Decorator。
实质:
动态地给⼀个对象添加⼀些额外的职责。就增加功能来说,Decorator模式⽐⽣成⼦类更为灵活。
2.6 代理模式
实现⽅式:
AOP底层,就是动态代理模式的实现。
动态代理:
在内存中构建的,不需要⼿动编写代理类。
静态代理:
需要⼿⼯编写代理类,代理类引⽤被代理对象。
实现原理:
切⾯在应⽤运⾏的时刻被织⼊。⼀般情况下,在织⼊切⾯时,AOP容器会为⽬标对象动态的创建⼀个代理对象。SpringAOP就是以这种⽅式织⼊切⾯的。
织⼊:把切⾯应⽤到⽬标对象并创建新的代理对象的过程。
2.7 观察者模式
实现⽅式:
spring的事件驱动模型使⽤的是 观察者模式 ,Spring中Observer模式常⽤的地⽅是listener的实现。
具体实现:
事件机制的实现需要三个部分:事件源、事件、事件。
ApplicationEvent抽象类(事件)
继承⾃jdk的EventObject,所有的事件都需要继承ApplicationEvent,并且通过构造器参数source得到事件源。该类的实现类ApplicationContextEvent表⽰ApplicaitonContext的容器事件。
代码:
public abstract class ApplicationEvent extends EventObject {
private static final long serialVersionUID =7099057708183571937L;
private final long timestamp;
public ApplicationEvent(Object source){
super(source);
this.timestamp = System.currentTimeMillis();
}
public final long getTimestamp(){
return this.timestamp;
}
}
ApplicationListener接⼝(事件)
继承⾃jdk的EventListener,所有的都要实现这个接⼝。
这个接⼝只有⼀个onApplicationEvent()⽅法,该⽅法接受⼀个ApplicationEvent或其⼦类对象作为参数,在⽅法体中,可以通过不同对Event类的判断来进⾏相应的处理。
当事件触发时所有的都会收到消息。
代码:
public interface ApplicationListener<E extends ApplicationEvent>extends EventListener {
void onApplicationEvent(E event);
}
ApplicationContext接⼝(事件源)
ApplicationContext是spring中的全局容器,翻译过来是”应⽤上下⽂”。
实现了ApplicationEventPublisher接⼝。
职责:
负责读取bean的配置⽂档,管理bean的加载,维护bean之间的依赖关系,可以说是负责bean的整个⽣命周期,再通俗⼀点就是我们平时所说的IOC容器。
代码:
public interface ApplicationEventPublisher {
void publishEvent(ApplicationEvent event);
}
public void publishEvent(ApplicationEvent event){
if(logger.isTraceEnabled()){
}
getApplicationEventMulticaster().multicastEvent(event);
if(this.parent != null){
this.parent.publishEvent(event);
}
}
ApplicationEventMulticaster抽象类[事件源中publishEvent⽅法需要调⽤其⽅法getApplicationEventMulticaster]属于事件⼴播器,它的作⽤是把Applicationcontext发布的Event⼴播给所有的。
代码:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。