当前位置:   article > 正文

Spring中涉及的设计模式总结,请注意查收

Spring中涉及的设计模式总结,请注意查收
  • 实现原理:实现了FactoryBean接口的bean是一类叫做factory的bean。其特点是,spring会在使用getBean()调用获得该bean时,会自动调用该bean的getObject()方法,所以返回的不是factory这个bean,而是这个bean.getOjbect()方法的返回值。

  • 例子:

  • 典型的例子有spring与mybatis的结合。

  • 代码示例

Spring中涉及的设计模式总结,请注意查收

微信8.0之后,又悄悄上线新功能:别人“抢不到”的红包!赶紧看看灰度到你了没?

  • 说明:我们看上面该bean,因为实现了FactoryBean接口,所以返回的不是 SqlSessionFactoryBean 的实例,而是她的 SqlSessionFactoryBean.getObject() 的返回值。

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 = this.singletonObjects.get(beanName);

if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {

//如果为空,则锁定全局变量并进行处理。

synchronized (this.singletonObjects) {

//如果此bean正在加载,则不处理

singletonObject = this.earlySingletonObjects.get(beanName);

if (singletonObject == null && allowEarlyReference) {

//当某些方法需要提前初始化的时候则会调用addSingleFactory 方法将对应的ObjectFactory初始化策略存储在singletonFactories

ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);

if (singletonFactory != null) {

//调用预先设定的getObject方法

singletonObject = singletonFactory.getObject();

//记录在缓存中,earlysingletonObjects和singletonFactories互斥

this.earlySingletonObjects.put(beanName, singletonObject);

this.singletonFactories.remove(beanName);

}

}

}

}

return (singletonObject != NULL_OBJECT ? singletonObject : null);

}

  • getSingleton()过程图 ps:spring依赖注入时,使用了 双重判断加锁的单例模式

Spring中涉及的设计模式总结,请注意查收

我以为的周末 vs 实际上的周末

    • 总结
  • 单例模式定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

  • spring对单例的实现:spring中的单例模式完成了后半句话,即提供了全局的访问点BeanFactory。但没有从构造器级别去控制单例,这是因为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的容器事件.

  • 代码:

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 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) {

Assert.notNull(event, “Event must not be null”);

if (logger.isTraceEnabled()) {

logger.trace("Publishing event in " + getDisplayName() + ": " + event);

}

getApplicationEventMulticaster().multicastEvent(event);

if (this.parent != null) {

this.parent.publishEvent(event);

}

}

    • ApplicationEventMulticaster抽象类事件源中publishEvent方法需要调用其方法getApplicationEventMulticaster
  • 属于事件广播器,它的作用是把Applicationcontext发布的Event广播给所有的监听器.

  • 代码

public abstract class AbstractApplicationContext extends DefaultResourceLoader

implements ConfigurableApplicationContext, DisposableBean {

private ApplicationEventMulticaster applicationEventMulticaster;

protected void registerListeners() {

// Register statically specified listeners first.

for (ApplicationListener<?> listener : getApplicationListeners()) {

getApplicationEventMulticaster().addApplicationListener(listener);

}

// Do not initialize FactoryBeans here: We need to leave all regular beans

// uninitialized to let post-processors apply to them!

String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);

for (String lisName : listenerBeanNames) {

getApplicationEventMulticaster().addApplicationListenerBean(lisName);

}

}

}

8.策略模式

======

  • 实现方式:Spring框架的资源访问Resource接口 。该接口提供了更强的资源访问能力,Spring 框架本身大量使用了 Resource 接口来访问底层资源。

  • Resource 接口介绍

  • source 接口是具体资源访问策略的抽象,也是所有资源访问类所实现的接口。

  • Resource 接口主要提供了如下几个方法:

  • getInputStream():定位并打开资源,返回资源对应的输入流。每次调用都返回新的输入流。调用者必须负责关闭输入流。

  • exists():返回 Resource 所指向的资源是否存在。

  • isOpen():返回资源文件是否打开,如果资源文件不能多次读取,每次读取结束应该显式关闭,以防止资源泄漏。

  • getDescription():返回资源的描述信息,通常用于资源处理出错时输出该信息,通常是全限定文件名或实际 URL。

笔者福利

以下是小编自己针对马上即将到来的金九银十准备的一套“面试宝典”,不管是技术还是HR的问题都有针对性的回答。

有了这个,面试踩雷?不存在的!

回馈粉丝,诚意满满!!!




束应该显式关闭,以防止资源泄漏。

  • getDescription():返回资源的描述信息,通常用于资源处理出错时输出该信息,通常是全限定文件名或实际 URL。

笔者福利

以下是小编自己针对马上即将到来的金九银十准备的一套“面试宝典”,不管是技术还是HR的问题都有针对性的回答。

有了这个,面试踩雷?不存在的!

回馈粉丝,诚意满满!!!

[外链图片转存中…(img-nX1FZa5n-1714471763508)]
[外链图片转存中…(img-GiqCmLo4-1714471763509)]
[外链图片转存中…(img-xiYT1SJH-1714471763509)]
[外链图片转存中…(img-G4IU4QCP-1714471763509)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/525894
推荐阅读
相关标签
  

闽ICP备14008679号