【java 基础】闲话 ClassLoader 和 资源读取

文章目录

  • ClassLoader再探
    • tomcat的类加载器
    • spring 的类加载器
    • springboot 的类加载器
  • 正确获取ClassLoader
    • 获取当前线程的ContextClassLoader
    • 加载当前类的ClassLoader
    • 不常用的获取 ClassLoader的方法
  • 使用ClassLoader的读取资源
    • ClassLoader 有几个常用的资源加载方法
    • Class 的资源加载方法

接上一篇:【java 基础】闲话 ClassLoader 和 SPI

ClassLoader再探

由上一篇我们知道,不同的 ClassLoader加载的资源范围不同。除了最常见的 java 自己实现的三个类加载器以外,其实还有很多别的加载器。比如spring、 springboot、以及早些年常用的 tomcat,都有自己的加载器。

tomcat的类加载器

tomcat为什么要自定义类加载器,主要有以下几个原因:

  • 作为 web 容器,可以同时运行多个应用。而不同的应用可能使用相同的jar包,但可能版本不同,为了防止出现类冲突,所以必须要对不同的应用进行隔离,方法便是不同的应用使用不同的WebAppClassLoader 实例。
  • 在war包中,类的存储结构是放在/WEB-INF/classes 和/WEB-INF/lib 中,所以类的扫描路径也会不同,需要自定义扫描。
  • 对于常用的包,比如 log4j 之类,如果在每个 classLoader 中都加载一次,是对资源的浪费,所以 tomcat 还存在一个共享的 ShareClassLoader作为WebAppClassLoader 的父加载器。

spring 的类加载器

spring也有自己的加载器:OverridingClassLoader,与双亲委派不同,OverridingClassLoader是自己先尝试加载,在无法加载到的情况下才会启用其父加载器(双亲委派)。即 spring 优先使用自己定义的类。

springboot 的类加载器

我们知道springboot FAT jar 的方式将依赖包都打包到了 BOOT-INF/lib 下,这就导致 java 普通的类加载器无法加载到jar 包中的 jar 包,所以 springboot实现了LaunchedURLClassLoader类加载器来实现自定义加载。

正确获取ClassLoader

通过以上描述我们大概说明了一下类加载器的一些自定义应用。而我们实际使用中,我们怎么获取正确的 ClassLoader呢?
常用的有两种方式获取 ClassLoader

  • Thread.currentThread().getContextClassLoader();
  • this.getClass().getClassLoader();

获取当前线程的ContextClassLoader

首先说明一下Thread.currentThread().getContextClassLoader():
在初始化 Thread 时可以指定我们要使用的 ClassLoader,默认情况下是内置的AppClassLoader(在 jvm 启动时指定),而比如 tomcat 等在会在每个应用启动时,初始化自己的 ClassLoader,并且在子线程初始化时会继承父线程的 ClassLoader(Thread 的默认行为)。

加载当前类的ClassLoader

而 this.getClass().getClassLoader()则是获取加载此类的 ClassLoader。每个类对象都会保存加载它自身的 classLoader。还有一个ClassName.class.getClassLoader(); 区别于this.getClass().getClassLoader(),用于静态方法中。

不常用的获取 ClassLoader的方法

ClassLoader.getSystemClassLoader(); //直接获取内置的AppClassLoader
ClassLoader.getPlatformClassLoader(); //直接获取内置的ExtClassLoader

使用ClassLoader的读取资源

通过以上的内容,我们说明了 ClassLoader 的扫描范围,以及如何正确的获取自己想要的 ClassLoader,搞明白了这些内容后,就可以开始应用 ClassLoader 进行资源读取了。

ClassLoader 有几个常用的资源加载方法

  • public URL getResource(String name);
    可以获取到相对于classpath根路径下的资源定位信息,通过 openStream 方法可以开启流读取。如果匹配到多个值,则返回第一个。
  • public Enumeration getResources(String name);
    同getResource,只是会返回所有匹配到的资源。
  • public InputStream getResourceAsStream(String name);
    同getResource,只是会返回直接返回流。
  • public URL getSystemResource(String name);
    不常用,直接获取 AppClassLoader,然后调用getResource(name)方法。范围更小
  • public InputStream getSystemResourceAsStream(String name);
    同getSystemResource方法,只是直接返回流。

注意⚠️:name 不能以/开头。

Class 的资源加载方法

  • public URL getResource(String name);
    如果 name 以/开头,则行为同 ClassLoader 的 getResource(name)方法。如果不以/开头,则路径是相对于当前类所在目录。
  • public InputStream getResourceAsStream(String name);
    同Class.getResource方法,只是直接返回流。

ok,结束收工!

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

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

相关文章

【操作系统概念】 第7章:死锁

文章目录 0.前言7.1 系统模型7.2 死锁特征7.2.1 必要条件7.2.2 资源分配图 7.3 死锁处理方法7.4 死锁预防(deadlock prevention)7.4.1 互斥7.4.2 占有并等待7.4.3 非抢占7.4.4 循环等待 7.5 死锁避免(deadlock-avoidance)7.5.1 安…

b站小土堆pytorch学习记录—— P25-P26 网络模型的使用和修改、保存和读取

文章目录 一、修改1.方法2.代码 二、保存和读取1.方法2.代码(1)保存(2)加载 3.陷阱 一、修改 1.方法 add_module(name: str, module: Module) -> None name 是要添加的子模块的名称。 module 是要添加的子模块。 调用 add_m…

练习 6 Web [极客大挑战 2019]HardSQL

[极客大挑战 2019]HardSQL 先尝试登录,查看报错信息 admin 111 password 1111 登录失败admin 111 password 1’or’1 登录成功 这里直接试了万能密码成功,复习一下,第一个 ’ 是为了闭合前面的sql语句,最后的1后面没有 ’ 是因为…

如何学习I2C协议

文章目录 学习I2C协议0 懒人直达1 了解协议开发者2 从恩智浦半导体公司下载官方技术文档3 翻译成中文4 资源下载 学习I2C协议 0 懒人直达 点击直达 1 了解协议开发者 I2C(Inter-Integrated Circuit)协议是由荷兰皇家飞利浦电子公司(现恩智…

008-跨域

跨域 什么是跨域?非同源限制跨域解决方案CORSJSONP服务器进行第三方代理webscoketwindow.postMessage 什么是跨域? 同源策略:协议相同、域名相同、端口号相同 的两个页面被认为是同源。 由一个页面的 js 访问不同源的页面内容,被…

Window11 Ubuntu双系统安装

一、制作启动盘 ubuntu下载:https://cn.ubuntu.com/download 启动盘工具:https://cdimage.deepin.com/applications/deepin-boot-maker/windows/deepin-boot-maker.exehttps://cdimage.deepin.com/applications/deepin-boot-maker/windows/deepin-boot…

HTTP代理ip如何助旅游大数据领域?怎么去建立安全代理隧道连接?

HTTP代理IP在旅游大数据领域的应用主要体现在以下几个方面: 数据抓取:旅游大数据的获取往往需要从各种在线旅游平台、社交媒体、评论网站等抓取数据。使用HTTP代理IP可以在抓取过程中隐藏真实IP,避免被目标网站封锁,从而持续、稳定…

LeetCode 刷题 [C++] 第300题.最长递增子序列

题目描述 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。 题目…

代码随想录算法训练营第25天|● 216.组合总和|||● 17.电话号码的字母组合

216.组合总和||| 思路:这题和77题的组合思路差不多一样,只是多了一步判断加起来的和是否和目标值相等,并且回溯需要把相应的值减去。 代码: vector<vector<int>> result;vector<int> path;void backtracking(int k,int targetSum,int sum,int startIndex)…

CTP-API开发系列之五:SimNow环境介绍

CTP-API开发系列之五&#xff1a;SimNow环境介绍 CTP-API开发系列之五&#xff1a;SimNow环境介绍SimNow模拟测试环境第一套第二套登录关键字段可视化终端常见问题 CTP-API开发系列之五&#xff1a;SimNow环境介绍 如果你要研发一套国内期货程序化交易系统&#xff0c;从模拟测…

设计模式在芯片验证中的应用——备忘录

1. 前言 软件设计模式定义了一组类和它们之间的关系&#xff0c;它们相互作用用以解决软件开发过程中面临的常见问题。由于验证工程师所做工作的重要部分包括使用面向对象语言(如SystemVerilog)进行编码&#xff0c;因此许多遇到的挑战都适合应用特定的设计模式来解决。将它们…

SCCM部署时遇到的问题:无法连接到SQL Server

根据提示信息逐一排除以下问题&#xff1a; 1、确保SQL服务器名称是否正确。 2、确保TCP1433和4022端口有没有被防火墙屏蔽。 3、站点服务器帐号加入SQLServer的sysadmin角色成员里 、确保SQL实例没有使用动态端口&#xff0c;可参考&#xff1a; Configure SQL Server to…

贪心 Leetcode 763 划分字母区间

划分字母区间 Leetcode 763 学习记录自代码随想录 给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段&#xff0c;同一字母最多出现在一个片段中。 注意&#xff0c;划分结果需要满足&#xff1a;将所有划分结果按顺序连接&#xff0c;得到的字符串仍然是 s 。 返…

题目 1572: 蓝桥杯-进制转换

题目描述: 程序提示用户输入三个字符&#xff0c;每个字符取值范围是0-9&#xff0c;A-F。然后程序会把这三个字符转化为相应的十六进制整数&#xff0c;并分别以十六进制&#xff0c;十进制&#xff0c;八进制输出。 代码: package lanqiao;import java.util.*;public clas…

重新启动vue-shop-maseter主支任务

以下是命令行&#xff0c;cmd任务管理程序进程中… 这部分是部分源码&#xff0c;用H5编辑器写的 等待慢慢启动重启中。。。。 然而没有反应&#xff0c;不知道为什么&#xff1f; 花里胡哨的&#xff0c;更加没看懂了。 我这暴脾气&#xff0c;气得我直接一顿乱敲 要怎…

C语言基础练习——Day01

目录 选择题 编程题 打印从1到最大的n位数 计算日期到天数转换 选择题 1、执行下面程序&#xff0c;正确的输出是 int x5,y7; void swap(int x, int y) {int z;zx;xy;yz; } int main() { int x3,y8; swap(int x, int y);printf("%d,%d\n"&#xff0c;x, y);return …

vue3怎么设置路由 Vue Route

1. 安装Vue Router npm install vue-router 2. 创建Home.vue组件 在 src/views 目录下创建一个名为 Home.vue 的文件&#xff1a; <!-- <template> 标签是Vue组件的模板部分&#xff0c;其中包含了组件的HTML结构。 --> <template><div><h1>…

2024年最新阿里云服务器地域选择方法,以及可用区说明

阿里云服务器地域和可用区怎么选择&#xff1f;地域是指云服务器所在物理数据中心的位置&#xff0c;地域选择就近选择&#xff0c;访客距离地域所在城市越近网络延迟越低&#xff0c;速度就越快&#xff1b;可用区是指同一个地域下&#xff0c;网络和电力相互独立的区域&#…

iostat命令详解

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 iostat是一个使用频率较高的命令&#xff0c;主要用来统计和输出CPU和磁盘IO信息。它的安装很简单&#xff1a; # yum -y insta…

【PyQt】16-剪切板的使用

文章目录 前言一、代码疑惑快捷键 二、现象2.1 复制粘贴文本复制粘贴 2.2 复制粘贴图片复制粘贴 2.3 复制粘贴网页 总结 前言 1、剪切板的使用 2、pycharm的编译快捷键 3、类的属性和普通变量的关系 4、pyqt应该养成的编程习惯-体现在代码里了&#xff0c;自己看看。 一、代码…