当前位置: 首页 > news >正文

在线做logo的网站wordpress ajax 评论

在线做logo的网站,wordpress ajax 评论,北京网站开发企业,安庆什么网站做火欢迎大家入坑,所谓师傅领进坑爬出去靠个人,首先我要说的是这个是上一篇《单刀直入ComponentScan》的姊妹篇哈,接着把没聊透的事说明白,咱不是虎头蛇尾的人。 资源加载是啥意思 scan ,都认识吧,小学词汇连…

欢迎大家入坑,所谓师傅领进坑爬出去靠个人,首先我要说的是这个是上一篇《单刀直入@ComponentScan》的姊妹篇哈,接着把没聊透的事说明白,咱不是虎头蛇尾的人。

资源加载是啥意思

scan ,都认识吧,小学词汇连我都认识,扫到的是啥,扫到的是资源啊,如何让资源为我所用,就需要把资源搞进来,这就是资源加载。

spring如何加载资源的

首先不得不承认spring本身是很专一的,她把所有的资源都用一个统一的接口来表示,Resource,我们不妨看看她的真容。


```java
/*** Interface for a resource descriptor that abstracts from the actual* type of underlying resource, such as a file or class path resource.** <p>An InputStream can be opened for every resource if it exists in* physical form, but a URL or File handle can just be returned for* certain resources. The actual behavior is implementation-specific.** @author Juergen Hoeller* @since 28.12.2003* @see #getInputStream()* @see #getURL()* @see #getURI()* @see #getFile()* @see WritableResource* @see ContextResource* @see UrlResource* @see FileUrlResource* @see FileSystemResource* @see ClassPathResource* @see ByteArrayResource* @see InputStreamResource*/
public interface Resource extends InputStreamSource {/*** Determine whether this resource actually exists in physical form.* <p>This method performs a definitive existence check, whereas the* existence of a {@code Resource} handle only guarantees a valid* descriptor handle.*/boolean exists();/*** Indicate whether non-empty contents of this resource can be read via* {@link #getInputStream()}.* <p>Will be {@code true} for typical resource descriptors that exist* since it strictly implies {@link #exists()} semantics as of 5.1.* Note that actual content reading may still fail when attempted.* However, a value of {@code false} is a definitive indication* that the resource content cannot be read.* @see #getInputStream()* @see #exists()*/default boolean isReadable() {return exists();}/*** Indicate whether this resource represents a handle with an open stream.* If {@code true}, the InputStream cannot be read multiple times,* and must be read and closed to avoid resource leaks.* <p>Will be {@code false} for typical resource descriptors.*/default boolean isOpen() {return false;}/*** Determine whether this resource represents a file in a file system.* A value of {@code true} strongly suggests (but does not guarantee)* that a {@link #getFile()} call will succeed.* <p>This is conservatively {@code false} by default.* @since 5.0* @see #getFile()*/default boolean isFile() {return false;}/*** Return a URL handle for this resource.* @throws IOException if the resource cannot be resolved as URL,* i.e. if the resource is not available as descriptor*/URL getURL() throws IOException;/*** Return a URI handle for this resource.* @throws IOException if the resource cannot be resolved as URI,* i.e. if the resource is not available as descriptor* @since 2.5*/URI getURI() throws IOException;/*** Return a File handle for this resource.* @throws java.io.FileNotFoundException if the resource cannot be resolved as* absolute file path, i.e. if the resource is not available in a file system* @throws IOException in case of general resolution/reading failures* @see #getInputStream()*/File getFile() throws IOException;/*** Return a {@link ReadableByteChannel}.* <p>It is expected that each call creates a <i>fresh</i> channel.* <p>The default implementation returns {@link Channels#newChannel(InputStream)}* with the result of {@link #getInputStream()}.* @return the byte channel for the underlying resource (must not be {@code null})* @throws java.io.FileNotFoundException if the underlying resource doesn't exist* @throws IOException if the content channel could not be opened* @since 5.0* @see #getInputStream()*/default ReadableByteChannel readableChannel() throws IOException {return Channels.newChannel(getInputStream());}/*** Determine the content length for this resource.* @throws IOException if the resource cannot be resolved* (in the file system or as some other known physical resource type)*/long contentLength() throws IOException;/*** Determine the last-modified timestamp for this resource.* @throws IOException if the resource cannot be resolved* (in the file system or as some other known physical resource type)*/long lastModified() throws IOException;/*** Create a resource relative to this resource.* @param relativePath the relative path (relative to this resource)* @return the resource handle for the relative resource* @throws IOException if the relative resource cannot be determined*/Resource createRelative(String relativePath) throws IOException;/*** Determine a filename for this resource, i.e. typically the last* part of the path: for example, "myfile.txt".* <p>Returns {@code null} if this type of resource does not* have a filename.*/@NullableString getFilename();/*** Return a description for this resource,* to be used for error output when working with the resource.* <p>Implementations are also encouraged to return this value* from their {@code toString} method.* @see Object#toString()*/String getDescription();}

请原谅我用代码占用了很大的篇幅,主要是为了让大家通过看文章不用去翻代码,能够连贯的读下来,同时没有把注释去掉的原因是,任何只看代码不看注释的行为都是耍流氓,多说一句,我觉得想要成为快乐的程序员,应该具备勇气和丰富的想象力。以上内容就需要你的想象力了,我啥都不说了。要用心,别走马观花,看热闹,觉得挺热闹然后给个赞,对自己啥收获也没有,那就是浪费时间,这是一个浪费了10余年老程序员的忠告,虽然现在他依然在浪费着时间,写到这里感觉自己有点飘了呢,开始好为人师了。
接下来着重说一下,Resource的神兵利器,ResourceLoader ,她算一个重头戏,资源加载器,拿来加载资源,为什么要有这么个东东呢,要根据她在spring中唯一的实现 DefaultResourceLoader 说起。

public class DefaultResourceLoader implements ResourceLoader {@Nullableprivate ClassLoader classLoader;private final Set<ProtocolResolver> protocolResolvers = new LinkedHashSet<>(4);private final Map<Class<?>, Map<Resource, ?>> resourceCaches = new ConcurrentHashMap<>(4);~~~~~~~~~~~~~~/*** Register the given resolver with this resource loader, allowing for* additional protocols to be handled.* <p>Any such resolver will be invoked ahead of this loader's standard* resolution rules. It may therefore also override any default rules.* @since 4.3* @see #getProtocolResolvers()*/public void addProtocolResolver(ProtocolResolver resolver) {Assert.notNull(resolver, "ProtocolResolver must not be null");this.protocolResolvers.add(resolver);}@Overridepublic Resource getResource(String location) {Assert.notNull(location, "Location must not be null");for (ProtocolResolver protocolResolver : getProtocolResolvers()) {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 (ResourceUtils.isFileURL(url) ? new FileUrlResource(url) : new UrlResource(url));}catch (MalformedURLException ex) {// No URL -> resolve as resource path.return getResourceByPath(location);}}}

不好意思,上面的类代码是不完整的,我删除了一些简单的构造函数,还有一些我没看懂的复杂函数,捡我认为重要的说,Resource getResource(String location),这核心的方法,也揭秘了ResourceLoader 存在的价值,首先我们知道我们在加载自愿的时候资源的形态是多样的,这个通过上面的注释也能看出来,有 UrlResource FileUrlResource FileSystemResource ClassPathResource,ResourceLoader 的作用就是可以让多样的资源来源加载用统一的方法来加载,主要是根据资源加载路径的组成方式,比如d:\abc.txt,www.baidu.com/abc.txt,classpath:abc.class, getResouce方法其实使用简单工厂模式的方式。public void addProtocolResolver(ProtocolResolver resolver) 这个方法其实是留给我们使用者去进行扩展的,当你的资源加载方式比较复杂,比如你的资源路径是通过读取另一些资源来拼装的,那么你可以自定义ProtocolResolver 来处理,因为getRource方法的第一句就是

	for (ProtocolResolver protocolResolver : getProtocolResolvers()) {Resource resource = protocolResolver.resolve(location, this);if (resource != null) {return resource;}}

如何去注册自己的ProtocolResolver 呢,applicationContext.addProtocolResolver();奥秘就是因为public abstract class AbstractApplicationContext extends DefaultResourceLoader。
如果你耐心的读到这里,我必须上点干货了,报答你的不走之恩。
ComponentScan 是如何应用这个ResourceLoader 的呢,ConfigurationClassPostProcessor 这个重头类就必须要说一下了,她是干嘛地…! 不得不说她是一个牛逼的类,干的事特别的多。

  1. 解析 @Configuration。
  2. 解析 @Bean 方法。
  3. 解析 @ComponentScan。
  4. 解析 @Import 注解。
  5. 解析 @ImportResource 注解。
  6. 解析 @PropertySource 注解。

可以这样说,所有bean的加载都是他来干,她实现了BeanDefinitionRegistryPostProcessor,懂得都懂,然后有一个关键台词,类里有一个成员变量,private ResourceLoader resourceLoader = new DefaultResourceLoader(); 然后把这个成员变量向下传递,一直到上文说到的private Set scanCandidateComponents(String basePackage)方法中哈,找到潜在的组件,什么组件无非就是上文说的加了@Component @Service @Controller等注解的类呗。

	private Set<BeanDefinition> scanCandidateComponents(String basePackage) {Set<BeanDefinition> candidates = new LinkedHashSet<>();try {String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +resolveBasePackage(basePackage) + '/' + this.resourcePattern;**Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);**boolean traceEnabled = logger.isTraceEnabled();boolean debugEnabled = logger.isDebugEnabled();for (Resource resource : resources) {if (traceEnabled) {logger.trace("Scanning " + resource);}if (resource.isReadable()) {try {MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);if (isCandidateComponent(metadataReader)) {ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);sbd.setResource(resource);sbd.setSource(resource);if (isCandidateComponent(sbd)) {if (debugEnabled) {logger.debug("Identified candidate component class: " + resource);}candidates.add(sbd);}else {if (debugEnabled) {logger.debug("Ignored because not a concrete top-level class: " + resource);}}}else {if (traceEnabled) {logger.trace("Ignored because not matching any filter: " + resource);}}}catch (Throwable ex) {throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, ex);}}else {if (traceEnabled) {logger.trace("Ignored because not readable: " + resource);}}}}catch (IOException ex) {throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);}return candidates;
}

两句关键台词
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + ‘/’ + this.resourcePattern;
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);

细心的读者会发现我们一直说的ResourceLoader 接口里面就没有getResources方法,这里面就提到一个衍生的接口,ResourcePatternResolver。

public interface ResourcePatternResolver extends ResourceLoader {/*** Pseudo URL prefix for all matching resources from the class path: "classpath*:"* This differs from ResourceLoader's classpath URL prefix in that it* retrieves all matching resources for a given name (e.g. "/beans.xml"),* for example in the root of all deployed JAR files.* @see org.springframework.core.io.ResourceLoader#CLASSPATH_URL_PREFIX*/String CLASSPATH_ALL_URL_PREFIX = "classpath*:";/*** Resolve the given location pattern into Resource objects.* <p>Overlapping resource entries that point to the same physical* resource should be avoided, as far as possible. The result should* have set semantics.* @param locationPattern the location pattern to resolve* @return the corresponding Resource objects* @throws IOException in case of I/O errors*/Resource[] getResources(String locationPattern) throws IOException;
}

getResourcePatternResolver 获取到的是PathMatchingResourcePatternResolver处理器,然后通过循环调用defaultResourceLoader的getResource方法来加载资源。今天先说这么多吧,对于加载还有不少内容,不放在一起了,以防都看蒙圈了。下一篇会着重讲下这里面的内容。

http://www.yayakq.cn/news/938136/

相关文章:

  • 微信群投票网站怎么做的北京住房和城乡建设部网站
  • 合肥网站设计哪家公司好快速网站建设费用
  • 网站建设模拟实验报告商店网站制作
  • 做网站找人深圳品牌策划营销
  • php做网站的支付功能挣钱做任务的网站
  • 校园云网站建设想做游戏推广怎么找游戏公司
  • 厦门唯一官方网站app001推广平台官网
  • 做便民网站都需要哪些模块哈尔滨优化建站哪家专业
  • 农村电商网站建设ppt进入微信官方网站注册
  • 沈阳建设网站哪家好湖北省电力建设三公司网站
  • vc域名建站的网站semiconductor是什么意思
  • 河北省建设厅官方网站三大oa办公软件
  • 公司网站制作要多少钱软件服务开发
  • 做网站的工具北京免费网站制作
  • 临沂免费做网站织梦做视频网站可以吗
  • 做招聘的h5用哪个网站做网站要会写什么
  • 网站建设费用写创意企业网站 php
  • 北京塞车网站建设为什么打开网站是建设中
  • 网站网络推广优化哪家好外贸网站如何做推广苏州
  • 个人做商业网站需要什么iis8出现在网站首页
  • php装饰公司网站源码换了家公司做网站如何接入备案
  • 阜新公司做网站移动端网站模板怎么做的
  • 珠海电商网站建设怎么做百度网站验证码
  • 网络app开发网站建设价格cad做兼职区哪个网站
  • 高清做 视频在线观看网站一个空间放2个网站
  • 建手机网站怎么收费保定市住房保障和城乡建设局网站
  • 网站建设培训基地手机制作海报app
  • 长沙人才招聘网站站长工具推荐网站
  • 上海住房建设部官方网站拍摄微电影公司
  • 新闻事件温州seo博客