美文网首页
2023-07-21Spring中用到的设计模式之一--适配器模

2023-07-21Spring中用到的设计模式之一--适配器模

作者: LAMYMAY | 来源:发表于2023-07-20 11:11 被阅读0次

一张图说明 Aware的原理

image.png

Spring中的Aware接口是一种适配器模式(Adapter Pattern)的应用。

适配器模式是一种结构型设计模式,它允许将一个类的接口转换为另一个类的接口,从而使不兼容的接口可以协同工作。在Spring中,Aware接口充当了适配器的角色,它将Spring容器中的一些特定功能暴露给Bean,使得Bean可以获取与Spring容器相关的信息和功能。

Spring中的Aware接口通常以Aware命名,例如ApplicationContextAware、BeanFactoryAware等。当Bean实现这些Aware接口时,Spring在初始化Bean的时候,会自动调用相应的set方法,将相应的资源或信息注入到Bean中。

以ApplicationContextAware为例,它允许Bean获取对ApplicationContext的引用,从而可以通过ApplicationContext来访问Spring容器的各种服务和功能。在这种情况下,ApplicationContext就是一个适配器,将Spring容器的功能适配给了Bean。

使用Aware接口的好处是,它能够在Bean的生命周期中注入所需的资源或信息,而不需要Bean自己主动去查找或请求。这种模式降低了Bean对Spring容器的依赖性,提高了代码的可扩展性和灵活性。

总结一下,Spring中的Aware接口采用了适配器模式,允许Bean获取对Spring容器的引用或其他特定资源,从而将Spring的功能适配给Bean,提供更灵活和松耦合的设计。

有人可能将Spring中的Aware接口与模板方法模式(Template Method Pattern)进行类比,这是因为在某种程度上它们有一些相似之处,但也要注意它们之间的区别。

模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,将一些步骤延迟到子类来实现。这样可以使得算法的结构稳定,而具体的实现可以在子类中灵活地改变,从而实现了代码复用和扩展。

在模板方法模式中,通常有一个抽象类,其中定义了一个模板方法,该方法包含了算法的主要步骤,并通过调用一些抽象方法和钩子方法来完成具体的实现。子类继承这个抽象类并实现抽象方法,从而完成对算法的定制。

现在让我们看看Spring中的Aware接口和模板方法模式之间的相似之处:

都涉及到在父类(或接口)中定义一些骨架结构:在模板方法模式中,抽象类中的模板方法就是算法的骨架,而在Spring的Aware接口中,接口中的set*方法就可以看作是Bean获取资源的骨架。

都允许子类(或实现类)进行自定义:在模板方法模式中,子类实现抽象方法可以自定义算法的实现细节,而在Spring的Aware接口中,Bean实现接口的方法可以获取到特定资源或信息,完成自定义的逻辑。

虽然有上述相似之处,但需要强调的是,Aware接口并不是典型的模板方法模式的应用。在模板方法模式中,抽象类定义了算法的骨架,而在Spring的Aware接口中,接口只是定义了一个回调方法,用于在Bean的初始化阶段注入特定资源。Aware接口更像是一个回调接口,而不是模板方法。

在软件设计中,常常会发现某些模式和原则之间有一些相似之处或共通点,因此有时会有人将它们进行类比或联想。虽然Aware接口与模板方法模式之间有一些类似之处,但仍然需要理解它们的不同和各自的设计目的。

常见的 Spring Aware 接口

Aware子接口 描述
BeanNameAware 获取容器中 Bean 的名称
BeanFactoryAware 获取当前 BeanFactory ,这样可以调用容器的服务
ApplicationContextAware 同上,在BeanFactory 和 ApplicationContext 的区别 中已明确说明
MessageSourceAware 获取 Message Source 相关文本信息
ApplicationEventPublisherAware 发布事件
ResourceLoaderAware 获取资源加载器,这样获取外部资源文件

当然不止以上这些 Aware, 通常使用 Spring Aware 的目的是为了让 Bean 获得 Spring 容器的服务。

代码中 有一段是资源权限问题的处理(方法 AccessController.doPrivileged() 90行位置)
参考文章:
https://www.cnblogs.com/liruilong/p/14810513.html

补充说明:
程序A想在/tmp目录中新建一个文件,它没有相应的权限,但是它引用了另外一个B.Jar包,刚好B有权限在/tmp目录中新建文件,而B在新建文件的时候采用的是AccessController.doPrivileged方法进行的,这种情况下A就可以调用B的创建文件方法进行文件创建。

AccessController.doPrivileged中断了栈检查过程,使得后续原本没有权限的代码也可以正常执行,从而成功创建文件,如果不使用AccessController.doPrivileged,会一直进行栈检查直到栈底位置,在程序A的栈帧(栈底)中会抛出权限异常,文件创建失败。

相关文章

网友评论

      本文标题:2023-07-21Spring中用到的设计模式之一--适配器模

      本文链接:https://www.haomeiwen.com/subject/nvtzudtx.html