springboot单例模式注⼊对象_Spring中经典的9种设计模式,
打死也要记住啊!
1.简单⼯⼚(⾮23种设计模式中的⼀种)
2.⼯⼚⽅法
3.单例模式
4.适配器模式
5.装饰器模式
6.代理模式
7.观察者模式
8.策略模式
9.模版⽅法模式
《Java 2019 超神之路》
《Dubbo 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》
《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》
《数据库实体设计合集》
《Java ⾯试题 —— 精品合集》
《Java 学习指南 —— 精品合集》
Spring中涉及的设计模式总结
1.简单⼯⼚(⾮23种设计模式中的⼀种)
实现⽅式:
BeanFactory。Spring中的BeanFactory就是简单⼯⼚模式的体现,根据传⼊⼀个唯⼀的标识来获得Bean对象,但是否是在传⼊参数后创建还是传⼊参数前创建这个要根据具体情况来定。
实质:
由⼀个⼯⼚类根据传⼊的参数,动态决定应该创建哪⼀个产品类。
实现原理:
bean容器的启动阶段:
读取bean的xml配置⽂件,将bean元素分别转换成⼀个BeanDefinition对象。
然后通过BeanDefinitionRegistry将这些bean注册到beanFactory中,保存在它的⼀个ConcurrentHashMap中。
将BeanDefinition注册到了beanFactory之后,在这⾥Spring为我们提供了⼀个扩展的切⼝,允许我们通过实现接⼝
BeanFactoryPostProcessor 在此处来插⼊我们定义的代码。典型的例⼦就是:PropertyPlaceholderConfigurer,我们⼀般在配置数据库的dataSource时使⽤到的占位符的值,就是它注⼊进去的。
容器中bean的实例化阶段:
实例化阶段主要是通过反射或者CGLIB对bean进⾏实例化,在这个阶段Spring⼜给我们暴露了很多的扩展点:
各种的Aware接⼝
各种的Aware接⼝ ,⽐如 BeanFactoryAware,对于实现了这些Aware接⼝的bean,在实例化bean时Spring会帮我们注⼊对应的BeanFactory的实例。
BeanPostProcessor接⼝ ,实现了BeanPostProcessor接⼝的bean,在实例化bean时Spring会帮我们调⽤接⼝中的⽅法。
BeanPostProcessor接⼝
InitializingBean接⼝
InitializingBean接⼝ ,实现了InitializingBean接⼝的bean,在实例化bean时Spring会帮我们调⽤接⼝中的⽅法。
DisposableBean接⼝ ,实现了BeanPostProcessor接⼝的bean,在该bean死亡时Spring会帮我们调⽤接⼝中的⽅法。
DisposableBean接⼝
设计意义:
松耦合。 可以将原来硬编码的依赖,通过Spring这个beanFactory这个⼯⼚来注⼊依赖,也就是说原来只有依赖⽅和被依赖⽅,现在我们松耦合。
引⼊了第三⽅——spring这个beanFactory,由它来解决bean之间的依赖问题,达到了松耦合的效果.
bean的额外处理。
bean的额外处理。 通过Spring接⼝的暴露,在实例化bean的阶段我们可以进⾏⼀些额外的处理,这些额外的处理只需要让bean实现对应的接⼝即可,那么spring就会在bean的⽣命周期调⽤我们实现的接⼝来处理该bean。[⾮常重要]
2.⼯⼚⽅法
实现⽅式:
FactoryBean接⼝。
实现原理:
实现了FactoryBean接⼝的bean是⼀类叫做factory的bean。其特点是,spring会在使⽤getBean()调⽤获得该bean时,会⾃动调⽤该bean的getObject()⽅法,所以返回的不是factory这个bean,⽽是这个Ojbect()⽅法的返回值。
例⼦:
典型的例⼦有spring与mybatis的结合。
代码⽰例:
说明:
我们看上⾯该bean,因为实现了FactoryBean接⼝,所以返回的不是 SqlSessionFactoryBean 的实例,⽽是它的Object() 的返回值。
3.单例模式
Spring依赖注⼊Bean实例默认是单例的。
Spring的依赖注⼊(包括lazy-init⽅式)都是发⽣在AbstractBeanFactory的getBean⾥。getBean的doGetBean⽅法调⽤getSingleton 进⾏bean的创建。
分析getSingleton()⽅法
public Object getSingleton(String beanName){
//参数true设置标识允许早期依赖
return getSingleton(beanName,true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//检查缓存中是否存在实例
Object singletonObject = (beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//如果为空,则锁定全局变量并进⾏处理。
synchronized (this.singletonObjects) {
//如果此bean正在加载,则不处理
singletonObject = (beanName);
if (singletonObject == null && allowEarlyReference) {
//当某些⽅法需要提前初始化的时候则会调⽤addSingleFactory ⽅法将对应的ObjectFactory初始化策略存储在singletonFactories
ObjectFactory<?> singletonFactory = (beanName);
if (singletonFactory != null) {
//调⽤预先设定的getObject⽅法
singletonObject = Object();
//记录在缓存中,earlysingletonObjects和singletonFactories互斥
this.earlySingletonObjects.put(beanName, singletonObject);
ve(beanName);
}
}
springboot aop}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
getSingleton()过程图
ps:spring依赖注⼊时,使⽤了 双重判断加锁 的单例模式
总结
单例模式定义: 保证⼀个类仅有⼀个实例,并提供⼀个访问它的全局访问点。
单例模式定义:
spring对单例的实现: spring中的单例模式完成了后半句话,即提供了全局的访问点BeanFactory。但没有从构造器级别去控制单例,spring对单例的实现:
这是因为spring管理的是任意的java对象。
4.适配器模式
实现⽅式:
SpringMVC中的适配器HandlerAdatper。
实现原理:
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的扩展了。
5.装饰器模式
实现⽅式:
Spring中⽤到的包装器模式在类名上有两种表现:⼀种是类名中含有Wrapper,另⼀种是类名中含有Decorator。
实质:
动态地给⼀个对象添加⼀些额外的职责。
就增加功能来说,Decorator模式相⽐⽣成⼦类更为灵活。
6.代理模式
实现⽅式:
AOP底层,就是动态代理模式的实现。
动态代理:
在内存中构建的,不需要⼿动编写代理类
静态代理:
需要⼿⼯编写代理类,代理类引⽤被代理对象。
实现原理:
切⾯在应⽤运⾏的时刻被织⼊。⼀般情况下,在织⼊切⾯时,AOP容器会为⽬标对象创建动态的创建⼀个代理对象。SpringAOP就是以这种⽅式织⼊切⾯的。
织⼊:把切⾯应⽤到⽬标对象并创建新的代理对象的过程。
7.观察者模式
实现⽅式:
spring的事件驱动模型使⽤的是 观察者模式 ,Spring中Observer模式常⽤的地⽅是listener的实现。
具体实现:
事件机制的实现需要三个部分,事件源,事件,事件
ApplicationEvent抽象类[事件]
继承⾃jdk的EventObject,所有的事件都需要继承ApplicationEvent,并且通过构造器参数source得到事件源.
该类的实现类ApplicationContextEvent表⽰ApplicaitonContext的容器事件.
代码:
publicabstractclass ApplicationEvent extends EventObject {
privatestaticfinallong serialVersionUID = 7099057708183571937L;
privatefinallong timestamp;
public ApplicationEvent(Object source) {
super(source);
this.timestamp = System.currentTimeMillis();
}
public final long getTimestamp() {
returnthis.timestamp;
}
}
ApplicationListener接⼝[事件]
继承⾃jdk的EventListener,所有的都要实现这个接⼝。
这个接⼝只有⼀个onApplicationEvent()⽅法,该⽅法接受⼀个ApplicationEvent或其⼦类对象作为参数,在⽅法体中,可以通过不同对Event 类的判断来进⾏相应的处理。
当事件触发时所有的都会收到消息。
代码:
publicinterface ApplicationListener<E extends ApplicationEvent> extends EventListener {
void onApplicationEvent(E event);
}
ApplicationContext接⼝[事件源]
ApplicationContext是spring中的全局容器,翻译过来是”应⽤上下⽂”。
实现了ApplicationEventPublisher接⼝。
职责:
负责读取bean的配置⽂档,管理bean的加载,维护bean之间的依赖关系,可以说是负责bean的整个⽣命周期,再通俗⼀点就是我们平时所说的IOC容器。
代码:
publicinterface ApplicationEventPublisher {
void publishEvent(ApplicationEvent event);
}
public void publishEvent(ApplicationEvent event) {
if (logger.isTraceEnabled()) {
}
getApplicationEventMulticaster().multicastEvent(event);
if (this.parent != null) {
this.parent.publishEvent(event);
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论