概述
–> go to 总目录
文章目录
- 2.4 Resourceloader
- 2.5 The ResourceLoaderAware interface
- 2.6 Resource as Dependencies
- 2.7 Application Contexts 和 Resource Paths
- 2.7.1. Constructing Application Contexts
- Constructing ClassPathXmlApplicationContext Instances — Shortcuts
- 2.7.2 通配符的使用 Application Context Constructor Resource Paths
- Ant-style模式
- 兼容的含义
- The classpath*: Prefix
- 其他相关联的通配符
- 2.7.3 FileSystemResource告警
2.4 Resourceloader
ResourceLoader 接口被用来加载实现了Resource
接口的实例。
接口定义
所有应用程序上下文都实现ResourceLoader接口。因此,所有应用程序上下文都可用于获取Resource实例。
当您在特定的应用程序上下文中调用getResource(),并且指定的位置路径没有特定的前缀时,您将获得适合该特定应用程序上下文的Resource类型。例如,假定针对ClassPathXmlApplicationContext实例执行了以下代码片段:
针对ClassPathXmlApplicationContext,该代码返回ClassPathResource。如果对FileSystemXmlApplicationContext实例执行了相同的方法,则它将返回FileSystemResource。对于WebApplicationContext,它将返回ServletContextResource。类似地,它将为每个上下文返回适当的对象。
结果,您可以以适合特定应用程序上下文的方式加载资源。
另一方面,您也可以通过指定特殊的classpath:前缀来强制使用ClassPathResource,而与应用程序上下文类型无关,如下例所示:
2.5 The ResourceLoaderAware interface
ResourceLoaderAware 接口可以提供ResourceLoader实例,实现它即可。
发现机制
当类实现ResourceLoaderAware并部署到应用程序上下文中(作为Spring托管的bean)时,该类被应用程序上下文识别为ResourceLoaderAware。然后,应用程序上下文调用setResourceLoader(ResourceLoader),将自身作为参数提供(请记住,Spring中的所有应用程序上下文均实现ResourceLoader接口)。
推荐使用
由于ApplicationContext是ResourceLoader,因此Bean也可以实现ApplicationContextAware接口,并直接使用提供的应用程序上下文来加载资源。但是,通常,如果需要的话,最好使用专门的ResourceLoader接口。该代码将仅耦合到资源加载接口(可以视为实用程序接口),而不耦合到整个Spring ApplicationContext接口。
推荐使用
在应用程序组件中,您还可以依赖自动装配ResourceLoader来实现ResourceLoaderAware接口。 “传统”构造函数和byType自动装配模式(如“自动装配协作器”中所述)能够分别为构造函数参数或setter方法参数提供ResourceLoader。为了获得更大的灵活性(包括自动装配字段和多个参数方法的能力),请考虑使用基于注释的自动装配功能。在这种情况下,只要有问题的字段,构造函数或方法带有@Autowired批注,ResourceLoader就会自动连接到需要ResourceLoader类型的字段,构造函数参数或方法参数中。有关更多信息,请参见使用@Autowired。
2.6 Resource as Dependencies
如果Bean本身将通过某种动态过程来确定并提供资源路径,那么对于Bean来说,使用ResourceLoader接口加载资源可能是有意义的。例如,考虑加载某种模板,其中所需的特定资源取决于用户的角色。如果资源是静态的,则有必要完全消除对ResourceLoader接口的使用,让Bean公开所需的Resource属性,并期望将其注入其中。
注入这些属性的麻烦之处在于,所有应用程序上下文都注册并使用了特殊的JavaBeans PropertyEditor,可以将String路径转换为Resource对象。因此,如果myBean具有资源类型的模板属性,则可以为该资源配置一个简单的字符串,如以下示例所示:
请注意,资源路径没有前缀。因此,由于应用程序上下文本身将用作ResourceLoader,因此根据上下文的确切类型,通过ClassPathResource,FileSystemResource或ServletContextResource加载资源本身。
如果需要强制使用特定的资源类型,则可以使用前缀。以下两个示例显示了如何强制ClassPathResource和UrlResource(后者用于访问文件系统文件):
2.7 Application Contexts 和 Resource Paths
2.7.1. Constructing Application Contexts
一个容器的构造器一般接受几个String作为参数。
当没有具体的协议或者前缀,Resource从load加载bean。
从以下ClassPathXmlApplicationContext
中加载的就是ClassPathResource
使用FileSystemXmlApplicationContext从类路径加载bean定义。但是,它仍然是FileSystemXmlApplicationContext。如果随后将其用作ResourceLoader,则所有未前缀的路径仍将视为文件系统路径。
Constructing ClassPathXmlApplicationContext Instances — Shortcuts
ClassPathXmlApplicationContext暴露了很多遍历的构造器,核心的思想是你仅需要提供很少的String(文件名或者xml名称),也会支持class类 。ClassPathXmlApplicationContext从被提供的类路径加载
示例
思考一下文件结构
加载成Context
2.7.2 通配符的使用 Application Context Constructor Resource Paths
应用程序上下文构造函数值中的资源路径可以是简单路径(如先前所示),每个路径都具有到目标资源的一对一映射,或者可以包含特殊的“ classpath *:”前缀或内部Ant。样式的正则表达式(通过使用Spring的PathMatcher实用程序进行匹配)。后者都是有效的通配符。
这种机制的一种用途是当您需要进行组件样式的应用程序组装时。所有组件都可以将上下文定义片段“发布”到一个众所周知的位置路径,并且当使用前缀为classpath *:的相同路径创建最终应用程序上下文时,将自动拾取所有组件片段。
请注意,此通配符特定于在应用程序上下文构造函数中使用资源路径(或当您直接使用PathMatcher实用工具类层次结构时),并且在构造时已解决。它与资源类型本身无关。您不能使用classpath *:前缀来构造实际的Resource,因为资源一次仅指向一个资源。
Ant-style模式
当路径位置包含Ant样式的模式时,解析程序将遵循更复杂的过程来尝试解析通配符。它为到达最后一个非通配符段的路径生成资源,并从中获取URL。如果此URL不是jar:URL或特定于容器的变体(例如WebLogic中的zip:,WebSphere中的wsjar等),则从中获取java.io.File并将其用于遍历文件系统。对于jar URL,解析器可以从中获取java.net.JarURLConnection,也可以手动解析jar URL,然后遍历jar文件的内容以解析通配符。
兼容的含义
测试为王
如果指定的路径已经是一个文件URL(由于基本ResourceLoader是一个文件系统,所以它是隐式的,或者是显式的),则保证通配符可以完全可移植的方式工作。
如果指定的路径是类路径位置,则解析器必须通过调用Classloader.getResource()获得最后的非通配符路径段URL。由于这只是路径的一个节点(而不是末尾的文件),因此实际上(在ClassLoader javadoc中)未定义确切返回的是哪种URL。实际上,它始终是一个java.io.File,代表目录(类路径资源解析为文件系统位置)或某个jar URL(类路径资源解析为jar位置)。尽管如此,此操作仍存在可移植性问题。
如果为最后一个非通配符段获取了jar URL,则解析程序必须能够从中获取java.net.JarURLConnection或手动解析jar URL,以便能够遍历jar的内容并解析通配符。这在大多数环境中确实有效,但在其他环境中则无效,因此我们强烈建议您在依赖特定环境之前,对来自jars的资源的通配符解析进行彻底测试。
The classpath*: Prefix
这个特殊的前缀意味着所有和给定名称匹配的Classpath的的Resource必须被获取(内部,这实际上是通过调用ClassLoader.getResources(…)发生的),然后合并以形成最终的应用程序上下文定义
!通配符类路径依赖于基础类加载器的getResources()方法。由于当今大多数应用程序服务器都提供自己的类加载器实现,因此行为可能有所不同,尤其是在处理jar文件时。检查classpath *是否可行的简单测试是使用classloader从classpath的jar中加载文件:getClass().getClassLoader().getResources(“ ”)。尝试对具有相同名称但位于两个不同位置的文件进行此测试。如果返回了不合适的结果,请检查应用程序服务器文档中可能影响类加载器行为的设置。
也可以和name的通配符搭配使用
classpath*:META-INF/*-beans.xml).
其他相关联的通配符
请注意,将classpath*:与Ant样式的模式结合使用时,除非模式文件实际驻留在文件系统中,否则在模式启动之前,它只能与至少一个根目录可靠地一起工作。这意味着诸如classpath**。xml之类的模式可能不会从jar文件的根目录检索文件,而只会从扩展目录的根目录检索文件。
Spring检索类路径条目的能力源自JDK的ClassLoader.getResources()方法,该方法仅返回文件系统中的空字符串位置(指示可能要搜索的根)。 Spring还评估jar文件中的URLClassLoader运行时配置和java.class.path清单,但这不能保证会导致可移植行为。
扫描类路径包需要在类路径中存在相应的目录条目。使用Ant构建JAR时,请勿激活JAR任务的file-only开关。另外,在某些环境中,基于安全策略,可能不会暴露类路径目录-例如,在JDK 1.7.0_45及更高版本上的独立应用程序(要求在清单中设置“受信任的库”。请参阅https:// /stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources)。
在JDK 9的模块路径(Jigsaw)上,Spring的类路径扫描通常可以按预期进行。强烈建议在此处将资源放入专用目录,以避免在搜索jar文件根目录级别时出现上述可移植性问题。
具有classpath的蚂蚁样式模式:如果要搜索的根包在多个类路径位置可用,则不能保证资源找到匹配的资源。考虑以下资源位置示例:
2.7.3 FileSystemResource告警
未附加到FileSystemApplicationContext的FileSystemResource(即,当FileSystemApplicationContext不是实际的ResourceLoader时)将按您期望的那样对待绝对路径和相对路径。相对路径是相对于当前工作目录的,而绝对路径是相对于文件系统的根的。
但是,出于向后兼容性(历史)的原因,当FileSystemApplicationContext是ResourceLoader时,情况会发生变化。 FileSystemApplicationContext强制所有附加的FileSystemResource实例将所有位置路径都视为相对位置,无论它们是否以前导斜杠开头。实际上,这意味着以下示例是等效的:
等效
在实践中,如果需要真正的绝对文件系统路径,则应避免将绝对路径与FileSystemResource或FileSystemXmlApplicationContext一起使用,并通过使用file:URL前缀来强制使用UrlResource。以下示例显示了如何执行此操作:
最后
以上就是危机荷花为你收集整理的b spring 之资源加载器--resourceLoader2.4 Resourceloader2.5 The ResourceLoaderAware interface2.6 Resource as Dependencies2.7 Application Contexts 和 Resource Paths的全部内容,希望文章能够帮你解决b spring 之资源加载器--resourceLoader2.4 Resourceloader2.5 The ResourceLoaderAware interface2.6 Resource as Dependencies2.7 Application Contexts 和 Resource Paths所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复