设计模式_策略模式_在Spring中的应用
一.理论
在spring中经常有读取配置文件的需求,这里就会用到一个Spring提供的Resource接口
Resource 接口是具体资源访问策略的抽象,也是所有资源访问类所实现的接口。Resource 接口主要提供了如下几个方法:
- getInputStream():定位并打开资源,返回资源对应的输入流。每次调用都返回新的输入流。调用者必须负责关闭输入流。
- exists():返回 Resource 所指向的资源是否存在。
- isOpen():返回资源文件是否打开,如果资源文件不能多次读取,每次读取结束应该显式关闭,以防止资源泄漏。
- getDescription():返回资源的描述信息,通常用于资源处理出错时输出该信息,通常是全限定文件名或实际 URL。
- getFile:返回资源对应的 File 对象。
- getURL:返回资源对应的 URL 对象。
Resource 接口本身没有提供访问任何底层资源的实现逻辑,针对不同的底层资源,Spring 将会提供不同的 Resource 实现类,不同的实现类负责不同的资源访问逻辑。
Resource 和策略模式 Resource 接口就是策略模式的典型应用,Resource 接口就代表资源访问策略,但具体采用哪种策略实现,Resource 接口并不理会。客户端程序只和 Resource 接口耦合,并不知道底层采用何种资源访问策略,这样应用可以在不同的资源访问策略之间自由切换。
Spring 为 Resource 接口提供了如下实现类:
- UrlResource:访问网络资源的实现类。
- ClassPathResource:访问类加载路径里资源的实现类。
- FileSystemResource:访问文件系统里资源的实现类。
- ServletContextResource:访问相对于 ServletContext 路径里的资源的实现类:
- InputStreamResource:访问输入流资源的实现类。
- ByteArrayResource:访问字节数组资源的实现类。
这些 Resource 实现类,针对不同的的底层资源,提供了相应的资源访问逻辑,并提供便捷的包装,以利于客户端程序的资源访问。

二.源码
这里跟踪ClassPathXmlApplicationContext对象的创建,来了解Spring底层怎么使用Resource接口及其实现类达成策略模式
策略模式的优势 当 Spring 应用需要进行资源访问时,实际上并不需要直接使用 Resource 实现类,而是调用 ApplicationContext 实例的 getResource() 方法来获得资源,ApplicationContext 将会负责选择 Resource 的实现类,也就是确定具体的资源访问策略,从而将应用程序和具体的资源访问策略分离开来,这就体现了策略模式的优势。
//1.根据传入的配置文件地址,创建容器对象 ClassPathXmlApplicationContext
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
//2.1中代码调用到此处,此处调用父类构造函数 ClassPathXmlApplicationContext
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException { super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
//3.2中代码一步步调用到此处 AbstractApplicationContext
public AbstractApplicationContext(ApplicationContext parent) {
this();
setParent(parent);
}
//4.3中代码调用此处 AbstractApplicationContext
public AbstractApplicationContext() {
this.resourcePatternResolver = getResourcePatternResolver();
}
//5.返回能将1中传入的configLocation转换成Resource对象的ResourcePatternResolver AbstractApplicationContext
protected ResourcePatternResolver getResourcePatternResolver() {
return new PathMatchingResourcePatternResolver(this);
}
//6.真正用到策略模式的地方,根据location的内容,决定返回对应的Resource实现,这个过程对客户来说是透明的 DefaultResourceLoader
@Override
public Resource getResource(String location) {
Assert.notNull(location, "Location must not be null"); for (ProtocolResolver protocolResolver : this.protocolResolvers) {
Resource resource = protocolResolver.resolve(location, this);
if (resource != null) {
return resource;
}
} if (location.startsWith("/")) {
return getResourceByPath(location);
}
else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
}
else {
try {
// Try to parse the location as a URL...
URL url = new URL(location);
return new UrlResource(url);
}
catch (MalformedURLException ex) {
// No URL -> resolve as resource path.
return getResourceByPath(location);
}
}
}
参考:https://www.ibm.com/developerworks/cn/java/j-lo-spring-resource/
设计模式_策略模式_在Spring中的应用的更多相关文章
- 在商城系统中使用设计模式----策略模式之在spring中使用策略模式
1.前言: 这是策略模式在spring中的使用,对策略模式不了解对同学可以移步在商城中简单对使用策略模式. 2.问题: 在策略模式中,我们创建表示各种策略的对象和一个行为,随着策略对象改变而改变的 c ...
- 【设计模式】【应用】使用模板方法设计模式、策略模式 处理DAO中的增删改查
原文:使用模板方法设计模式.策略模式 处理DAO中的增删改查 关于模板模式和策略模式参考前面的文章. 分析 在dao中,我们经常要做增删改查操作,如果每个对每个业务对象的操作都写一遍,代码量非常庞大. ...
- 【GOF23设计模式】策略模式
来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_策略模式.CRM中报价策略.GUI编程中布局管理器底层架构 package com.test.strategy; /** ...
- JavaScript设计模式之策略模式(学习笔记)
在网上搜索“为什么MVC不是一种设计模式呢?”其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选 ...
- PHP设计模式之策略模式
前提: 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查 找.排序等,一种常用的方法是硬编码(Hard Cod ...
- 乐在其中设计模式(C#) - 策略模式(Strategy Pattern)
原文:乐在其中设计模式(C#) - 策略模式(Strategy Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 策略模式(Strategy Pattern) 作者:webabc ...
- 再起航,我的学习笔记之JavaScript设计模式20(策略模式)
策略模式 策略模式(Strategy):将定义的一组算法封装起来,使其相互之间可以替换.封装的算法具有一定的独立性,不会随客户端变化而变化. 其实策略模式在我们生活中可应用的地方还是比较多的,比如在商 ...
- JavaScript设计模式之策略模式
所谓"条条道路通罗马",在现实中,为达到某种目的往往不是只有一种方法.比如挣钱养家:可以做点小生意,可以打分工,甚至还可以是偷.抢.赌等等各种手段.在程序语言设计中,也会遇到这种类 ...
- 小白学习java设计模式之策略模式
策略模式:1.分析项目中的变化部分与不变部分(每个设计模式都要分析的)2.多用组合少用继承;用行为类组合,而不是行为继承,更具有弹性直接上代码: package com.wz.oneStrategis ...
随机推荐
- python基础数据类型--list列表
列表: 列表是python中的基础数据类型之一,其他语言中也有类似于列表的数据类型,比如js中叫数组,他是以[]括起来,每个元素以逗号隔开,而且他里面可以存放各种数据类型比如: li = [‘alex ...
- PXE网络装机
PXE网络装机配置 安装CentOS 6.5系统 1.配置服务端IP地址和yum源 略 2.安装配置VSFTP服务 vsftpd 的作用:为客户端提供FTP服务,便于客户端下载操作系统 (1)安装vs ...
- Xml的用途
1.可以作为数据库存储数据--通过XML文件存储数据,可以通过javaScript读取外部的XML文件,然后更新HTML的数据内容 2.XML数据以纯文本格式进行存储,提供了独立于软件和硬件的数据存储 ...
- Luogu4726 【模板】多项式指数函数(NTT+多项式求逆)
https://www.cnblogs.com/HocRiser/p/8207295.html 安利! #include<iostream> #include<cstdio> ...
- 洛谷P2722总分题解
题目 这个题是一个裸的完全背包问题,但是数组需要开大, 代码 #include<iostream> using namespace std; int n,m,v,i; int c[1000 ...
- spring05-Spring事务管理
事务的第一个方面是传播行为(propagation behavior).当事务方法被另一个事务方法调用时,必须指定事务应该如何传播.例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的 ...
- MySQL 练习题 附答案,未完
综合练习题 表结构 整合一下方便查看 teacher student course scors 练习题 1.自行创建测试数据 create table student( sid int prima ...
- MT【262】一道常见错题
若$f(x^2)$的定义域为$[-1,1]$,则函数$f(x)$的定义域为______ 设$a>0$构造$f(x)=\sqrt{x(1-x)(a+x)}$,此时$f(x^2)$的定义域为$[-1 ...
- php获取用户真实IP和防刷机制
一. 如何获取用户IP地址 public static function getClientIp() { if (getenv('HTTP_CLIENT_IP')) { $ip = getenv( ...
- Hdoj 2108.Shape of HDU 题解
Problem Description 话说上回讲到海东集团推选老总的事情,最终的结果是XHD以微弱优势当选,从此以后,"徐队"的称呼逐渐被"徐总"所取代,海东 ...