免费做公司手机网站怎样在网站做环评公示

bicheng/2026/1/18 13:01:55/文章来源:
免费做公司手机网站,怎样在网站做环评公示,常州被约谈企业主公司发讣告,抽奖网站插件前言 在学 Java的时候#xff0c;我们学习了一个标准类 java.net.URL#xff0c;该类在 Java SE 中的定位为统一资源定位器#xff08;Uniform Resource Locator#xff09;#xff0c;但是我们知道它的实现基本只限于网络形式发布的资源的查找和定位。然而#xff0c;实…前言 在学 Java的时候我们学习了一个标准类 java.net.URL该类在 Java SE 中的定位为统一资源定位器Uniform Resource Locator但是我们知道它的实现基本只限于网络形式发布的资源的查找和定位。然而实际上资源的定义比较广泛除了网络形式的资源还有以二进制形式存在的、以文件形式存在的、以字节流形式存在的等等。而且它可以存在于任何场所比如网络、文件系统、应用程序中。所以 java.net.URL 的局限性迫使 Spring 必须实现自己的资源加载策略该资源加载策略需要满足如下要求 职能划分清楚。资源的定义和资源的加载应该要有一个清晰的界限统一的抽象。统一的资源定义和资源加载策略。资源加载后要返回统一的抽象给客户端客户端要对资源进行怎样的处理应该由抽象资源接口来界定。 1. 统一资源Resource org.springframework.core.io.Resource 为 Spring 框架所有资源的抽象和访问接口它继承 org.springframework.core.io.InputStreamSource接口。作为所有资源的统一抽象Resource 定义了一些通用的方法由子类 AbstractResource 提供统一的默认实现。定义如下 public interface Resource extends InputStreamSource {/*** 资源是否存在*/boolean exists();/*** 资源是否可读*/default boolean isReadable() {return true;}/*** 资源所代表的句柄是否被一个 stream 打开了*/default boolean isOpen() {return false;}/*** 是否为 File*/default boolean isFile() {return false;}/*** 返回资源的 URL 的句柄*/URL getURL() throws IOException;/*** 返回资源的 URI 的句柄*/URI getURI() throws IOException;/*** 返回资源的 File 的句柄*/File getFile() throws IOException;/*** 返回 ReadableByteChannel*/default ReadableByteChannel readableChannel() throws IOException {return java.nio.channels.Channels.newChannel(getInputStream());}/*** 资源内容的长度*/long contentLength() throws IOException;/*** 资源最后的修改时间*/long lastModified() throws IOException;/*** 根据资源的相对路径创建新资源*/Resource createRelative(String relativePath) throws IOException;/*** 资源的文件名*/NullableString getFilename();/*** 资源的描述*/String getDescription();} 1.1 子类结构 类结构图如下 从上图可以看到Resource 根据资源的不同类型提供不同的具体实现如下 FileSystemResource 对 java.io.File 类型资源的封装只要是跟 File 打交道的基本上与 FileSystemResource 也可以打交道。支持文件和 URL 的形式实现 WritableResource 接口且从 Spring Framework 5.0 开始FileSystemResource 使用 NIO2 API进行读/写交互。ByteArrayResource 对字节数组提供的数据的封装。如果通过 InputStream 形式访问该类型的资源该实现会根据字节数组的数据构造一个相应的 ByteArrayInputStream。UrlResource 对 java.net.URL类型资源的封装。内部委派 URL 进行具体的资源操作。ClassPathResource class path 类型资源的实现。使用给定的 ClassLoader 或者给定的 Class 来加载资源。InputStreamResource 将给定的 InputStream 作为一种资源的 Resource 的实现类。 1.2 AbstractResource org.springframework.core.io.AbstractResource 为 Resource 接口的默认抽象实现。它实现了 Resource 接口的大部分的公共实现作为 Resource 接口中的重中之重其定义如下 public abstract class AbstractResource implements Resource {/*** 判断文件是否存在若判断过程产生异常因为会调用SecurityManager来判断就关闭对应的流*/Overridepublic boolean exists() {try {// 基于 File 进行判断return getFile().exists();}catch (IOException ex) {// Fall back to stream existence: can we open the stream?// 基于 InputStream 进行判断try {InputStream is getInputStream();is.close();return true;} catch (Throwable isEx) {return false;}}}/*** 直接返回true表示可读*/Overridepublic boolean isReadable() {return true;}/*** 直接返回 false表示未被打开*/Overridepublic boolean isOpen() {return false;}/*** 直接返回false表示不为 File*/Overridepublic boolean isFile() {return false;}/*** 抛出 FileNotFoundException 异常交给子类实现*/Overridepublic URL getURL() throws IOException {throw new FileNotFoundException(getDescription() cannot be resolved to URL);}/*** 基于 getURL() 返回的 URL 构建 URI*/Overridepublic URI getURI() throws IOException {URL url getURL();try {return ResourceUtils.toURI(url);} catch (URISyntaxException ex) {throw new NestedIOException(Invalid URI [ url ], ex);}}/*** 抛出 FileNotFoundException 异常交给子类实现*/Overridepublic File getFile() throws IOException {throw new FileNotFoundException(getDescription() cannot be resolved to absolute file path);}/*** 根据 getInputStream() 的返回结果构建 ReadableByteChannel*/Overridepublic ReadableByteChannel readableChannel() throws IOException {return Channels.newChannel(getInputStream());}/*** 获取资源的长度** 这个资源内容长度实际就是资源的字节长度通过全部读取一遍来判断*/Overridepublic long contentLength() throws IOException {InputStream is getInputStream();try {long size 0;byte[] buf new byte[255]; // 每次最多读取 255 字节int read;while ((read is.read(buf)) ! -1) {size read;}return size;} finally {try {is.close();} catch (IOException ex) {}}}/*** 返回资源最后的修改时间*/Overridepublic long lastModified() throws IOException {long lastModified getFileForLastModifiedCheck().lastModified();if (lastModified 0L) {throw new FileNotFoundException(getDescription() cannot be resolved in the file system for resolving its last-modified timestamp);}return lastModified;}protected File getFileForLastModifiedCheck() throws IOException {return getFile();}/*** 抛出 FileNotFoundException 异常交给子类实现*/Overridepublic Resource createRelative(String relativePath) throws IOException {throw new FileNotFoundException(Cannot create a relative resource for getDescription());}/*** 获取资源名称默认返回 null 交给子类实现*/OverrideNullablepublic String getFilename() {return null;}/*** 返回资源的描述*/Overridepublic String toString() {return getDescription();}Overridepublic boolean equals(Object obj) {return (obj this ||(obj instanceof Resource ((Resource) obj).getDescription().equals(getDescription())));}Overridepublic int hashCode() {return getDescription().hashCode();}}如果我们想要实现自定义的 Resource 记住不要实现 Resource 接口而应该继承 AbstractResource 抽象类然后根据当前的具体资源特性覆盖相应的方法即可。 1.3 其他子类 Resource 的子类例如 FileSystemResource、ByteArrayResource 等等的代码非常简单。感兴趣的同学自己去研究。 2. 统一资源定位ResourceLoader 一开始就说了 Spring 将资源的定义和资源的加载区分开了Resource 定义了统一的资源那资源的加载则由 ResourceLoader 来统一定义。 org.springframework.core.io.ResourceLoader 为 Spring 资源加载的统一抽象具体的资源加载则由相应的实现类来完成所以我们可以将 ResourceLoader 称作为统一资源定位器。其定义如下 public interface ResourceLoader {String CLASSPATH_URL_PREFIX ResourceUtils.CLASSPATH_URL_PREFIX; // CLASSPATH URL 前缀。默认为classpath:Resource getResource(String location);ClassLoader getClassLoader();}#getResource(String location) 方法根据所提供资源的路径 location 返回 Resource 实例但是它不确保该 Resource 一定存在需要调用 Resource#exist() 方法来判断。 该方法支持以下模式的资源加载 URL位置资源如 file:C:/test.dat 。ClassPath位置资源如 classpath:test.dat 。相对路径资源如 WEB-INF/test.dat 此时返回的Resource 实例根据实现不同而不同。该方法的主要实现是在其子类 DefaultResourceLoader 中实现具体过程我们在分析 DefaultResourceLoader 时做详细说明。#getClassLoader() 方法返回 ClassLoader 实例对于想要获取 ResourceLoader 使用的 ClassLoader 用户来说可以直接调用该方法来获取。在分析 Resource 时提到了一个类 ClassPathResource 这个类是可以根据指定的 ClassLoader 来加载资源的。 2.1 DefaultResourceLoader 与 AbstractResource 相似org.springframework.core.io.DefaultResourceLoader 是 ResourceLoader 的默认实现。 2.1.1 构造函数 它接收 ClassLoader 作为构造函数的参数或者使用不带参数的构造函数。 在使用不带参数的构造函数时使用的 ClassLoader 为默认的 ClassLoader一般 Thread.currentThread()#getContextClassLoader() 。在使用带参数的构造函数时可以通过 ClassUtils#getDefaultClassLoader()获取。 另外也可以调用 #setClassLoader() 方法进行后续设置。 Nullable private ClassLoader classLoader;public DefaultResourceLoader() { // 无参构造函数this.classLoader ClassUtils.getDefaultClassLoader(); }public DefaultResourceLoader(Nullable ClassLoader classLoader) { // 带 ClassLoader 参数的构造函数this.classLoader classLoader; }public void setClassLoader(Nullable ClassLoader classLoader) {this.classLoader classLoader; }Override Nullable public ClassLoader getClassLoader() {return (this.classLoader ! null ? this.classLoader : ClassUtils.getDefaultClassLoader()); }2.1.2 getResource 方法 ResourceLoader 中最核心的方法为 #getResource(String location) 它根据提供的 location 返回相应的 Resource 。而 DefaultResourceLoader 对该方法提供了核心实现因为它的两个子类都没有提供覆盖该方法所以可以断定 ResourceLoader 的资源加载策略就封装在 DefaultResourceLoader 中)代码如下 // DefaultResourceLoader.javaOverride public Resource getResource(String location) {Assert.notNull(location, Location must not be null);// 首先通过 ProtocolResolver 来加载资源for (ProtocolResolver protocolResolver : this.protocolResolvers) {Resource resource protocolResolver.resolve(location, this);if (resource ! null) {return resource;}}// 其次以 / 开头返回 ClassPathContextResource 类型的资源if (location.startsWith(/)) {return getResourceByPath(location);// 再次以 classpath: 开头返回 ClassPathResource 类型的资源} else if (location.startsWith(CLASSPATH_URL_PREFIX)) {return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());// 然后根据是否为文件 URL 是则返回 FileUrlResource 类型的资源否则返回 UrlResource 类型的资源} else {try {// Try to parse the location as a URL...URL url new URL(location);return (ResourceUtils.isFileURL(url) ? new FileUrlResource(url) : new UrlResource(url));} catch (MalformedURLException ex) {// 最后返回 ClassPathContextResource 类型的资源// No URL - resolve as resource path.return getResourceByPath(location);}} }首先通过 ProtocolResolver 来加载资源成功返回 Resource 。 其次若 location 以 / 开头则调用 #getResourceByPath() 方法构造 ClassPathContextResource 类型资源并返回。代码如下 protected Resource getResourceByPath(String path) {return new ClassPathContextResource(path, getClassLoader()); }再次若 location 以 classpath: 开头则构造 ClassPathResource 类型资源并返回。在构造该资源时通过 #getClassLoader() 获取当前的 ClassLoader。然后构造 URL 尝试通过它进行资源定位若没有抛出 MalformedURLException 异常则判断是否为 FileURL , 如果是则构造 FileUrlResource 类型的资源否则构造 UrlResource 类型的资源。最后若在加载过程中抛出 MalformedURLException 异常则委派 #getResourceByPath() 方法实现资源定位加载。实际上和【其次】相同落。 2.1.3 ProtocolResolver org.springframework.core.io.ProtocolResolver 用户自定义协议资源解决策略作为 DefaultResourceLoader 的 SPI它允许用户自定义资源加载协议而不需要继承 ResourceLoader 的子类。 在介绍 Resource 时提到如果要实现自定义 Resource我们只需要继承 AbstractResource 即可但是有了 ProtocolResolver 后我们不需要直接继承 DefaultResourceLoader改为实现 ProtocolResolver 接口也可以实现自定义的 ResourceLoader。 ProtocolResolver 接口仅有一个方法 Resource resolve(String location, ResourceLoader resourceLoader) 。代码如下 /*** 使用指定的 ResourceLoader 解析指定的 location 。* 若成功则返回对应的 Resource 。** Resolve the given location against the given resource loader* if this implementations protocol matches.* param location the user-specified resource location 资源路径* param resourceLoader the associated resource loader 指定的加载器 ResourceLoader* return a corresponding {code Resource} handle if the given location* matches this resolvers protocol, or {code null} otherwise 返回为相应的 Resource*/ Nullable Resource resolve(String location, ResourceLoader resourceLoader);在 Spring 中你会发现该接口并没有实现类它需要用户自定义自定义的 Resolver 如何加入 Spring 体系呢调用 DefaultResourceLoader#addProtocolResolver(ProtocolResolver) 方法即可。代码如下 /*** ProtocolResolver 集合*/ private final SetProtocolResolver protocolResolvers new LinkedHashSet(4);public void addProtocolResolver(ProtocolResolver resolver) {Assert.notNull(resolver, ProtocolResolver must not be null);this.protocolResolvers.add(resolver); }2.1.4 示例 下面示例是演示 DefaultResourceLoader 加载资源的具体策略代码如下该示例参考《Spring 揭秘》 P89 ResourceLoader resourceLoader new DefaultResourceLoader();Resource fileResource1 resourceLoader.getResource(D:/Users/chenming673/Documents/spark.txt); System.out.println(fileResource1 is FileSystemResource: (fileResource1 instanceof FileSystemResource));Resource fileResource2 resourceLoader.getResource(/Users/chenming673/Documents/spark.txt); System.out.println(fileResource2 is ClassPathResource: (fileResource2 instanceof ClassPathResource));Resource urlResource1 resourceLoader.getResource(file:/Users/chenming673/Documents/spark.txt); System.out.println(urlResource1 is UrlResource: (urlResource1 instanceof UrlResource));Resource urlResource2 resourceLoader.getResource(http://www.baidu.com); System.out.println(urlResource1 is urlResource: (urlResource2 instanceof UrlResource)); 运行结果 fileResource1 is FileSystemResource:false fileResource2 is ClassPathResource:true urlResource1 is UrlResource:true urlResource1 is urlResource:true 其实对于 fileResource1 我们更加希望是 FileSystemResource 资源类型。但是事与愿违它是 ClassPathResource 类型。为什么呢在 DefaultResourceLoader#getResource() 方法的资源加载策略中我们知道 D:/Users/chenming673/Documents/spark.txt 地址其实在该方法中没有相应的资源类型那么它就会在抛出 MalformedURLException 异常时通过 DefaultResourceLoader#getResourceByPath(...) 方法构造一个 ClassPathResource 类型的资源。而 urlResource1 和 urlResource2 指定有协议前缀的资源路径则通过 URL 就可以定义所以返回的都是 UrlResource 类型。 2.2 FileSystemResourceLoader 从上面的示例我们看到其实 DefaultResourceLoader 对#getResourceByPath(String) 方法处理其实不是很恰当这个时候我们可以使用 org.springframework.core.io.FileSystemResourceLoader 。它继承 DefaultResourceLoader 且覆写了 #getResourceByPath(String) 方法使之从文件系统加载资源并以 FileSystemResource 类型返回这样我们就可以得到想要的资源类型。代码如下 Override protected Resource getResourceByPath(String path) {// 截取首 /if (path.startsWith(/)) {path path.substring(1);}// 创建 FileSystemContextResource 类型的资源return new FileSystemContextResource(path); }2.2.1 FileSystemContextResource FileSystemContextResource 为 FileSystemResourceLoader 的内部类它继承 FileSystemResource 类实现 ContextResource 接口。代码如下 /*** FileSystemResource that explicitly expresses a context-relative path* through implementing the ContextResource interface.*/ private static class FileSystemContextResource extends FileSystemResource implements ContextResource {public FileSystemContextResource(String path) {super(path);}Overridepublic String getPathWithinContext() {return getPath();} }在构造器中也是调用 FileSystemResource 的构造函数来构造 FileSystemResource 的。为什么要有 FileSystemContextResource 类的原因是实现 ContextResource 接口并实现对应的 #getPathWithinContext() 接口方法。 2.3 ClassRelativeResourceLoader org.springframework.core.io.ClassRelativeResourceLoader 是 DefaultResourceLoader 的另一个子类的实现。和 FileSystemResourceLoader 类似在实现代码的结构上类似也是覆写 #getResourceByPath(String path) 方法并返回其对应的 ClassRelativeContextResource 的资源类型。 2.4 ResourcePatternResolver ResourceLoader 的 Resource getResource(String location) 方法每次只能根据 location 返回一个 Resource 。当需要加载多个资源时我们除了多次调用 #getResource(String location) 方法外别无他法。org.springframework.core.io.support.ResourcePatternResolver 是 ResourceLoader 的扩展它支持根据指定的资源路径匹配模式每次返回多个 Resource 实例其定义如下 public interface ResourcePatternResolver extends ResourceLoader {String CLASSPATH_ALL_URL_PREFIX classpath*:;Resource[] getResources(String locationPattern) throws IOException;}ResourcePatternResolver 在 ResourceLoader 的基础上增加了 #getResources(String locationPattern) 方法以支持根据路径匹配模式返回多个 Resource 实例。同时也新增了一种新的协议前缀 classpath*:该协议前缀由其子类负责实现。 2.5 PathMatchingResourcePatternResolver org.springframework.core.io.support.PathMatchingResourcePatternResolver 为 ResourcePatternResolver 最常用的子类它除了支持 ResourceLoader 和 ResourcePatternResolver 新增的 classpath*: 前缀外还支持 Ant 风格的路径匹配模式类似于 **/*.xml。 2.5.1 构造函数 PathMatchingResourcePatternResolver 提供了三个构造函数如下 /*** 内置的 ResourceLoader 资源定位器*/ private final ResourceLoader resourceLoader; /*** Ant 路径匹配器*/ private PathMatcher pathMatcher new AntPathMatcher();public PathMatchingResourcePatternResolver() {this.resourceLoader new DefaultResourceLoader(); }public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {Assert.notNull(resourceLoader, ResourceLoader must not be null);this.resourceLoader resourceLoader; }public PathMatchingResourcePatternResolver(Nullable ClassLoader classLoader) {this.resourceLoader new DefaultResourceLoader(classLoader); }PathMatchingResourcePatternResolver 在实例化的时候可以指定一个 ResourceLoader如果不指定的话它会在内部构造一个 DefaultResourceLoader 。pathMatcher 属性默认为 AntPathMatcher 对象用于支持 Ant 类型的路径匹配。 2.5.2 getResource Override public Resource getResource(String location) {return getResourceLoader().getResource(location); }public ResourceLoader getResourceLoader() {return this.resourceLoader; }该方法直接委托给相应的 ResourceLoader 来实现。所以如果我们在实例化的 PathMatchingResourcePatternResolver 的时候如果未指定 ResourceLoader 参数的情况下那么在加载资源时其实就是 DefaultResourceLoader 的过程。 其实在下面介绍的 Resource[] getResources(String locationPattern) 方法也相同只不过返回的资源是多个而已。 2.5.3 getResources Override public Resource[] getResources(String locationPattern) throws IOException {Assert.notNull(locationPattern, Location pattern must not be null);// 以 classpath*: 开头if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {// 路径包含通配符// a class path resource (multiple resources for same name possible)if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {// a class path resource patternreturn findPathMatchingResources(locationPattern);// 路径不包含通配符} else {// all class path resources with the given namereturn findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));}// 不以 classpath*: 开头} else {// Generally only look for a pattern after a prefix here, // 通常只在这里的前缀后面查找模式// and on Tomcat only after the */ separator for its war: protocol. 而在 Tomcat 上只有在 “*/ ”分隔符之后才为其 “war:” 协议int prefixEnd (locationPattern.startsWith(war:) ? locationPattern.indexOf(*/) 1 :locationPattern.indexOf(:) 1);// 路径包含通配符if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {// a file patternreturn findPathMatchingResources(locationPattern);// 路径不包含通配符} else {// a single resource with the given namereturn new Resource[] {getResourceLoader().getResource(locationPattern)};}} }非 classpath*: 开头且路径不包含通配符直接委托给相应的 ResourceLoader 来实现。其他情况调用 #findAllClassPathResources(...)、或 #findPathMatchingResources(...) 方法返回多个 Resource 。下面我们来详细分析。 2.5.4 findAllClassPathResources 当 locationPattern 以 classpath*: 开头但是不包含通配符则调用 #findAllClassPathResources(...) 方法加载资源。该方法返回 classes 路径下和所有 jar 包中的所有相匹配的资源。 protected Resource[] findAllClassPathResources(String location) throws IOException {String path location;// 去除首个 /if (path.startsWith(/)) {path path.substring(1);}// 真正执行加载所有 classpath 资源SetResource result doFindAllClassPathResources(path);if (logger.isTraceEnabled()) {logger.trace(Resolved classpath location [ location ] to resources result);}// 转换成 Resource 数组返回return result.toArray(new Resource[0]); }真正执行加载的是在 #doFindAllClassPathResources(...) 方法代码如下 protected SetResource doFindAllClassPathResources(String path) throws IOException {SetResource result new LinkedHashSet(16);ClassLoader cl getClassLoader();// 1 根据 ClassLoader 加载路径下的所有资源EnumerationURL resourceUrls (cl ! null ? cl.getResources(path) : ClassLoader.getSystemResources(path));// 2while (resourceUrls.hasMoreElements()) {URL url resourceUrls.nextElement();// 将 URL 转换成 UrlResourceresult.add(convertClassLoaderURL(url));}// 3 加载路径下得所有 jar 包if (.equals(path)) {// The above result is likely to be incomplete, i.e. only containing file system references.// We need to have pointers to each of the jar files on the classpath as well...addAllClassLoaderJarRoots(cl, result);}return result; }1 处根据 ClassLoader 加载路径下的所有资源。在加载资源过程时如果在构造 PathMatchingResourcePatternResolver 实例的时候如果传入了 ClassLoader则调用该 ClassLoader 的 #getResources() 方法否则调用 ClassLoader#getSystemResources(path) 方法。另外ClassLoader#getResources() 方法代码如下: // java.lang.ClassLoader.java public EnumerationURL getResources(String name) throws IOException {SuppressWarnings(unchecked)EnumerationURL[] tmp (EnumerationURL[]) new Enumeration?[2];if (parent ! null) {tmp[0] parent.getResources(name);} else {tmp[0] getBootstrapResources(name);}tmp[1] findResources(name);return new CompoundEnumeration(tmp); }看到这里是不是就已经一目了然了如果当前父类加载器不为 null 则通过父类向上迭代获取资源否则调用 #getBootstrapResources() 。这里是不是特别熟悉(^▽^)。 2 处遍历 URL 集合调用 #convertClassLoaderURL(URL url) 方法将 URL 转换成 UrlResource 对象。代码如下 protected Resource convertClassLoaderURL(URL url) {return new UrlResource(url); } 3 处若 path 为空“”时则调用 #addAllClassLoaderJarRoots(...)方法。该方法主要是加载路径下得所有 jar 包方法较长也没有什么实际意义就不贴出来了。 通过上面的分析我们知道 #findAllClassPathResources(...) 方法其实就是利用 ClassLoader 来加载指定路径下的资源不论它是在 class 路径下还是在 jar 包中。如果我们传入的路径为空或者 /则会调用 #addAllClassLoaderJarRoots(...) 方法加载所有的 jar 包。 2.5.5 findPathMatchingResources 当 locationPattern 中包含了通配符则调用该方法进行资源加载。代码如下 protected Resource[] findPathMatchingResources(String locationPattern) throws IOException {// 确定根路径、子路径String rootDirPath determineRootDir(locationPattern);String subPattern locationPattern.substring(rootDirPath.length());// 获取根据路径下的资源Resource[] rootDirResources getResources(rootDirPath);// 遍历迭代SetResource result new LinkedHashSet(16);for (Resource rootDirResource : rootDirResources) {rootDirResource resolveRootDirResource(rootDirResource);URL rootDirUrl rootDirResource.getURL();// bundle 资源类型if (equinoxResolveMethod ! null rootDirUrl.getProtocol().startsWith(bundle)) {URL resolvedUrl (URL) ReflectionUtils.invokeMethod(equinoxResolveMethod, null, rootDirUrl);if (resolvedUrl ! null) {rootDirUrl resolvedUrl;}rootDirResource new UrlResource(rootDirUrl);}// vfs 资源类型if (rootDirUrl.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {result.addAll(VfsResourceMatchingDelegate.findMatchingResources(rootDirUrl, subPattern, getPathMatcher()));// jar 资源类型} else if (ResourceUtils.isJarURL(rootDirUrl) || isJarResource(rootDirResource)) {result.addAll(doFindPathMatchingJarResources(rootDirResource, rootDirUrl, subPattern));// 其它资源类型} else {result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern));}}if (logger.isTraceEnabled()) {logger.trace(Resolved location pattern [ locationPattern ] to resources result);}// 转换成 Resource 数组返回return result.toArray(new Resource[0]); } 方法有点儿长但是思路还是很清晰的主要分两步 确定目录获取该目录下得所有资源。在所获得的所有资源后进行迭代匹配获取我们想要的资源。 在这个方法里面我们要关注两个方法一个是 #determineRootDir(String location) 方法一个是 #doFindPathMatchingXXXResources(...) 等方法。 2.5.5.1 determineRootDir determineRootDir(String location) 方法主要是用于确定根路径。代码如下 /*** Determine the root directory for the given location.* pUsed for determining the starting point for file matching,* resolving the root directory location to a {code java.io.File}* and passing it into {code retrieveMatchingFiles}, with the* remainder of the location as pattern.* pWill return /WEB-INF/ for the pattern /WEB-INF/*.xml,* for example.* param location the location to check* return the part of the location that denotes the root directory* see #retrieveMatchingFiles*/ protected String determineRootDir(String location) {// 找到冒号的后一位int prefixEnd location.indexOf(:) 1;// 根目录结束位置int rootDirEnd location.length();// 在从冒号开始到最后的字符串中循环判断是否包含通配符如果包含则截断最后一个由”/”分割的部分。// 例如在我们路径中就是最后的ap?-context.xml这一段。再循环判断剩下的部分直到剩下的路径中都不包含通配符。while (rootDirEnd prefixEnd getPathMatcher().isPattern(location.substring(prefixEnd, rootDirEnd))) {rootDirEnd location.lastIndexOf(/, rootDirEnd - 2) 1;}// 如果查找完成后rootDirEnd 0 了则将之前赋值的 prefixEnd 的值赋给 rootDirEnd 也就是冒号的后一位if (rootDirEnd 0) {rootDirEnd prefixEnd;}// 截取根目录return location.substring(0, rootDirEnd); }方法比较绕效果如下示例 原路径确定根路径classpath*:test/cc*/spring-*.xmlclasspath*:test/classpath*:test/aa/spring-*.xmlclasspath*:test/aa/ 2.5.5.2 doFindPathMatchingXXXResources #doFindPathMatchingXXXResources(...) 方法是个泛指一共对应三个方法 #doFindPathMatchingJarResources(rootDirResource, rootDirUrl, subPatter) 方法#doFindPathMatchingFileResources(rootDirResource, subPattern) 方法VfsResourceMatchingDelegate#findMatchingResources(rootDirUrl, subPattern, pathMatcher) 方法 因为本文重在分析 Spring 统一资源加载策略的整体流程。相对来说上面几个方法的代码量会比较多。所以本文不再追溯 总结 至此 Spring 整个资源记载过程已经分析完毕。下面简要总结下 Spring 提供了 Resource 和 ResourceLoader 来统一抽象整个资源及其定位。使得资源与资源的定位有了一个更加清晰的界限并且提供了合适的 Default 类使得自定义实现更加方便和清晰。AbstractResource 为 Resource 的默认抽象实现它对 Resource 接口做了一个统一的实现子类继承该类后只需要覆盖相应的方法即可同时对于自定义的 Resource 我们也是继承该类。DefaultResourceLoader 同样也是 ResourceLoader 的默认实现在自定 ResourceLoader 的时候我们除了可以继承该类外还可以实现 ProtocolResolver 接口来实现自定资源加载协议。DefaultResourceLoader 每次只能返回单一的资源所以 Spring 针对这个提供了另外一个接口 ResourcePatternResolver 该接口提供了根据指定的 locationPattern 返回多个资源的策略。其子类 PathMatchingResourcePatternResolver 是一个集大成者的 ResourceLoader 因为它即实现了 Resource getResource(String location) 方法也实现了 Resource[] getResources(String locationPattern) 方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/89204.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站付费推广渠道做商城网站产品怎么分布

作为一名热衷于分布式系统的开发者,你或许对Tomcat8已经不陌生了。然而,单个Tomcat实例的性能和可用性总有瓶颈,要实现高可用性和更强的性能,就需要搭建一个Tomcat集群。在这篇文章中,我将带你一步步搭建一个基于Tomca…

网站开发源码虚拟主机可以做视频视频网站吗

transition: right 1s; //重点直接改变right值 操作过快 这里用该方法实现1s内淡入淡出 达到效果目标

东莞整合网站建设公司版式设计素材网站

目录 1、实验目的 2、实验预习与准备 3、实验内容及步骤 本博客为数据库课布置的实验二的作业。 1、实验目的 (1) 掌握Select子句的功能和检索数据的方法 (2) 掌握对查询结果排序的方法 2、实验预习与准备 &#xf…

聊城网站开发thinkphp做的网站源码

本篇文章主要是对a、img和table标签用法介绍:a标签:可称为锚元素,主要功能是创建通向其他网页、文件、同一页面的其他位置、电子邮件地址或其他任何url地址的超链接;1.img标签:发出get请求并显示返回的图片1.常用属性&…

高端网站建设北京企业品牌营销推广

前言 看视频有UP主提到“AC5”“AC6”这样的词,一开始有些不理解,原来他说的是ARMCC版本。 keil自带的是ARMCC5,由于ARMCC5已经停止维护了,很多开发者会选择ARMCC6。 在维护公司“成年往事”项目可能就会遇到新KEIL旧版本编译器…

交通运输企业标准建设网站广州新闻报道

华为乾坤区县教育安全云服务解决方案(1) 课程地址方案背景客户痛点分析区县教育网概述区县教育网业务概述区县教育网业务安全风险分析区县教育网安全运维现状分析区县教育网安全建设痛点分析 安全解决方案功能概述架构概述方案架构设备选型 课程地址 本…

《网站设计与建设》电子书做一个手机网站多少钱

原生小程序开发如何使用 tailwindcss 原生小程序开发如何使用 tailwindcss 前言什么是 weapp-tailwindcss ?0. 准备环境以及小程序项目1. 安装与配置 tailwindcss 0. 使用包管理器安装 tailwindcss1. 在项目目录下创建 postcss.config.js 并注册 tailwindcss2. 配置 tailwind…

兰亭集势网站模板手游充值代理平台

目录 前言 一、背景 传统序列模型的问题 Transformer的动机 二、组成部分 自注意力机制(Self-Attention) 编码器和解码器 位置编码 前馈神经网络 三、训练和推理 训练过程 推理过程 四、应用 自然语言处理任务 图像处理和其他领域 BERT和…

和17做网店一样的货源网站北京网站建设站建设

文章目录一、时间序列综述二、时间序列数据以及基本概念三、时间序列分解四、指数平滑模型五、一元时间序列分析的模型六、AR(p)模型七、MA(q)模型八、ARMA(p, q)模型九、模型选择:AIC 和 BIC 准…

域名和网站的建设实训报告小程序开发公司价格表

unity不同版本的升级URP的方式不一样,但是大体流程是相似的 首先是加载URP包 Windows -> package manager,在unity registry中找到Universal RP 2023版本: 更早的版本: 创建URP资源和渲染器​​ 有些版本在加载时会自动创建&#…

网站背景色代码上海网络营销网站建设

第一章 C语言概述 1.1 C语言的发展史 1.1.1程序语言简述 1、机器语言 低级语言,又称二进制代码语言。一种使用0、1表示的二进制代码编写指令以执行计算机操作的语言。 特点:计算机可以直接识别,不需要进行任何翻译。 2、汇编语言 为了减…

做淘宝需要知道什么网站短网址压缩

《软件工程》期末复习提纲 第一章 第二章 第三章 第四章 第五章 第六章 第七章 第八章 第九章 第十章 第十一章 第十二章 第十三章 第十四章 小题参考 大题参考 《软件工程》期末复习提纲 第一章 1.在下列选项中,( )不是软…

企业网站策划建设方案静态网站html模板下载

11.1Spring基础(核心概念,创建和使用,简单读取) 11.2SpringBoot 11.3SpringMVC 11.4MyBatis(基础) 11.5MyBatis(进阶) 11.6AOP 11.7统一功能处理 11.8事务 11.9密码加密,加盐算法(手动实现) 11.10Redis基础​​​​​​​

贵州建设厅考试网站安全员网站举报

1. 简介 目前响应式编程的学习中很多时候都用到了Lambda表达式和StreamAPI,那么今天就在这里记录一下一些最基本的使用方法。 StreamAPI中引入了流的概念,其将集合看作一种流,流在管道中传输(动态的),可以…

网页网站怎么做的seo整站优化公司持续监控

计算机视觉(Computer Vision)是一门研究如何让计算机能够理解和分析数字图像或视频的学科。简单来说,计算机视觉的目标是让计算机能够像人类一样对视觉信息进行处理和理解。为实现这个目标,计算机视觉结合了图像处理、机器学习、模…

怎么测网站流量吗贵阳建设厅网站

目录 ​编辑一、HTTP 协议是什么 二、抓包工具的使用 三、HTTP 请求 1、认识 URL 2、认识方法 3、认识请求 “报头” HOST : Content-Length 和 Content-Type​编辑 User-Agent Referer Cookie 四、HTTP 响应 1、认识状态码 2、通过 form 表单构造 H…

建设网站需要些什么手续实体电商app定制开发

1 matlab 2ask close all clear all clcL =1000;Rb=2822400;%码元速率 Fs =Rb*8; Fc=Rb*30;%载波频率 Ld =L*Fs/Rb;%产生载波信号 t =0:1/Fs:L/Rb;carrier&

企业网站的常见类型有学网站建设工作室

我们平时经常会有一些数据运算的操作,需要调用sqrt,exp,abs等函数,那么时候你有没有想过:这个些函数系统是如何实现的?就拿最常用的sqrt函数来说吧,系统怎么来实现这个经常调用的函数呢&#xf…

阜宁做网站工作室网站设计说明

电子电器架构车载软件 —— 集中化架构软件开发 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任…

做网站卖水果哪里进货建立拼音

本文地址:https://blog.csdn.net/t163361/article/details/135024136 针对工作中遇到的优化问题,记录一下,给大家优化自己的项目提供一些思路。 公司产品最近正给国内某大型赛事做支撑服务暴露出不少问题。 使用环境 Unity 2021.3.0f1 cpu…