|
对于最新稳定版本,请使用Spring Framework 7.0.1! |
资源
本章介绍了Spring如何管理资源,以及如何利用资源 Spring。课程涵盖以下主题:
介绍
Java 标准java.net.URL类处理程序和各种URL前缀的标准处理程序,
遗憾的是,这些资源还不足以满足所有低层次资源的访问需求。为
例如,没有标准化的网址实现,可用于访问
需要从类路径或相对于ServletContext.虽然可以注册新的处理器以获得专门化网址前缀(类似于现有处理前缀的处理程序,如http:),通常为
相当复杂,而且网址界面仍缺少一些理想的功能,
例如,一种检测被指向资源存在的方法。
这资源接口
斯普林斯资源位于org.springframework.core.io。包是
旨在提供更强大的接口,用于抽象对低层资源的访问。这
以下列表提供了该项目的概览资源接口。参见资源更多详情请参见 Javadoc。
public interface Resource extends InputStreamSource {
boolean exists();
boolean isReadable();
boolean isOpen();
boolean isFile();
URL getURL() throws IOException;
URI getURI() throws IOException;
File getFile() throws IOException;
ReadableByteChannel readableChannel() throws IOException;
long contentLength() throws IOException;
long lastModified() throws IOException;
Resource createRelative(String relativePath) throws IOException;
String getFilename();
String getDescription();
}
作为资源界面显示,它扩展了输入流源接口。以下列表展示了输入流源接口:
public interface InputStreamSource {
InputStream getInputStream() throws IOException;
}
其中一些最重要的方法来自资源接口包括:
-
getInputStream(): 定位并打开资源,返回输入流为 阅读资源。每次召唤都应返回一个新消息输入流.来电者有责任关闭该流。 -
存在()返回 a布尔表明该资源是否实际存在于 实体形态。 -
isOpen()返回 a布尔指示该资源是否代表句柄 有一条开放的溪流。如果true这输入流不可多次读取且 必须只读取一次,然后关闭,以避免资源泄漏。返回false为 所有常见的资源实现,除了输入流资源. -
getDescription()返回该资源的描述,用于错误处理 在使用资源时输出。这通常是完全限定的文件名,或者 资源的实际网址。
其他方法则可以让你获得实际情况网址或文件表示
资源(如果底层实现兼容并支持该条件)
功能性)。
一些实现资源接口还实现了扩展的WritableResource接口
需要一个支持写作的资源。
Spring本身使用资源广泛抽象,作为参数类型
当需要资源时,方法签名多。某些 Spring API 中的其他方法
(例如,构建子对各种应用上下文实现)取一个字符串以简洁或简洁的形式,用来创造资源适合
该上下文实现,或者通过在字符串路径,设
呼叫者指定具体的资源必须被创建并使用。
虽然资源界面在Spring中被大量使用,到了Spring,实际上
作为通用工具类单独在你自己的代码中使用非常方便,方便访问
资源,即使你的代码不了解或关心Spring的其他部分。
虽然这把你的代码和 Spring 绑定了,但它实际上只是绑定到这小部分
该类作为更强大的替代网址并且可以是
它被视为相当于你为此目的使用的其他库。
这资源抽象并不能取代功能。它包裹在
可能。例如,一个UrlResource将 URL 封装并使用网址去做
工作。 |
内置资源实现
Spring 包含多个内置功能资源实现:
完整列表资源春季可用的实现,请参阅
“所有已知实现类”部分资源Javadoc。
UrlResource
UrlResource包裹 ajava.net.URL可以用来访问任何
通常通过URL(如文件)、HTTPS目标、FTP目标访问,以及
别人。所有网址都有标准化的字符串表示,使得
标准化前缀用于区分不同URL类型之间的区别。这包括文件:用于访问文件系统路径,https:通过
HTTPS协议,FTP:通过FTP等方式访问资源。
一个UrlResource由 Java 代码通过显式使用UrlResource构造 函数
但通常在调用一个接受字符串论点旨在代表一条路径。对于后一种情况,是 JavaBeans属性编辑最终决定哪种类型的资源去创造。如果路径字符串包含
对属性编辑器来说是已知的前缀(例如Classpath:),它会生成一个
合适的专业资源就是因为那个前缀。然而,如果它不识别
前缀,它假设字符串是标准的 URL 字符串,并创建UrlResource.
ClassPathResource
该类代表应从类路径中获得的资源。它使用 无论是线程上下文类加载器、给定的类加载器,还是给定的 加载资源。
这资源实现支持作为解析java.io.file如果
资源存在于文件系统中,但不存在于位于
jar 并且没有被扩展(无论是通过 Servlet 引擎还是其他环境)
到文件系统。针对此,各种资源实现始终支持
作为java.net.URL.
一个ClassPathResource由 Java 代码通过显式使用ClassPathResource但通常在调用一个 API 方法时隐式创建的,该方法对字符串论点旨在代表一条路径。对于后一种情况,是 JavaBeans属性编辑承认特殊前缀,Classpath:,在弦路径上,且
生成一个ClassPathResource那就这样吧。
文件系统资源
这是一艘资源实现java.io.file处理。它还支持java.nio.file.Path应用 Spring 标准的基于字符串的路径
但所有作都通过java.nio.file.files应用程序接口。纯粹java.nio.path.Path基于支持的使用路径资源相反。文件系统资源支持作为文件以及作为网址.
路径资源
这是一艘资源实现java.nio.file.Path手柄,执行所有
通过路径应用程序接口。它支持作为文件和
作为网址并且还实现了扩展的WritableResource接口。路径资源实际上是纯粹的java.nio.path.Path基于的替代方案文件系统资源跟
不同createRelative(创建关系)行为。
ServletContextResource
这是一艘资源实现ServletContext能够解释
相关网页应用根目录内的相对路径。
它始终支持流访问和网址访问,但允许java.io.file仅限进入
当网页应用归档被扩展且资源物理地位于
文件系统。无论它是否被扩展并存储在文件系统中,还是被访问
直接从JAR或数据库(可以想象)直接获取,实际上是
依赖于 Servlet 容器。
这ResourceLoader接口
这ResourceLoader接口旨在由能够返回的对象实现
(即装载)资源实例。以下列表显示了ResourceLoader界面定义:
public interface ResourceLoader {
Resource getResource(String location);
ClassLoader getClassLoader();
}
所有应用上下文都实现了ResourceLoader接口。因此,所有
应用上下文可用于获得资源实例。
你打电话时getResource()在特定应用上下文和位置路径上
指定没有特定的前缀,你会得到一个资源类型为
根据该具体应用上下文。例如,假设如下
代码片段被运行在ClassPathXmlApplicationContext实例:
-
Java
-
Kotlin
Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
val template = ctx.getResource("some/resource/path/myTemplate.txt")
对抗ClassPathXmlApplicationContext,该代码返回ClassPathResource.如果
同样的方法也在文件系统Xml应用上下文比如,它会
返回A文件系统资源.对于一个WebApplicationContext,它会返回ServletContextResource.它同样会返回针对每个上下文的适当对象。
因此,你可以根据具体应用的方式加载资源 上下文。
另一方面,你也可以强行ClassPathResource无论
通过指定特殊条件Classpath:前缀,如下
示例如下:
-
Java
-
Kotlin
Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");
val template = ctx.getResource("classpath:some/resource/path/myTemplate.txt")
同样,你可以强制 aUrlResource通过指定任一标准来使用java.net.URL前缀。以下示例使用了文件和https前缀:
-
Java
-
Kotlin
Resource template = ctx.getResource("file:///some/resource/path/myTemplate.txt");
val template = ctx.getResource("file:///some/resource/path/myTemplate.txt")
-
Java
-
Kotlin
Resource template = ctx.getResource("https://myhost.com/resource/path/myTemplate.txt");
val template = ctx.getResource("https://myhost.com/resource/path/myTemplate.txt")
下表总结了转换策略字符串对象为资源对象:
| 前缀 | 示例 | 解释 |
|---|---|---|
Classpath: |
|
从类路径加载过来。 |
文件: |
|
装载如同 |
https: |
|
装载如同 |
(无) |
|
这取决于标的资产 |
这资源模式解析器接口
这资源模式解析器接口是ResourceLoader接口
该方法定义了解决位置模式的策略(例如Ant式路径)
模式)变成资源对象。
public interface ResourcePatternResolver extends ResourceLoader {
String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
Resource[] getResources(String locationPattern) throws IOException;
}
如上所示,该接口还定义了特殊条件classpath*:资源前缀
对于类路径中所有匹配的资源。注意资源位置为
在这种情况下,预期路径是没有占位符的——例如,classpath*:/config/beans.xml.JAR文件或类路径中的不同目录可以
包含多个路径相同且名称相同的文件。详情请参见应用上下文构造器资源路径中的万用符及其子节
关于与classpath*:资源前缀。
一个过户的ResourceLoader(例如,提供给ResourceLoaderAware语义)可以检查
它也实现了这种扩展界面。
PathMatchingResourcePatternResolver是一个可使用的独立实现
在外面应用上下文也被用于ResourceArrayPropertyEditor为
填充资源[]豆子的地产。PathMatchingResourcePatternResolver能够
将指定的资源位置路径解析为一个或多个匹配路径资源对象。
源路径可以是简单路径,具有与目标的一一映射资源或者包含特殊条件classpath*:前缀和/或内部
Ant式正则表达式(使用 Spring 的org.springframework.util.AntPathMatcher实用性)。后者实际上都是
变数。
|
默认 |
这ResourceLoaderAware接口
这ResourceLoaderAware接口是一种特殊的回调接口,用于识别
期望被提供ResourceLoader参考。以下列表
显示 的定义ResourceLoaderAware接口:
public interface ResourceLoaderAware {
void setResourceLoader(ResourceLoader resourceLoader);
}
当一个类实现ResourceLoaderAware并且部署到应用上下文中
(作为春季管理的Beans),它被认可为ResourceLoaderAware由应用
上下文。应用上下文随后调用setResourceLoader(ResourceLoader),
作为参数提供自身(记住,Spring 中的所有应用上下文都是实现的
这ResourceLoader界面)。
因为应用上下文是ResourceLoader,豆子也可以实现应用上下文感知接口并直接使用提供的应用上下文到
加载资源。不过,一般来说,最好还是用专业的ResourceLoader如果你只需要接口,那就更好。代码只与资源加载耦合
接口(可以视为工具接口),而非整个 Spring应用上下文接口。
在应用组件中,你也可以依赖自动接线ResourceLoader如
实现ResourceLoaderAware接口。传统
构造 函数和byType自动接线模式(如《自动接线协作者》中描述)
能够提供ResourceLoader对于构造子参数或
分别是设定器方法参数。为了更多灵活性(包括能够
自动线字段和多参数方法),考虑使用基于注释的
自动接线功能。在这种情况下,ResourceLoader是自动接线到场中,
构造函数参数,或期望ResourceLoader类型
因为该场、构造器或方法携带@Autowired注解。
更多信息请参见用@Autowired.
加载一个或多个资源包含通配符的资源路径对象
或者利用特殊情况classpath*:资源前缀,考虑拥有一个实例资源模式解析器自动接线到你的
应用组件ResourceLoader. |
资源作为依赖
如果豆子本身会通过某种方式确定并供应资源路径,
对于动态过程来说,豆子使用以下ResourceLoader或资源模式解析器与加载资源的接口。例如,考虑载荷
某种模板,其中所需的具体资源取决于
用户的角色。如果资源是静态的,那么取消使用ResourceLoader接口(或资源模式解析器接口)完全,拥有
豆氏揭露了资源它需要的属性,并期望这些属性被注入其中。
之所以容易注入这些属性,是因为所有应用上下文
注册并使用一个特殊的JavaBeans属性编辑,可以转换字符串路径
自资源对象。例如,如下我的豆子类有模板类型性质资源.
-
Java
-
Kotlin
public class MyBean {
private Resource template;
public setTemplate(Resource template) {
this.template = template;
}
// ...
}
class MyBean(var template: Resource)
在XML配置文件中,模板属性可以用简单的
字符串,如下示例所示:
<bean id="myBean" class="example.MyBean">
<property name="template" value="some/resource/path/myTemplate.txt"/>
</bean>
注意资源路径没有前缀。因此,由于应用上下文
本身将被用作ResourceLoader,资源通过ClassPathResource一个文件系统资源,或ServletContextResource根据
具体应用上下文的类型。
如果你需要强制执行资源输入 To 使用的类型,你可以用前缀。这
以下两个示例展示了如何强制 aClassPathResource以及一个UrlResource(
后者用于访问文件系统中的文件):
<property name="template" value="classpath:some/resource/path/myTemplate.txt">
<property name="template" value="file:///some/resource/path/myTemplate.txt"/>
如果我的豆子类被重构以配合注释驱动配置,该配置
通往myTemplate.txt可以存储在一个名为模板.路径——例如,
在一份提供给春季的房产档案中环境(参见环境抽象)模板路径随后可以通过@Value使用属性占位符的注释(参见用@Value).Spring将
检索模板路径的字符串值,以及一个特殊值属性编辑将
将字符串转换为资源要注入的对象我的豆子构造 函数。
以下示例展示了如何实现这一点。
-
Java
-
Kotlin
@Component
public class MyBean {
private final Resource template;
public MyBean(@Value("${template.path}") Resource template) {
this.template = template;
}
// ...
}
@Component
class MyBean(@Value("\${template.path}") private val template: Resource)
如果我们想支持在同一路径下发现的多个模板,并且在多个路径上
类路径中的位置——例如,在类路径的多个jar中——我们可以
用特别的classpath*:前缀和万用卡定义templates.path注释为classpath*:/config/templates/*.txt.如果我们重新定义我的豆子类如下,
Spring 会将模板路径模式转换为资源对象
可以注入我的豆子构造 函数。
-
Java
-
Kotlin
@Component
public class MyBean {
private final Resource[] templates;
public MyBean(@Value("${templates.path}") Resource[] templates) {
this.templates = templates;
}
// ...
}
@Component
class MyBean(@Value("\${templates.path}") private val templates: Resource[])
应用上下文与资源路径
本节介绍如何创建带有资源的应用上下文,包括快捷方式 这些内容涉及 XML 的作、如何使用通配符以及其他细节。
构建应用上下文
通常是针对特定应用上下文类型的应用上下文构造器 取一个字符串或字符串数组作为资源的位置路径,例如 构成上下文定义的XML文件。
当该位置路径没有前缀时,具体资源制造的类型
该路径 和 用于加载豆定义 依赖于 和 适用于
具体应用背景。例如,考虑以下例子,它生成ClassPathXmlApplicationContext:
-
Java
-
Kotlin
ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
val ctx = ClassPathXmlApplicationContext("conf/appContext.xml")
豆子定义是从类路径加载的,因为ClassPathResource是
使用。然而,考虑以下示例,它生成文件系统Xml应用上下文:
-
Java
-
Kotlin
ApplicationContext ctx =
new FileSystemXmlApplicationContext("conf/appContext.xml");
val ctx = FileSystemXmlApplicationContext("conf/appContext.xml")
现在,豆子定义是从文件系统位置加载的(此例中,相对于 当前工作目录)。
注意特殊词的使用类路径前缀或标准URL前缀
位置路径覆盖默认类型资源创建以加载豆子
定义。请考虑以下例子:
-
Java
-
Kotlin
ApplicationContext ctx =
new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");
val ctx = FileSystemXmlApplicationContext("classpath:conf/appContext.xml")
用文件系统Xml应用上下文从 classpath 加载 bean 定义。
然而,它仍然是文件系统Xml应用上下文.如果它随后被用作ResourceLoader,任何未前缀的路径仍被视为文件系统路径。
构建ClassPathXmlApplicationContext实例 — 捷径
这ClassPathXmlApplicationContext暴露若干构造子以支持
方便的实例化。基本思想是你只需提供字符串数组
仅包含XML文件本身的文件名(不含引导路径)
信息)并提供类.这ClassPathXmlApplicationContext则推导
提供类别的路径信息。
请考虑以下目录布局:
com/
example/
services.xml
repositories.xml
MessengerService.class
以下示例展示了ClassPathXmlApplicationContext实例由以下组成
这些 BEANS 定义在文件中,名为services.xml和repositories.xml(这些
classpath)可以实例化为:
-
Java
-
Kotlin
ApplicationContext ctx = new ClassPathXmlApplicationContext(
new String[] {"services.xml", "repositories.xml"}, MessengerService.class);
val ctx = ClassPathXmlApplicationContext(arrayOf("services.xml", "repositories.xml"), MessengerService::class.java)
参见ClassPathXmlApplicationContext关于各种构造函数的详细信息,请使用javadoc。
应用上下文构造器资源路径中的万用符
应用上下文构造器中的资源路径值可以是简单路径(如
如前所述),每个目标都与目标一一对应资源或
或者,可能包含特殊内容classpath*:前缀或内部蚁式图案
(通过使用 Spring 的路径匹配器实用性)。后者实际上都是
变数。
这种机制的一个用途是需要进行组件式应用汇编。都
组件可以将上下文定义片段发布到已知的位置路径,并且,
当最终应用上下文使用相同的路径创建时,前缀为classpath*:,所有组件片段都会自动被拾取。
注意,这种通配符是针对应用上下文中资源路径的专用
构造子(或当你使用路径匹配器直接的效用类层级),并且是
施工时已解决。这和资源打字本身。
你不能使用classpath*:前缀用于构造一个实际资源如
资源一次只指向一个资源。
Ant式图案
路径位置可以包含Ant式的模式,如下示例所示:
/WEB-INF/*-context.xml com/mycompany/**/applicationContext.xml file:C:/some/path/*-context.xml classpath:com/mycompany/**/applicationContext.xml
当路径位置包含Ant式模式时,解析器遵循更复杂的模式
试图解决万用卡的程序。它产生资源对于通往
最后一个非万用符段,并从中获取一个URL。如果这个URL不是罐:网址或
容器专用变体(例如邮编:在WebLogic中,WSJAR在WebSphere中,等等),
一个java.io.file从中获得,并用来通过遍历
文件系统。对于jar URL,解析器要么获得java.net.JarURLConnection从中,或者手动解析jar URL,然后遍历
jar文件中的内容来解析通配符。
对便携性的影响
如果指定的路径已经是文件URL(无论是隐含的,还是因为基底ResourceLoader是文件系统之一或显式的),万用卡保证为
完全便携地工作。
如果指定的路径是类路径地点,解析器必须获得最后一个
通过创建非通配符路径段 URL 来实现Classloader.getResource()叫。自此以来
只是路径的一个节点(不是末尾的文件),实际上它是未定义的(在ClassLoaderjavadoc)在这种情况下究竟返回了哪种类型的URL。实际上,
它总是java.io.file表示目录(其中 classpath 资源
解析到文件系统位置)或某种jar URL(其中classpath资源)
解析为一个罐子位置)。不过,这次作存在便携性问题。
如果为最后一个非万用字段获得了jar URL,解析器必须能够
拿一个java.net.JarURLConnection从它中或手动解析jar URL,以便能够
走动罐子里的内容物,解决万用牌。这在大多数环境中都有效
但在其他方面失败,我们强烈建议资源的变数解决
从罐子购买后,在使用之前一定要在你所在的环境中彻底测试。
这classpath*:前缀
在构建基于XML的应用上下文时,位置字符串可能会使用
特殊classpath*:前缀,如下示例所示:
-
Java
-
Kotlin
ApplicationContext ctx =
new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");
val ctx = ClassPathXmlApplicationContext("classpath*:conf/appContext.xml")
该特殊前缀指定所有与名称匹配的类路径资源
必须获得(内部,这本质上是通过调用ClassLoader.getResources(...)然后合并形成最终应用
上下文定义。
通配类路径依赖于getResources()基础的方法ClassLoader.因为现在大多数应用服务器都提供自己的服务ClassLoader实现时,行为可能会有所不同,尤其是在处理jar文件时。一个
简单的测试阶级路径*作品是使用ClassLoader从
在 classpath 上的一个罐子里:getClass().getClassLoader().getResources(“<someFileInsideTheJar>”).试试用
同名但位于两个不同位置的文件——例如,
同一个名字和相同的路径,但分在 classpath 的不同 jar 里。如果
如果结果不当,请查看应用服务器文档中的设置
这可能会影响ClassLoader行为。 |
你也可以结合classpath*:前缀为路径匹配器模式
其余位置路径(例如,classpath*:META-INF/*-beans.xml).在这方面
在该情形下,解析策略相当简单:AClassLoader.getResources()叫声为
用于最后一个非通配符路径段,以获取所有匹配的资源
类加载器层级,然后每个资源的层级相同路径匹配器分辨率
前述策略用于通配子路径。
与万用卡相关的其他说明
注意classpath*:,与蚁式图案结合时,只有
在模式开始前至少有一个根目录,除非实际
目标文件存储在文件系统中。这意味着像Classpath*:*.xml可能不会从jar文件的根节点检索文件,而是只从文件中获取
从扩展目录的根源开始。
Spring 检索类路径条目的能力源自 JDKClassLoader.getResources()方法,仅返回
空字符串(表示潜在的搜索根)。春季评估URLClassLoader运行时配置和java.class.path在jar文件中实现
同样如此,但这并不保证会导致便携行为。
|
扫描类路径包需要对应的目录
类路径中的条目。当你用Ant建造JAR时,不要激活 在JDK 9的模块路径(Jigsaw)中,Spring的类路径扫描通常正常。 这里也强烈建议将资源放入专门的目录, 避免了前述搜索 jar 文件根级时的可移植性问题。 |
蚁式模式Classpath:资源不保证能找到匹配的
资源:如果要搜索的根包在多个类路径位置上可用。
请考虑以下资源位置的示例:
com/mycompany/package1/service-context.xml
现在考虑一条类似Ant的路径,有人可能会用它来寻找该文件:
classpath:com/mycompany/**/service-context.xml
此类资源可能只存在于类路径中的一个位置,但当路径如
上述示例用于尝试解析,解析器基于(第一个)
URL返回getResource(“com/mycompany”);.如果这个基础包节点存在于
倍数ClassLoader地点,期望的资源可能不存在于第一个
位置已找到。因此,在这种情况下,你应该更倾向于使用classpath*:其中
同样的Ant风格模式,搜索所有包含com.mycompany基础包:Classpath*:com/mycompany/**/service-context.xml.
文件系统资源警告
一个文件系统资源不附着于FileSystemApplicationContext(那个
是,当 aFileSystemApplicationContext不是实际的ResourceLoader) treat
正如你所预期的,绝对路径和相对路径。相对路径相对于
当前工作目录,而绝对路径相对于
文件系统。
然而,出于向后兼容性(历史)原因,当FileSystemApplicationContext是ResourceLoader.这FileSystemApplicationContext所有部队都附着文件系统资源实例
把所有位置路径都当作相对的,无论它们是否以前导斜线开头。
实际上,这意味着以下例子是等价的:
-
Java
-
Kotlin
ApplicationContext ctx =
new FileSystemXmlApplicationContext("conf/context.xml");
val ctx = FileSystemXmlApplicationContext("conf/context.xml")
-
Java
-
Kotlin
ApplicationContext ctx =
new FileSystemXmlApplicationContext("/conf/context.xml");
val ctx = FileSystemXmlApplicationContext("/conf/context.xml")
以下例子也是等价的(尽管它们作为一个不同是合理的 情况是相对的,另一个是绝对的):
-
Java
-
Kotlin
FileSystemXmlApplicationContext ctx = ...;
ctx.getResource("some/resource/path/myTemplate.txt");
val ctx: FileSystemXmlApplicationContext = ...
ctx.getResource("some/resource/path/myTemplate.txt")
-
Java
-
Kotlin
FileSystemXmlApplicationContext ctx = ...;
ctx.getResource("/some/resource/path/myTemplate.txt");
val ctx: FileSystemXmlApplicationContext = ...
ctx.getResource("/some/resource/path/myTemplate.txt")
实际上,如果你需要真正的绝对文件系统路径,应避免使用
绝对路径文件系统资源或文件系统Xml应用上下文和
强制使用UrlResource通过使用文件:URL前缀。以下示例
展示如何作:
-
Java
-
Kotlin
// actual context type doesn't matter, the Resource will always be UrlResource
ctx.getResource("file:///some/resource/path/myTemplate.txt");
// actual context type doesn't matter, the Resource will always be UrlResource
ctx.getResource("file:///some/resource/path/myTemplate.txt")
-
Java
-
Kotlin
// force this FileSystemXmlApplicationContext to load its definition via a UrlResource
ApplicationContext ctx =
new FileSystemXmlApplicationContext("file:///conf/context.xml");
// force this FileSystemXmlApplicationContext to load its definition via a UrlResource
val ctx = FileSystemXmlApplicationContext("file:///conf/context.xml")