文章目录

  • 目标
    • 引入问题
  • 线程上下文类加载器
    • 服务提供者接口(SPI)
    • JDBC 源码分析
  • 代码实践
    • 工程一
      • SPI 服务接口
      • 基础调用类
      • 打包
    • 工程二
      • 导入base.jar包
      • SPI 服务实现
      • 测试代码
    • 测试
      • 测试1:
      • 测试2:

目标

  • 了解线程上下文类加载的作用和用法

    参考:深入理解Java虚拟机——JVM高级特性与最佳实践(第2版) 书籍

    mermaid

    你知道java反射机制中class.forName和classloader的区别吗?

    JAVA之SPI-服务发现机制

引入问题

如何破坏类加载器的双亲委派模型?(转换为更简单的问题:如何让父类加载器(Bootstrap ClassLoader)加载的类调用子类加载器(Application ClassLoader)加载的类)

注意:由于双亲委派模型,子类加载器加载的类可以引用父类加载器加载的类,父类加载器加载的类无法引用子类加载器加载的类

为了解决基础类调用回用户的代码,java引入了线程上下文类加载器(Thread Context ClassLoader)作为一种方式来实现。

线程上下文类加载器

线程上下文类加载器(Thread Context ClassLoader)

基本方法:

// 设置线程的上下文类加载器
Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
// 获取当前线程的上下文类加载器
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();

获取线程上下文类加载器的三种情况:

  • 全局范围内没有设置过上下文类加载器,默认类加载器就是应用类加载器(Application ClassLoader)
  • 创建线程但没有设置上下文类加载器,将从父线程继承一个类加载器
  • 设置了线程的上下文类加载器,就返回设置的类加载器

再引入一个SPI 的概念

服务提供者接口(SPI)

服务提供者接口(Service Provider Interface),Java 提供了很多服务提供者接口(Service Provider Interface,SPI),允许第三方为这些接口提供实现。常见的 SPI 有 JDBC、JCE、JNDI、JAXP 和 JBI 等。

这些服务一般使用这个线程的上下文类加载器去加载需要的SPI接口实现的代码,也就是让父类加载器委派子类加载器完成类加载。

#mermaid-svg-540LcNQu33cHiFdN .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-540LcNQu33cHiFdN .label text{fill:#333}#mermaid-svg-540LcNQu33cHiFdN .node rect,#mermaid-svg-540LcNQu33cHiFdN .node circle,#mermaid-svg-540LcNQu33cHiFdN .node ellipse,#mermaid-svg-540LcNQu33cHiFdN .node polygon,#mermaid-svg-540LcNQu33cHiFdN .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-540LcNQu33cHiFdN .node .label{text-align:center;fill:#333}#mermaid-svg-540LcNQu33cHiFdN .node.clickable{cursor:pointer}#mermaid-svg-540LcNQu33cHiFdN .arrowheadPath{fill:#333}#mermaid-svg-540LcNQu33cHiFdN .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-540LcNQu33cHiFdN .flowchart-link{stroke:#333;fill:none}#mermaid-svg-540LcNQu33cHiFdN .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-540LcNQu33cHiFdN .edgeLabel rect{opacity:0.9}#mermaid-svg-540LcNQu33cHiFdN .edgeLabel span{color:#333}#mermaid-svg-540LcNQu33cHiFdN .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-540LcNQu33cHiFdN .cluster text{fill:#333}#mermaid-svg-540LcNQu33cHiFdN div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-540LcNQu33cHiFdN .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-540LcNQu33cHiFdN text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-540LcNQu33cHiFdN .actor-line{stroke:grey}#mermaid-svg-540LcNQu33cHiFdN .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-540LcNQu33cHiFdN .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-540LcNQu33cHiFdN #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-540LcNQu33cHiFdN .sequenceNumber{fill:#fff}#mermaid-svg-540LcNQu33cHiFdN #sequencenumber{fill:#333}#mermaid-svg-540LcNQu33cHiFdN #crosshead path{fill:#333;stroke:#333}#mermaid-svg-540LcNQu33cHiFdN .messageText{fill:#333;stroke:#333}#mermaid-svg-540LcNQu33cHiFdN .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-540LcNQu33cHiFdN .labelText,#mermaid-svg-540LcNQu33cHiFdN .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-540LcNQu33cHiFdN .loopText,#mermaid-svg-540LcNQu33cHiFdN .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-540LcNQu33cHiFdN .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-540LcNQu33cHiFdN .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-540LcNQu33cHiFdN .noteText,#mermaid-svg-540LcNQu33cHiFdN .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-540LcNQu33cHiFdN .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-540LcNQu33cHiFdN .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-540LcNQu33cHiFdN .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-540LcNQu33cHiFdN .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-540LcNQu33cHiFdN .section{stroke:none;opacity:0.2}#mermaid-svg-540LcNQu33cHiFdN .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-540LcNQu33cHiFdN .section2{fill:#fff400}#mermaid-svg-540LcNQu33cHiFdN .section1,#mermaid-svg-540LcNQu33cHiFdN .section3{fill:#fff;opacity:0.2}#mermaid-svg-540LcNQu33cHiFdN .sectionTitle0{fill:#333}#mermaid-svg-540LcNQu33cHiFdN .sectionTitle1{fill:#333}#mermaid-svg-540LcNQu33cHiFdN .sectionTitle2{fill:#333}#mermaid-svg-540LcNQu33cHiFdN .sectionTitle3{fill:#333}#mermaid-svg-540LcNQu33cHiFdN .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-540LcNQu33cHiFdN .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-540LcNQu33cHiFdN .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-540LcNQu33cHiFdN .grid path{stroke-width:0}#mermaid-svg-540LcNQu33cHiFdN .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-540LcNQu33cHiFdN .task{stroke-width:2}#mermaid-svg-540LcNQu33cHiFdN .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-540LcNQu33cHiFdN .taskText:not([font-size]){font-size:11px}#mermaid-svg-540LcNQu33cHiFdN .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-540LcNQu33cHiFdN .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-540LcNQu33cHiFdN .task.clickable{cursor:pointer}#mermaid-svg-540LcNQu33cHiFdN .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-540LcNQu33cHiFdN .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-540LcNQu33cHiFdN .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-540LcNQu33cHiFdN .taskText0,#mermaid-svg-540LcNQu33cHiFdN .taskText1,#mermaid-svg-540LcNQu33cHiFdN .taskText2,#mermaid-svg-540LcNQu33cHiFdN .taskText3{fill:#fff}#mermaid-svg-540LcNQu33cHiFdN .task0,#mermaid-svg-540LcNQu33cHiFdN .task1,#mermaid-svg-540LcNQu33cHiFdN .task2,#mermaid-svg-540LcNQu33cHiFdN .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-540LcNQu33cHiFdN .taskTextOutside0,#mermaid-svg-540LcNQu33cHiFdN .taskTextOutside2{fill:#000}#mermaid-svg-540LcNQu33cHiFdN .taskTextOutside1,#mermaid-svg-540LcNQu33cHiFdN .taskTextOutside3{fill:#000}#mermaid-svg-540LcNQu33cHiFdN .active0,#mermaid-svg-540LcNQu33cHiFdN .active1,#mermaid-svg-540LcNQu33cHiFdN .active2,#mermaid-svg-540LcNQu33cHiFdN .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-540LcNQu33cHiFdN .activeText0,#mermaid-svg-540LcNQu33cHiFdN .activeText1,#mermaid-svg-540LcNQu33cHiFdN .activeText2,#mermaid-svg-540LcNQu33cHiFdN .activeText3{fill:#000 !important}#mermaid-svg-540LcNQu33cHiFdN .done0,#mermaid-svg-540LcNQu33cHiFdN .done1,#mermaid-svg-540LcNQu33cHiFdN .done2,#mermaid-svg-540LcNQu33cHiFdN .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-540LcNQu33cHiFdN .doneText0,#mermaid-svg-540LcNQu33cHiFdN .doneText1,#mermaid-svg-540LcNQu33cHiFdN .doneText2,#mermaid-svg-540LcNQu33cHiFdN .doneText3{fill:#000 !important}#mermaid-svg-540LcNQu33cHiFdN .crit0,#mermaid-svg-540LcNQu33cHiFdN .crit1,#mermaid-svg-540LcNQu33cHiFdN .crit2,#mermaid-svg-540LcNQu33cHiFdN .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-540LcNQu33cHiFdN .activeCrit0,#mermaid-svg-540LcNQu33cHiFdN .activeCrit1,#mermaid-svg-540LcNQu33cHiFdN .activeCrit2,#mermaid-svg-540LcNQu33cHiFdN .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-540LcNQu33cHiFdN .doneCrit0,#mermaid-svg-540LcNQu33cHiFdN .doneCrit1,#mermaid-svg-540LcNQu33cHiFdN .doneCrit2,#mermaid-svg-540LcNQu33cHiFdN .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-540LcNQu33cHiFdN .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-540LcNQu33cHiFdN .milestoneText{font-style:italic}#mermaid-svg-540LcNQu33cHiFdN .doneCritText0,#mermaid-svg-540LcNQu33cHiFdN .doneCritText1,#mermaid-svg-540LcNQu33cHiFdN .doneCritText2,#mermaid-svg-540LcNQu33cHiFdN .doneCritText3{fill:#000 !important}#mermaid-svg-540LcNQu33cHiFdN .activeCritText0,#mermaid-svg-540LcNQu33cHiFdN .activeCritText1,#mermaid-svg-540LcNQu33cHiFdN .activeCritText2,#mermaid-svg-540LcNQu33cHiFdN .activeCritText3{fill:#000 !important}#mermaid-svg-540LcNQu33cHiFdN .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-540LcNQu33cHiFdN g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-540LcNQu33cHiFdN g.classGroup text .title{font-weight:bolder}#mermaid-svg-540LcNQu33cHiFdN g.clickable{cursor:pointer}#mermaid-svg-540LcNQu33cHiFdN g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-540LcNQu33cHiFdN g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-540LcNQu33cHiFdN .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-540LcNQu33cHiFdN .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-540LcNQu33cHiFdN .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-540LcNQu33cHiFdN .dashed-line{stroke-dasharray:3}#mermaid-svg-540LcNQu33cHiFdN #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-540LcNQu33cHiFdN #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-540LcNQu33cHiFdN #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-540LcNQu33cHiFdN #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-540LcNQu33cHiFdN #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-540LcNQu33cHiFdN #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-540LcNQu33cHiFdN #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-540LcNQu33cHiFdN #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-540LcNQu33cHiFdN .commit-id,#mermaid-svg-540LcNQu33cHiFdN .commit-msg,#mermaid-svg-540LcNQu33cHiFdN .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-540LcNQu33cHiFdN .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-540LcNQu33cHiFdN .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-540LcNQu33cHiFdN g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-540LcNQu33cHiFdN g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-540LcNQu33cHiFdN g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-540LcNQu33cHiFdN g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-540LcNQu33cHiFdN g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-540LcNQu33cHiFdN g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-540LcNQu33cHiFdN .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-540LcNQu33cHiFdN .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-540LcNQu33cHiFdN .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-540LcNQu33cHiFdN .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-540LcNQu33cHiFdN .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-540LcNQu33cHiFdN .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-540LcNQu33cHiFdN .edgeLabel text{fill:#333}#mermaid-svg-540LcNQu33cHiFdN .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-540LcNQu33cHiFdN .node circle.state-start{fill:black;stroke:black}#mermaid-svg-540LcNQu33cHiFdN .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-540LcNQu33cHiFdN #statediagram-barbEnd{fill:#9370db}#mermaid-svg-540LcNQu33cHiFdN .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-540LcNQu33cHiFdN .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-540LcNQu33cHiFdN .statediagram-state .divider{stroke:#9370db}#mermaid-svg-540LcNQu33cHiFdN .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-540LcNQu33cHiFdN .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-540LcNQu33cHiFdN .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-540LcNQu33cHiFdN .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-540LcNQu33cHiFdN .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-540LcNQu33cHiFdN .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-540LcNQu33cHiFdN .note-edge{stroke-dasharray:5}#mermaid-svg-540LcNQu33cHiFdN .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-540LcNQu33cHiFdN .error-icon{fill:#522}#mermaid-svg-540LcNQu33cHiFdN .error-text{fill:#522;stroke:#522}#mermaid-svg-540LcNQu33cHiFdN .edge-thickness-normal{stroke-width:2px}#mermaid-svg-540LcNQu33cHiFdN .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-540LcNQu33cHiFdN .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-540LcNQu33cHiFdN .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-540LcNQu33cHiFdN .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-540LcNQu33cHiFdN .marker{fill:#333}#mermaid-svg-540LcNQu33cHiFdN .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-540LcNQu33cHiFdN {color: rgba(0, 0, 0, 0.75);font: ;}

委派
BootstrapClassLoader
ApplicationClassLoader

JDBC 源码分析

通过分析jdbc 加载过程,理解如何让父类加载器委派子类加载器完成类加载。

比较详细的分析可以参考:深入探索“线程上下文类加载器”

真正理解线程上下文类加载器(多案例分析)

Jdbc 操作数据库的代码,简单示例:

// 装载mysql的驱动,把Driver类装载进jvm
Class.forName("com.mysql.jdbc.Driver");
// 获取数据库连接
Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
// 使用连接操作数据库
stmt = (Statement) conn.createStatement();
String sql = "SELECT * FROM xxx";
ResultSet rs = stmt.executeQuery(sql);

Class.forName 将类.class 文件加载到jvm中。并且会执行static代码块,初始化静态变量。

着重分析一下 DriverManager.getConnection 过程

DriverManager 类代码:

在执行getConnection方法前,会先执行静态代码块,只看核心代码

    static {loadInitialDrivers();println("JDBC DriverManager initialized");}private static void loadInitialDrivers() {// ....// 加载 Driver 所有实现ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);Iterator<Driver> driversIterator = loadedDrivers.iterator();try{while(driversIterator.hasNext()) {driversIterator.next();}} catch(Throwable t) {// Do nothing}return null;// ....}

说明:ServiceLoader 是jdk提供的服务实现查找的工具类。这里引入java.sql.Driver Class,就会去Mysql jar 包 “META-INF/services/” 目录下,寻找 java.sql.Driver 命名的文件,该文件中存放所有的服务接口实现类的全限定名称(com.mysql.jdbc.Driver),具体看下load方法:

    public static <S> ServiceLoader<S> load(Class<S> service) {// 获取线程上下文类加载器ClassLoader cl = Thread.currentThread().getContextClassLoader();// 执行load方法return ServiceLoader.load(service, cl);}public static <S> ServiceLoader<S> load(Class<S> service,ClassLoader loader){// 创建了一个 ServiceLoader,调用有参的构造方法return new  ServiceLoader<>(service, loader);}private ServiceLoader(Class<S> svc, ClassLoader cl) {service = Objects.requireNonNull(svc, "Service interface cannot be null");loader = (cl == null) ? ClassLoader.getSystemClassLoader() : cl;acc = (System.getSecurityManager() != null) ? AccessController.getContext() : null;// 执行reload方法reload();}public void reload() {// LinkedHashMap<String,S> providers 用于缓存提供程序providers.clear();// 创建一个惰性迭代器lookupIterator = new LazyIterator(service, loader);}

其实就是将所有服务实现类(比如com.mysql.jdbc.Driver ,com.mysql.fabric.jdbc.FabricMySQLDriver等等),放入迭代器中,再关注下,迭代的代码实现了什么

   while(driversIterator.hasNext()) {driversIterator.next();}
//  hasNext 和  next 都被重新实现了
// 具体只展示一下 next() 方法,在next 方法中将服务实现类,都创建出来(删掉了许多代码,只保留了主要的)private S next() {String cn = nextName;nextName = null;Class<?> c = null;// ...// 使用forname 反射,将服务实现(比如 com.mysql.jdbc.Driver )装载至jvm中,但是并没有初始化(false),loader 就是构造 LazyIterator 传入的 classloader,也就是线程上下文类加载器(默认是 applicationClassloader 应用类加载器)c = Class.forName(cn, false, loader);// ...// 使用 newInstance 创建对象(使用无参的构造方法)S p = service.cast(c.newInstance());// 将服务实现类对象,设置到 缓存map中。providers.put(cn, p);return p;}       

其实在迭代所有服务实现类时,都会使用线程上下文类加载器(threadContextClassLoader)做为参数,执行forName 方法,并newInstance 调用无参构造器实例化。

// java.sql.DriverManagerprivate static Connection getConnection(String url, java.util.Properties info, Class<?> caller) throws SQLException {// 循环 registeredDrivers 是一个 CopyOnWriteArrayList<DriverInfo> 存放这 driver实例for(DriverInfo aDriver : registeredDrivers) {if(isDriverAllowed(aDriver.driver, callerCL)) {// driver.connect 调用的代码就是 服务实现类(比如com.mysql.cj.jdbc.Driver)实现的内容Connection con = aDriver.driver.connect(url, info);if (con != null) {return (con);}}

基于上述的代码,可以看到 基础类(jdk中的DriverManager)回调用户的代码(com.mysql.cj.jdbc.Driver 的connect 方法)。 在 DriverManager.getConnection 方法中,调用了 Driver 的 connect 用于获取数据库连接。

#mermaid-svg-brMKgBnO96SP2Jqo .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-brMKgBnO96SP2Jqo .label text{fill:#333}#mermaid-svg-brMKgBnO96SP2Jqo .node rect,#mermaid-svg-brMKgBnO96SP2Jqo .node circle,#mermaid-svg-brMKgBnO96SP2Jqo .node ellipse,#mermaid-svg-brMKgBnO96SP2Jqo .node polygon,#mermaid-svg-brMKgBnO96SP2Jqo .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-brMKgBnO96SP2Jqo .node .label{text-align:center;fill:#333}#mermaid-svg-brMKgBnO96SP2Jqo .node.clickable{cursor:pointer}#mermaid-svg-brMKgBnO96SP2Jqo .arrowheadPath{fill:#333}#mermaid-svg-brMKgBnO96SP2Jqo .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-brMKgBnO96SP2Jqo .flowchart-link{stroke:#333;fill:none}#mermaid-svg-brMKgBnO96SP2Jqo .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-brMKgBnO96SP2Jqo .edgeLabel rect{opacity:0.9}#mermaid-svg-brMKgBnO96SP2Jqo .edgeLabel span{color:#333}#mermaid-svg-brMKgBnO96SP2Jqo .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-brMKgBnO96SP2Jqo .cluster text{fill:#333}#mermaid-svg-brMKgBnO96SP2Jqo div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-brMKgBnO96SP2Jqo .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-brMKgBnO96SP2Jqo text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-brMKgBnO96SP2Jqo .actor-line{stroke:grey}#mermaid-svg-brMKgBnO96SP2Jqo .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-brMKgBnO96SP2Jqo .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-brMKgBnO96SP2Jqo #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-brMKgBnO96SP2Jqo .sequenceNumber{fill:#fff}#mermaid-svg-brMKgBnO96SP2Jqo #sequencenumber{fill:#333}#mermaid-svg-brMKgBnO96SP2Jqo #crosshead path{fill:#333;stroke:#333}#mermaid-svg-brMKgBnO96SP2Jqo .messageText{fill:#333;stroke:#333}#mermaid-svg-brMKgBnO96SP2Jqo .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-brMKgBnO96SP2Jqo .labelText,#mermaid-svg-brMKgBnO96SP2Jqo .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-brMKgBnO96SP2Jqo .loopText,#mermaid-svg-brMKgBnO96SP2Jqo .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-brMKgBnO96SP2Jqo .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-brMKgBnO96SP2Jqo .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-brMKgBnO96SP2Jqo .noteText,#mermaid-svg-brMKgBnO96SP2Jqo .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-brMKgBnO96SP2Jqo .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-brMKgBnO96SP2Jqo .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-brMKgBnO96SP2Jqo .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-brMKgBnO96SP2Jqo .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-brMKgBnO96SP2Jqo .section{stroke:none;opacity:0.2}#mermaid-svg-brMKgBnO96SP2Jqo .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-brMKgBnO96SP2Jqo .section2{fill:#fff400}#mermaid-svg-brMKgBnO96SP2Jqo .section1,#mermaid-svg-brMKgBnO96SP2Jqo .section3{fill:#fff;opacity:0.2}#mermaid-svg-brMKgBnO96SP2Jqo .sectionTitle0{fill:#333}#mermaid-svg-brMKgBnO96SP2Jqo .sectionTitle1{fill:#333}#mermaid-svg-brMKgBnO96SP2Jqo .sectionTitle2{fill:#333}#mermaid-svg-brMKgBnO96SP2Jqo .sectionTitle3{fill:#333}#mermaid-svg-brMKgBnO96SP2Jqo .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-brMKgBnO96SP2Jqo .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-brMKgBnO96SP2Jqo .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-brMKgBnO96SP2Jqo .grid path{stroke-width:0}#mermaid-svg-brMKgBnO96SP2Jqo .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-brMKgBnO96SP2Jqo .task{stroke-width:2}#mermaid-svg-brMKgBnO96SP2Jqo .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-brMKgBnO96SP2Jqo .taskText:not([font-size]){font-size:11px}#mermaid-svg-brMKgBnO96SP2Jqo .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-brMKgBnO96SP2Jqo .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-brMKgBnO96SP2Jqo .task.clickable{cursor:pointer}#mermaid-svg-brMKgBnO96SP2Jqo .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-brMKgBnO96SP2Jqo .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-brMKgBnO96SP2Jqo .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-brMKgBnO96SP2Jqo .taskText0,#mermaid-svg-brMKgBnO96SP2Jqo .taskText1,#mermaid-svg-brMKgBnO96SP2Jqo .taskText2,#mermaid-svg-brMKgBnO96SP2Jqo .taskText3{fill:#fff}#mermaid-svg-brMKgBnO96SP2Jqo .task0,#mermaid-svg-brMKgBnO96SP2Jqo .task1,#mermaid-svg-brMKgBnO96SP2Jqo .task2,#mermaid-svg-brMKgBnO96SP2Jqo .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-brMKgBnO96SP2Jqo .taskTextOutside0,#mermaid-svg-brMKgBnO96SP2Jqo .taskTextOutside2{fill:#000}#mermaid-svg-brMKgBnO96SP2Jqo .taskTextOutside1,#mermaid-svg-brMKgBnO96SP2Jqo .taskTextOutside3{fill:#000}#mermaid-svg-brMKgBnO96SP2Jqo .active0,#mermaid-svg-brMKgBnO96SP2Jqo .active1,#mermaid-svg-brMKgBnO96SP2Jqo .active2,#mermaid-svg-brMKgBnO96SP2Jqo .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-brMKgBnO96SP2Jqo .activeText0,#mermaid-svg-brMKgBnO96SP2Jqo .activeText1,#mermaid-svg-brMKgBnO96SP2Jqo .activeText2,#mermaid-svg-brMKgBnO96SP2Jqo .activeText3{fill:#000 !important}#mermaid-svg-brMKgBnO96SP2Jqo .done0,#mermaid-svg-brMKgBnO96SP2Jqo .done1,#mermaid-svg-brMKgBnO96SP2Jqo .done2,#mermaid-svg-brMKgBnO96SP2Jqo .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-brMKgBnO96SP2Jqo .doneText0,#mermaid-svg-brMKgBnO96SP2Jqo .doneText1,#mermaid-svg-brMKgBnO96SP2Jqo .doneText2,#mermaid-svg-brMKgBnO96SP2Jqo .doneText3{fill:#000 !important}#mermaid-svg-brMKgBnO96SP2Jqo .crit0,#mermaid-svg-brMKgBnO96SP2Jqo .crit1,#mermaid-svg-brMKgBnO96SP2Jqo .crit2,#mermaid-svg-brMKgBnO96SP2Jqo .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-brMKgBnO96SP2Jqo .activeCrit0,#mermaid-svg-brMKgBnO96SP2Jqo .activeCrit1,#mermaid-svg-brMKgBnO96SP2Jqo .activeCrit2,#mermaid-svg-brMKgBnO96SP2Jqo .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-brMKgBnO96SP2Jqo .doneCrit0,#mermaid-svg-brMKgBnO96SP2Jqo .doneCrit1,#mermaid-svg-brMKgBnO96SP2Jqo .doneCrit2,#mermaid-svg-brMKgBnO96SP2Jqo .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-brMKgBnO96SP2Jqo .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-brMKgBnO96SP2Jqo .milestoneText{font-style:italic}#mermaid-svg-brMKgBnO96SP2Jqo .doneCritText0,#mermaid-svg-brMKgBnO96SP2Jqo .doneCritText1,#mermaid-svg-brMKgBnO96SP2Jqo .doneCritText2,#mermaid-svg-brMKgBnO96SP2Jqo .doneCritText3{fill:#000 !important}#mermaid-svg-brMKgBnO96SP2Jqo .activeCritText0,#mermaid-svg-brMKgBnO96SP2Jqo .activeCritText1,#mermaid-svg-brMKgBnO96SP2Jqo .activeCritText2,#mermaid-svg-brMKgBnO96SP2Jqo .activeCritText3{fill:#000 !important}#mermaid-svg-brMKgBnO96SP2Jqo .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-brMKgBnO96SP2Jqo g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-brMKgBnO96SP2Jqo g.classGroup text .title{font-weight:bolder}#mermaid-svg-brMKgBnO96SP2Jqo g.clickable{cursor:pointer}#mermaid-svg-brMKgBnO96SP2Jqo g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-brMKgBnO96SP2Jqo g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-brMKgBnO96SP2Jqo .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-brMKgBnO96SP2Jqo .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-brMKgBnO96SP2Jqo .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-brMKgBnO96SP2Jqo .dashed-line{stroke-dasharray:3}#mermaid-svg-brMKgBnO96SP2Jqo #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-brMKgBnO96SP2Jqo #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-brMKgBnO96SP2Jqo #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-brMKgBnO96SP2Jqo #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-brMKgBnO96SP2Jqo #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-brMKgBnO96SP2Jqo #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-brMKgBnO96SP2Jqo #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-brMKgBnO96SP2Jqo #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-brMKgBnO96SP2Jqo .commit-id,#mermaid-svg-brMKgBnO96SP2Jqo .commit-msg,#mermaid-svg-brMKgBnO96SP2Jqo .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-brMKgBnO96SP2Jqo .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-brMKgBnO96SP2Jqo .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-brMKgBnO96SP2Jqo g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-brMKgBnO96SP2Jqo g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-brMKgBnO96SP2Jqo g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-brMKgBnO96SP2Jqo g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-brMKgBnO96SP2Jqo g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-brMKgBnO96SP2Jqo g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-brMKgBnO96SP2Jqo .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-brMKgBnO96SP2Jqo .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-brMKgBnO96SP2Jqo .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-brMKgBnO96SP2Jqo .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-brMKgBnO96SP2Jqo .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-brMKgBnO96SP2Jqo .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-brMKgBnO96SP2Jqo .edgeLabel text{fill:#333}#mermaid-svg-brMKgBnO96SP2Jqo .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-brMKgBnO96SP2Jqo .node circle.state-start{fill:black;stroke:black}#mermaid-svg-brMKgBnO96SP2Jqo .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-brMKgBnO96SP2Jqo #statediagram-barbEnd{fill:#9370db}#mermaid-svg-brMKgBnO96SP2Jqo .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-brMKgBnO96SP2Jqo .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-brMKgBnO96SP2Jqo .statediagram-state .divider{stroke:#9370db}#mermaid-svg-brMKgBnO96SP2Jqo .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-brMKgBnO96SP2Jqo .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-brMKgBnO96SP2Jqo .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-brMKgBnO96SP2Jqo .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-brMKgBnO96SP2Jqo .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-brMKgBnO96SP2Jqo .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-brMKgBnO96SP2Jqo .note-edge{stroke-dasharray:5}#mermaid-svg-brMKgBnO96SP2Jqo .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-brMKgBnO96SP2Jqo .error-icon{fill:#522}#mermaid-svg-brMKgBnO96SP2Jqo .error-text{fill:#522;stroke:#522}#mermaid-svg-brMKgBnO96SP2Jqo .edge-thickness-normal{stroke-width:2px}#mermaid-svg-brMKgBnO96SP2Jqo .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-brMKgBnO96SP2Jqo .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-brMKgBnO96SP2Jqo .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-brMKgBnO96SP2Jqo .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-brMKgBnO96SP2Jqo .marker{fill:#333}#mermaid-svg-brMKgBnO96SP2Jqo .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-brMKgBnO96SP2Jqo {color: rgba(0, 0, 0, 0.75);font: ;}

java.sql.Driver SPI接口 被bootstrap类加载器加载
com.mysql.cj.jdbc.Driver SPI实现类 被application类加载器加载
spijava.sql.Driver   # SPI 接口  #bootstrapClassLoader
com.mysql.cj.jdbc.Driver # SPI 实现类  # appClassLoader

代码实践

需求: 模拟上述JDBC使用SPI的方式在基础类中回调用户的代码

开发环境:JDK1.8

思路: 需要创建SPI服务接口和基础调用类(在Bootstrap Calssloader下加载,跟JDK加载核心包是同一个classloader),创建SPI服务实现(在appClassloader下加载),用于基础调用类调用SPI的服务实现。

目的:1, 测试在双亲委派模型下,父类加载器加载的类能否调用子类加载器加载的类。

2, 使用线程上下文类加载器(ThredContextClassLoader)破坏双亲委派模型

流程图:

#mermaid-svg-v6k8VTKOYNbZp7j6 .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 .label text{fill:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 .node rect,#mermaid-svg-v6k8VTKOYNbZp7j6 .node circle,#mermaid-svg-v6k8VTKOYNbZp7j6 .node ellipse,#mermaid-svg-v6k8VTKOYNbZp7j6 .node polygon,#mermaid-svg-v6k8VTKOYNbZp7j6 .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-v6k8VTKOYNbZp7j6 .node .label{text-align:center;fill:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 .node.clickable{cursor:pointer}#mermaid-svg-v6k8VTKOYNbZp7j6 .arrowheadPath{fill:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-v6k8VTKOYNbZp7j6 .flowchart-link{stroke:#333;fill:none}#mermaid-svg-v6k8VTKOYNbZp7j6 .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-v6k8VTKOYNbZp7j6 .edgeLabel rect{opacity:0.9}#mermaid-svg-v6k8VTKOYNbZp7j6 .edgeLabel span{color:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-v6k8VTKOYNbZp7j6 .cluster text{fill:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-v6k8VTKOYNbZp7j6 .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-v6k8VTKOYNbZp7j6 text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-v6k8VTKOYNbZp7j6 .actor-line{stroke:grey}#mermaid-svg-v6k8VTKOYNbZp7j6 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 .sequenceNumber{fill:#fff}#mermaid-svg-v6k8VTKOYNbZp7j6 #sequencenumber{fill:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 #crosshead path{fill:#333;stroke:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 .messageText{fill:#333;stroke:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-v6k8VTKOYNbZp7j6 .labelText,#mermaid-svg-v6k8VTKOYNbZp7j6 .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-v6k8VTKOYNbZp7j6 .loopText,#mermaid-svg-v6k8VTKOYNbZp7j6 .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-v6k8VTKOYNbZp7j6 .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-v6k8VTKOYNbZp7j6 .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-v6k8VTKOYNbZp7j6 .noteText,#mermaid-svg-v6k8VTKOYNbZp7j6 .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-v6k8VTKOYNbZp7j6 .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-v6k8VTKOYNbZp7j6 .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-v6k8VTKOYNbZp7j6 .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-v6k8VTKOYNbZp7j6 .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-v6k8VTKOYNbZp7j6 .section{stroke:none;opacity:0.2}#mermaid-svg-v6k8VTKOYNbZp7j6 .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-v6k8VTKOYNbZp7j6 .section2{fill:#fff400}#mermaid-svg-v6k8VTKOYNbZp7j6 .section1,#mermaid-svg-v6k8VTKOYNbZp7j6 .section3{fill:#fff;opacity:0.2}#mermaid-svg-v6k8VTKOYNbZp7j6 .sectionTitle0{fill:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 .sectionTitle1{fill:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 .sectionTitle2{fill:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 .sectionTitle3{fill:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-v6k8VTKOYNbZp7j6 .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-v6k8VTKOYNbZp7j6 .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-v6k8VTKOYNbZp7j6 .grid path{stroke-width:0}#mermaid-svg-v6k8VTKOYNbZp7j6 .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-v6k8VTKOYNbZp7j6 .task{stroke-width:2}#mermaid-svg-v6k8VTKOYNbZp7j6 .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-v6k8VTKOYNbZp7j6 .taskText:not([font-size]){font-size:11px}#mermaid-svg-v6k8VTKOYNbZp7j6 .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-v6k8VTKOYNbZp7j6 .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-v6k8VTKOYNbZp7j6 .task.clickable{cursor:pointer}#mermaid-svg-v6k8VTKOYNbZp7j6 .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-v6k8VTKOYNbZp7j6 .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-v6k8VTKOYNbZp7j6 .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-v6k8VTKOYNbZp7j6 .taskText0,#mermaid-svg-v6k8VTKOYNbZp7j6 .taskText1,#mermaid-svg-v6k8VTKOYNbZp7j6 .taskText2,#mermaid-svg-v6k8VTKOYNbZp7j6 .taskText3{fill:#fff}#mermaid-svg-v6k8VTKOYNbZp7j6 .task0,#mermaid-svg-v6k8VTKOYNbZp7j6 .task1,#mermaid-svg-v6k8VTKOYNbZp7j6 .task2,#mermaid-svg-v6k8VTKOYNbZp7j6 .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-v6k8VTKOYNbZp7j6 .taskTextOutside0,#mermaid-svg-v6k8VTKOYNbZp7j6 .taskTextOutside2{fill:#000}#mermaid-svg-v6k8VTKOYNbZp7j6 .taskTextOutside1,#mermaid-svg-v6k8VTKOYNbZp7j6 .taskTextOutside3{fill:#000}#mermaid-svg-v6k8VTKOYNbZp7j6 .active0,#mermaid-svg-v6k8VTKOYNbZp7j6 .active1,#mermaid-svg-v6k8VTKOYNbZp7j6 .active2,#mermaid-svg-v6k8VTKOYNbZp7j6 .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-v6k8VTKOYNbZp7j6 .activeText0,#mermaid-svg-v6k8VTKOYNbZp7j6 .activeText1,#mermaid-svg-v6k8VTKOYNbZp7j6 .activeText2,#mermaid-svg-v6k8VTKOYNbZp7j6 .activeText3{fill:#000 !important}#mermaid-svg-v6k8VTKOYNbZp7j6 .done0,#mermaid-svg-v6k8VTKOYNbZp7j6 .done1,#mermaid-svg-v6k8VTKOYNbZp7j6 .done2,#mermaid-svg-v6k8VTKOYNbZp7j6 .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-v6k8VTKOYNbZp7j6 .doneText0,#mermaid-svg-v6k8VTKOYNbZp7j6 .doneText1,#mermaid-svg-v6k8VTKOYNbZp7j6 .doneText2,#mermaid-svg-v6k8VTKOYNbZp7j6 .doneText3{fill:#000 !important}#mermaid-svg-v6k8VTKOYNbZp7j6 .crit0,#mermaid-svg-v6k8VTKOYNbZp7j6 .crit1,#mermaid-svg-v6k8VTKOYNbZp7j6 .crit2,#mermaid-svg-v6k8VTKOYNbZp7j6 .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-v6k8VTKOYNbZp7j6 .activeCrit0,#mermaid-svg-v6k8VTKOYNbZp7j6 .activeCrit1,#mermaid-svg-v6k8VTKOYNbZp7j6 .activeCrit2,#mermaid-svg-v6k8VTKOYNbZp7j6 .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-v6k8VTKOYNbZp7j6 .doneCrit0,#mermaid-svg-v6k8VTKOYNbZp7j6 .doneCrit1,#mermaid-svg-v6k8VTKOYNbZp7j6 .doneCrit2,#mermaid-svg-v6k8VTKOYNbZp7j6 .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-v6k8VTKOYNbZp7j6 .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-v6k8VTKOYNbZp7j6 .milestoneText{font-style:italic}#mermaid-svg-v6k8VTKOYNbZp7j6 .doneCritText0,#mermaid-svg-v6k8VTKOYNbZp7j6 .doneCritText1,#mermaid-svg-v6k8VTKOYNbZp7j6 .doneCritText2,#mermaid-svg-v6k8VTKOYNbZp7j6 .doneCritText3{fill:#000 !important}#mermaid-svg-v6k8VTKOYNbZp7j6 .activeCritText0,#mermaid-svg-v6k8VTKOYNbZp7j6 .activeCritText1,#mermaid-svg-v6k8VTKOYNbZp7j6 .activeCritText2,#mermaid-svg-v6k8VTKOYNbZp7j6 .activeCritText3{fill:#000 !important}#mermaid-svg-v6k8VTKOYNbZp7j6 .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-v6k8VTKOYNbZp7j6 g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-v6k8VTKOYNbZp7j6 g.classGroup text .title{font-weight:bolder}#mermaid-svg-v6k8VTKOYNbZp7j6 g.clickable{cursor:pointer}#mermaid-svg-v6k8VTKOYNbZp7j6 g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-v6k8VTKOYNbZp7j6 g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-v6k8VTKOYNbZp7j6 .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-v6k8VTKOYNbZp7j6 .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-v6k8VTKOYNbZp7j6 .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-v6k8VTKOYNbZp7j6 .dashed-line{stroke-dasharray:3}#mermaid-svg-v6k8VTKOYNbZp7j6 #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-v6k8VTKOYNbZp7j6 #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-v6k8VTKOYNbZp7j6 #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-v6k8VTKOYNbZp7j6 #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-v6k8VTKOYNbZp7j6 #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-v6k8VTKOYNbZp7j6 #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-v6k8VTKOYNbZp7j6 #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-v6k8VTKOYNbZp7j6 #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-v6k8VTKOYNbZp7j6 .commit-id,#mermaid-svg-v6k8VTKOYNbZp7j6 .commit-msg,#mermaid-svg-v6k8VTKOYNbZp7j6 .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-v6k8VTKOYNbZp7j6 .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-v6k8VTKOYNbZp7j6 .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-v6k8VTKOYNbZp7j6 g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-v6k8VTKOYNbZp7j6 g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-v6k8VTKOYNbZp7j6 g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-v6k8VTKOYNbZp7j6 g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-v6k8VTKOYNbZp7j6 g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-v6k8VTKOYNbZp7j6 .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-v6k8VTKOYNbZp7j6 .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-v6k8VTKOYNbZp7j6 .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-v6k8VTKOYNbZp7j6 .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-v6k8VTKOYNbZp7j6 .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-v6k8VTKOYNbZp7j6 .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-v6k8VTKOYNbZp7j6 .edgeLabel text{fill:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-v6k8VTKOYNbZp7j6 .node circle.state-start{fill:black;stroke:black}#mermaid-svg-v6k8VTKOYNbZp7j6 .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-v6k8VTKOYNbZp7j6 #statediagram-barbEnd{fill:#9370db}#mermaid-svg-v6k8VTKOYNbZp7j6 .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-v6k8VTKOYNbZp7j6 .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-v6k8VTKOYNbZp7j6 .statediagram-state .divider{stroke:#9370db}#mermaid-svg-v6k8VTKOYNbZp7j6 .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-v6k8VTKOYNbZp7j6 .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-v6k8VTKOYNbZp7j6 .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-v6k8VTKOYNbZp7j6 .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-v6k8VTKOYNbZp7j6 .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-v6k8VTKOYNbZp7j6 .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-v6k8VTKOYNbZp7j6 .note-edge{stroke-dasharray:5}#mermaid-svg-v6k8VTKOYNbZp7j6 .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-v6k8VTKOYNbZp7j6 .error-icon{fill:#522}#mermaid-svg-v6k8VTKOYNbZp7j6 .error-text{fill:#522;stroke:#522}#mermaid-svg-v6k8VTKOYNbZp7j6 .edge-thickness-normal{stroke-width:2px}#mermaid-svg-v6k8VTKOYNbZp7j6 .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-v6k8VTKOYNbZp7j6 .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-v6k8VTKOYNbZp7j6 .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-v6k8VTKOYNbZp7j6 .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-v6k8VTKOYNbZp7j6 .marker{fill:#333}#mermaid-svg-v6k8VTKOYNbZp7j6 .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-v6k8VTKOYNbZp7j6 {color: rgba(0, 0, 0, 0.75);font: ;}

实现
调用
SPI服务接口
SPI服务实现
基础调用类

需要创建两个工程,

工程一: spi接口和基础调用类需要打成jar包追加在bootstrap加载。(父,类加载器)

工程二: 我们自己的程序,实现spi服务接口并调用(子,类加载器)

(jvm 命令,用于将该jar使用bootstrap classloader 加载: -Xbootclasspath/a:D:/ideaworkspace/base.jar)

工程一

新建工程步骤省略,最简单的java工程就可以,或者maven工程

SPI 服务接口

很简单,只有一个方法。

/*** <h1>SPI接口</h1>*/
public interface SpiService {/*** 连接** @return*/String conn();
}

基础调用类

这里没有使用 ServiceLoader 去自动扫描具体的服务实现类名,这里直接指定了(”fun.gengzi.test.classshow.SpiServiceImpl“) 这个就是spi服务实现的全限定名称,具体自己的实现的包名类名,自行修改。

import java.util.ArrayList;
import java.util.List;/*** <h1>基础调用类</h1>*/
public class SpiUse {// 保存所有服务实现public static List<SpiService> spiServiceList = new ArrayList<>();static {try {System.out.println("thread context classloader :" + Thread.currentThread().getContextClassLoader());// TODO 测试1:测试不使用线程上下文类加载器,也就是遵循双亲委派模型,加载类// 通过反射获取SPI服务实现类,并创建Class<?> aClass = Class.forName("fun.gengzi.test.classshow.SpiServiceImpl");// TODO 测试2:注释上述代码,放开下面代码,测试使用线程上下文类加载器破坏双亲委派模型//      Class<?> aClass = Class.forName("fun.gengzi.test.classshow.SpiServiceImpl", true, Thread.currentThread().getContextClassLoader());Object o = aClass.newInstance();spiServiceList.add((SpiService) o);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();}}/*** 工具方法** @return*/public static String conn() {// 仿照DriverManager.getConnection,循环所有的服务实现,有一个成功就返回(其实我们这里只有一个实现)for (SpiService spiService : spiServiceList) {return spiService.conn();}return null;}}

打包

关于打jar包注意:需要在artifacts添加 Jar-> From model… 。然后 Build->Build Porject 就可以了

将打包好的jar,拷贝至一个目录中,方便使用。我拷贝到本地的:D:\ideaworkspace\base.jar

注意:测试两种情况,要分别修改代码,并重新打包,拷贝至之前的目录覆盖之前的jar

工程二

省略新建工程的步骤

导入base.jar包

将base.jar 引入当前工程,才能引用需要的类

SPI 服务实现

这里实现很简单,就返回了一个文本

import com.gengzi.base.SpiService;/*** <h1>服务接口实现</h1>*/
public class SpiServiceImpl implements SpiService {@Overridepublic String conn() {return "---conn---";}
}

测试代码

import com.gengzi.base.SpiUse;public class SpiTest {public static void main(String[] args) {String conn = SpiUse.conn();System.out.println(conn);}}

测试

执行上述测试代码main方法时,请加入jvm 的参数命令,将base.jar 使用bootstrap classloader 加载。

-Xbootclasspath/a:D:\ideaworkspace\base.jar

测试1:

  // TODO 测试1:测试不使用线程上下文类加载器,也就是遵循双亲委派模型,加载类Class<?> aClass = Class.forName("fun.gengzi.test.classshow.SpiServiceImpl");

结果:

thread context classloader :sun.misc.Launcher$AppClassLoader@18b4aac2
null
java.lang.ClassNotFoundException: fun/gengzi/test/classshow/SpiServiceImplat java.lang.Class.forName0(Native Method)at java.lang.Class.forName(Class.java:264)at com.gengzi.base.SpiUse.<clinit>(SpiUse.java:18)at fun.gengzi.test.classshow.SpiTest.main(SpiTest.java:8)Process finished with exit code 0

根据上述信息:在基础类中,无法找到SpiServiceImpl 这个类。也就是说,在遵循双亲委派模型的情况下,父类加载器加载的类无法调用子类加载器加载的类

测试2:

 // TODO 测试2:注释上述代码,放开下面代码,测试使用线程上下文类加载器破坏双亲委派模型Class<?> aClass = Class.forName("fun.gengzi.test.classshow.SpiServiceImpl", true, Thread.currentThread().getContextClassLoader());

结果:

thread context classloader :sun.misc.Launcher$AppClassLoader@18b4aac2
---conn---Process finished with exit code 0

成功了,实现了在基础类中调用了用户代码,就是依靠于线程上下文类加载器。

听说点赞关注的人,身体健康,一夜暴富,升职加薪迎娶白富美!!!

点我领取每日福利
微信公众号:耿子blog
GitHub地址:gengzi

日志追踪-类加载器-线程上下文类加载器相关推荐

  1. 类加载器-线程上下文

    线程上下文类加载器 我们在使用 JDBC 时,都需要加载 Driver 驱动,不知道你注意到没有,不写 Class.forName("com.mysql.jdbc.Driver") ...

  2. (二)JVM成神路之剖析Java类加载子系统、双亲委派机制及线程上下文类加载器

    引言 上篇<初识Java虚拟机>文章中曾提及到:我们所编写的Java代码经过编译之后,会生成对应的class字节码文件,而在程序启动时会通过类加载子系统将这些字节码文件先装载进内存,然后再 ...

  3. 利用classloader同一个项目中加载另一个同名的类_线程上下文类加载器ContextClassLoader内存泄漏隐患...

    前提 今天(2020-01-18)在编写Netty相关代码的时候,从Netty源码中的ThreadDeathWatcher和GlobalEventExecutor追溯到两个和线程上下文类加载器Cont ...

  4. 真正理解线程上下文类加载器(多案例分析)

    1.线程上下文类加载器是从jdk1.2开始引入的,类Thread中的getContextClassLoader()与setContextClassLoader(ClassLoader c1),分别用来 ...

  5. java查看上下文加载器_线程上下文类加载器

    package util.tom; import java.io.*; public class ThreadClassLoader extends Thread { @Override public ...

  6. 重置线程中断状态_记住要重置线程上下文类加载器

    重置线程中断状态 我很难思考与Java 加载有关的东西,而不是与类加载器有关的东西. 在使用应用程序服务器或OSGi的情况下尤其如此,在这些应用程序服务器或OSGi中,经常使用多个类加载器,并且透明地 ...

  7. 记住要重置线程上下文类加载器

    我很难思考与Java 加载有关的东西,而不是与类加载器有关的东西. 在使用应用程序服务器或OSGi的情况下尤其如此,在这些应用程序服务器或OSGi中,经常使用多个类加载器,并且透明地使用类加载器的能力 ...

  8. JVM类加载理解(线程上下文类加载器、Tomcat类加载器)

    类加载机制概念 Java虚拟机把描述类的class文件加载到内存,对其进行校验.转换解析.初始化等操作,最终得到可以被虚拟机直接使用的java类型,这就是虚拟机的加载机制. 主要有五个步骤: 加载 将 ...

  9. Java高并发编程详解系列-线程上下文类加载

    前面的分享中提到的最多的概念就是关于类加载器的概念,但是当我们查看Thread源码的时候会发现如下的两个方法,这两个方法就是获取或者设置线程的上下文类加载器的方法,那么为什么要设置这两个方法呢?这个就 ...

  10. java 上下文加载器_【深入理解Java虚拟机 】线程的上下文类加载器

    线程上下文类加载器 线程上下文类加载器( Thread Context ClassLoader) 是从JDK1.2 引入的,类Thread 的getContextClassLoader() 与 set ...

最新文章

  1. Java项目:生活旅行分享平台(java+Springboot+JPA+Jsp+Html+js+Ajax+maven+mysql)
  2. 集成学习-Adaboost
  3. Science:产前母体感染促进后代的组织特异性免疫和炎症
  4. GDB调试器使用手册
  5. crontab用法疑云
  6. DHCP和DHCP中继功能与配置
  7. 2017-2018-1 20155229 《信息安全系统设计基础》第十三周学习总结
  8. easyui combobox java_Easyui的combobox实现动态数据级联效果
  9. 怎样快速掌握深度学习TensorFlow框架?
  10. 从零入门 Serverless | 使用 Spot 低成本运行 Job 任务
  11. Spring下Redis的响应式编程
  12. 浪潮服务器可管理和维护性,专注用户需求,浪潮服务器提供优质高效的产品
  13. 十个 Python 自动化常用操作
  14. (45.5)【API接口漏洞】API接口之Web Service测试工具Soap UI PRO、SOAPSonar、Burp Suite、WSSAT、WS-Attacker
  15. 《设计模式》笔记 02 - 实例研究:设计一个文档编辑器
  16. Unity 自定义自发光材质 shader (对比Standard Eimission)
  17. FA-RPN: Floating Region Proposals for Face Detection(论文阅读笔记)
  18. 寒武纪MLU270 平台 CNStream 学习记录
  19. [行业动态] 阿里入股新浪对蘑菇街、美丽说的冲击
  20. Node.js中的egg入门、egg路由、egg控制器、egg服务、egg中间件

热门文章

  1. java foxpro,在Visual FoxPro中更新顶部
  2. [渝粤教育] 浙江工商大学 中外经典演出欣赏 参考 资料
  3. [BZOJ3503][CQOI2014]和谐矩阵
  4. 【MMML】多模态机器学习高被引综述论文笔记
  5. 【NLP】一文简要了解词义消歧与实体消歧
  6. xdoj系统_基于RBRVS和DRGs的医院绩效管理体系如何建立?
  7. 冰心吴文藻的爱情始于留学远洋客轮上
  8. 二级造价师课件网课下载,二级造价工程师考试时间报考条件公布!
  9. Android adb截图后保存到电脑
  10. None of the following candidates is applicable because of a receiver type mismatch