什么是双亲委派模型?

什么是双亲委派模型?
最新回答
梦忆沐歌

2026-01-01 14:04:03

双亲委派模型是Java类加载器在加载类时采用的一种自上而下委派、自下而上加载的策略,其核心目的是确保类加载的统一性与安全性。

  • 工作机制:当类加载器收到加载请求时,首先通过findLoadedClass()检查类是否已加载。若未加载,则将请求委派给父类加载器(递归向上至启动类加载器)。仅当所有父类加载器均无法加载时,当前类加载器才会通过findClass()方法自行加载。若最终失败,抛出ClassNotFoundException。这一过程类似“层层上报”,确保类加载的优先级从顶层到底层。

  • 解决的核心问题:

    安全性:通过强制核心Java API类(如java.lang.Object)由启动类加载器加载,防止用户自定义同名类篡改基础类。启动类加载器仅加载$JAVA_HOME/jre/lib目录下的类库,拦截所有非官方类,保障运行时环境的稳定。

    避免重复加载:双亲委派确保类在内存中的唯一性。若子类加载器重复加载已由父类加载的类,JVM会视为不同类,导致ClassCastException。模型通过委派机制消除此类问题。

  • 执行流程:

    检查已加载类:调用findLoadedClass(name),若存在直接返回。

    委派父类加载器:若未加载,递归委派至父类加载器,直至启动类加载器。

    自行加载:父类均无法加载时,调用findClass(name)从文件系统、网络等来源加载字节码,并通过defineClass()转换为Class对象。

    解析类:若resolve参数为true,调用resolveClass()将符号引用转为直接引用。流程形成“自上而下委派、自下而上加载”的顺序,确保高级别加载器优先处理请求。

  • 打破模型的场景:

    SPI机制(如JDBC驱动):核心API(如java.sql.Driver)由启动类加载器加载,但驱动实现(如MySQL JAR)由应用类加载器加载。为解决“父类无法访问子类加载的类”的问题,Java引入线程上下文类加载器(TCCL),允许启动类加载器通过TCCL反向加载应用层类,实现“借道”加载。

    Web服务器(如Tomcat):Tomcat为每个Web应用创建独立的WebAppClassLoader,优先加载应用自身类,仅在找不到时委派父类。这种“子类优先”策略实现类隔离与热部署,允许不同应用使用不同版本的库而互不干扰。

双亲委派模型通过委派机制保障了类加载的安全性与唯一性,而SPI和Tomcat等场景的例外设计则体现了灵活性与业务需求的平衡。