Spring 5 DefaultResourceLoader 源码注释

tech2022-10-12  106

相关源码注释

ApplicationContext

Spring 5 DefaultResourceLoader 源码注释 Spring 5 AbstractApplicationContext 源码注释

BeanFactory

Spring 5 SimpleAliasRegistry 源码注释 Spring 5 DefaultSingletonBeanRegistry 源码注释 Spring 5 FactoryBeanRegistrySupport 源码注释 Spring 5 AbstractBeanFactory 源码注释 Spring 5 AbstractAutowireCapableBeanFactory 源码注释 Spring 5 DefaultLisbaleBeanFactory 源码注释

UML类图

源码

/** * Default implementation of the {@link ResourceLoader} interface. * Used by {@link ResourceEditor}, and serves as base class for * {@link org.springframework.context.support.AbstractApplicationContext}. * Can also be used standalone. * <p> * {@link ResourceLoader}接口的默认实现。 * 由{@link ResourceEditor}使用,并看作{@link org.springframework.context.support.AbstractApplicationContext}. * 的基类。也可以独立使用。 * </p> * <p>Will return a {@link UrlResource} if the location value is a URL, * and a {@link ClassPathResource} if it is a non-URL path or a * "classpath:" pseudo-URL. * <p> * 如位置值是一个URL,会返回一个 {@link UrlResource}对象, * 如果是非URL路径或者是一个'classpatch:'伪路径,会返回一个 {@link ClassPathResource} * 对象 * </p> * * @author Juergen Hoeller * @since 10.03.2004 * @see FileSystemResourceLoader * @see org.springframework.context.support.ClassPathXmlApplicationContext */ public class DefaultResourceLoader implements ResourceLoader { /** * 类加载器 */ @Nullable private ClassLoader classLoader; /** * 协议解析器组 */ private final Set<ProtocolResolver> protocolResolvers = new LinkedHashSet<>(4); /** * 资源映射缓存 */ private final Map<Class<?>, Map<Resource, ?>> resourceCaches = new ConcurrentHashMap<>(4); /** * Create a new DefaultResourceLoader. * <p>创建一个新的DefaultResourceLoader</p> * <p>ClassLoader access will happen using the thread context class loader * at the time of this ResourceLoader's initialization. * <p> * 在这个ResourceLoader初始化期间,将使用线程上下文加载器进行Classload进行访问 * </p> * @see java.lang.Thread#getContextClassLoader() */ public DefaultResourceLoader() { // 获取默认类加载器,一般返回线程上下文类加载器,没有就返回加载ClassUtils的类加载器, // 还是没有就返回系统类加载器,最后还是没有就返回null this.classLoader = ClassUtils.getDefaultClassLoader(); } /** * Create a new DefaultResourceLoader. * <p>创建一个新的DefaultResourceLoader</p> * @param classLoader the ClassLoader to load class path resources with, or {@code null} * for using the thread context class loader at the time of actual resource access * -- ClassLoader用来加载类路径资源,或用于实际资源访问时,使用线程上下文加载器 * 返回null */ public DefaultResourceLoader(@Nullable ClassLoader classLoader) { this.classLoader = classLoader; } /** * Specify the ClassLoader to load class path resources with, or {@code null} * for using the thread context class loader at the time of actual resource access. * <p> * 指定ClassLoader以加载类路径资源,或者用于实际资源访问时,使用线程上下文加载器 * 返回null * </p> * <p>The default is that ClassLoader access will happen using the thread context * class loader at the time of this ResourceLoader's initialization. * <p> * 默认情况下,在ResourceLoader初始化期间,将使用线程上下文类加载器进行ClassLoader * 访问 * </p> */ public void setClassLoader(@Nullable ClassLoader classLoader) { this.classLoader = classLoader; } /** * Return the ClassLoader to load class path resources with. * <p>返回指定ClassLoader以加载类路径资源</p> * <p>Will get passed to ClassPathResource's constructor for all * ClassPathResource objects created by this resource loader. * <p>将这个资源加载器创建的所有ClassPathResource对象传递给ClassPathResource的构造器 * </p> * @see ClassPathResource */ @Override @Nullable public ClassLoader getClassLoader() { //如果classLoader不为null就直接返回class,否则使用默认的类加载器 return (this.classLoader != null ? this.classLoader : ClassUtils.getDefaultClassLoader()); } /** * Register the given resolver with this resource loader, allowing for * additional protocols to be handled. * <p> * 向这个资源加载器注册给定的解析器,运行处理额外协议 * </p> * <p>Any such resolver will be invoked ahead of this loader's standard * resolution rules. It may therefore also override any default rules. * <p> * 任何此类解析器都将在这个加载器的标准解析规则之前调用。因此,它也可以覆盖任何 * 默认规则。 * </p> * @since 4.3 * @see #getProtocolResolvers() */ public void addProtocolResolver(ProtocolResolver resolver) { //如果resolver为null,抛出异常 Assert.notNull(resolver, "ProtocolResolver must not be null"); //将resolver添加到protocalResolvers中 this.protocolResolvers.add(resolver); } /** * Return the collection of currently registered protocol resolvers, * allowing for introspection as well as modification. * <p> * 返回当前已注册的协议解析器列表,允许自省和修改 * </p> * @since 4.3 */ public Collection<ProtocolResolver> getProtocolResolvers() { return this.protocolResolvers; } /** * Obtain a cache for the given value type, keyed by {@link Resource}. * 获取给定值类型的缓存,以{@link Resource}作为键名 * @param valueType the value type, e.g. an ASM {@code MetadataReader} * -- 值类型,例如ASM{@code MetaDataReader} * @return the cache {@link Map}, shared at the {@code ResourceLoader} level * -- 缓存{@link Map},在{@code ResourceLoader}级别共享 * @since 5.0 */ @SuppressWarnings("unchecked") public <T> Map<Resource, T> getResourceCache(Class<T> valueType) { //如果从resourceCache中获取valueType对应的值,如果不存在,就新建一个返回出去 //ConcurrentHashMap:可以将其当做HashMap使用,区别在于ConcurrentHashMap是线程安全的; // ConcurrentHashMap在对象中保存了一个Segment数组,即将整个Hash表划分为多个分段;而每个Segment元素,即每个分段则类似于一个Hashtable; // 这样,在执行put操作时首先根据hash算法定位到元素属于哪个Segment,然后对该Segment加锁即可。因此,ConcurrentHashMap在多线程并 // 发编程中可是实现多线程put操作 return (Map<Resource, T>) this.resourceCaches.computeIfAbsent(valueType, key -> new ConcurrentHashMap<>()); } /** * Clear all resource caches in this resource loader. * <p> * 清空在资源加载器中的所有资源缓存 * </p> * @since 5.0 * @see #getResourceCache */ public void clearResourceCaches() { //清空resourceCaches this.resourceCaches.clear(); } @Override public Resource getResource(String location) { //如果location为null,抛出异常 Assert.notNull(location, "Location must not be null"); //遍历所有协议解析器 for (ProtocolResolver protocolResolver : getProtocolResolvers()) { //如果protocolResolver的协议匹配,根据defaultResourceLoader解析location Resource resource = protocolResolver.resolve(location, this); //如果资源对象不为null if (resource != null) { //返回该资源对象 return resource; } } //如果localion是以'/'开头 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); } } } /** * Return a Resource handle for the resource at the given path. * <p>返回给定路径下资源的资源句柄</p> * <p>The default implementation supports class path locations. This should * be appropriate for standalone implementations but can be overridden, * e.g. for implementations targeted at a Servlet container. * <p>默认实现支持类路径位置。这个应该适用于独立的实现但可以被复写,例如针对Servlet容器的实现</p> * @param path the path to the resource 资源路径 * @return the corresponding Resource handle 对应的资源句柄 * @see ClassPathResource * @see org.springframework.context.support.FileSystemXmlApplicationContext#getResourceByPath * @see org.springframework.web.context.support.XmlWebApplicationContext#getResourceByPath */ protected Resource getResourceByPath(String path) { return new ClassPathContextResource(path, getClassLoader()); } /** * ClassPathResource that explicitly expresses a context-relative path * through implementing the ContextResource interface. * <p> * 通过实现ContextResource接口显示表示上下文相对路径的ClasPathResource * </p> */ protected static class ClassPathContextResource extends ClassPathResource implements ContextResource { /** * 使用ClassLoader为path创建一个新的ClassPathContextResource. * 前导斜杆将被删除, 因为ClassLoader资源访问方法不接受它。 * @param path 资源路径 * @param classLoader 类加载器 */ public ClassPathContextResource(String path, @Nullable ClassLoader classLoader) { super(path, classLoader); } @Override public String getPathWithinContext() { //返回此资源的路径(作为类路径中的资源路径) return getPath(); } @Override public Resource createRelative(String relativePath) { //将给定相对路径应用于给定Java资源路径,组装成完整路径 String pathToUse = StringUtils.applyRelativePath(getPath(), relativePath); // 使用ClassLoader为path创建一个新的ClassPathContextResource. // 前导斜杆将被删除, 因为ClassLoader资源访问方法不接受它。 return new ClassPathContextResource(pathToUse, getClassLoader()); } } }

ClassPathResource

Spring 5 Resource 源码注释

最新回复(0)