问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

打破双亲委派机制之线程上下文类加载器

创作时间:
作者:
@小白创作中心

打破双亲委派机制之线程上下文类加载器

引用
CSDN
1.
https://m.blog.csdn.net/m0_68089732/article/details/137674906

线程上下文类加载器

在Java中,线程上下文类加载器(Thread Context ClassLoader)是一种特殊的类加载器,主要用于加载JDBC驱动、JNDI服务等。下面通过一个JDBC案例来说明其工作原理。

JDBC案例分析

  1. DriverManager的使用

    在JDBC中,DriverManager用于管理项目中引入的不同数据库驱动,例如MySQL驱动和Oracle驱动。以下是使用DriverManager连接数据库的示例代码:

    package classloader.broken;
    import com.mysql.cj.jdbc.Driver;
    import java.sql.*;
    
    public class JDBCExample {
        static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
        static final String DB_URL = "jdbc:mysql:///bank1";
        static final String USER = "root";
        static final String PASS = "123456";
    
        public static void main(String[] args) {
            Connection conn = null;
            Statement stmt = null;
            try {
                conn = DriverManager.getConnection(DB_URL, USER, PASS);
                stmt = conn.createStatement();
                String sql = "SELECT id, account_name FROM account_info";
                ResultSet rs = stmt.executeQuery(sql);
                while (rs.next()) {
                    int id = rs.getInt("id");
                    String name = rs.getString("account_name");
                    System.out.print("ID: " + id);
                    System.out.print(", Name: " + name + "\n");
                }
                rs.close();
                stmt.close();
                conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (stmt != null) stmt.close();
                } catch (SQLException se2) {}
                try {
                    if (conn != null) conn.close();
                } catch (SQLException se) {
                    se.printStackTrace();
                }
            }
        }
    }
    
  2. 类加载器分析

  • DriverManager类位于rt.jar包中,由启动类加载器(Bootstrap ClassLoader)加载。

  • 项目依赖中的MySQL驱动类由应用程序类加载器(Application ClassLoader)加载。

    DriverManager类的初始化代码中,存在一个LoadInitialDrivers方法,该方法使用SPI机制加载所有实现了Driver接口的实现类。SPI机制通过在特定位置存放一个文件(文件名是接口名,内容包含实现类的类名)来定位实现类。这个过程使用了线程上下文类加载器(即应用程序类加载器)来加载类并创建对象。

双亲委派机制的讨论

关于JDBC案例是否打破了双亲委派机制,存在不同的观点:

  • 观点一:在《深入理解Java虚拟机》一书中,作者周志明认为这种由启动类加载器加载的类,委派应用程序类加载器去加载类的方式,打破了双亲委派机制。

  • 观点二:从类加载流程的角度分析,JDBC只是在DriverManager加载完成后,通过初始化阶段触发了驱动类的加载。类的加载过程仍然遵循双亲委派机制。

因此,关于是否打破双亲委派机制这一问题,目前存在争议,读者可以根据自己的理解做出判断。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号