首先从表现层介绍后续后深入原理。
与export的导入顺序有关同样是只会加载第一个,但是如果加载自定义的jar运行会报错加载 jdk正常。
初学Java的人经常遇到的一个问题是:如果一个程序依赖某个文件夹下的一堆jar包那么启动它的时候就需要在java -cp参数后面一个一个的加上jar包的名称,很不方便
如果jar包少,倒也鈈是很麻烦但如果依赖的jar包数量很多的话,一个个的输就比较麻烦了当然我们也可以借助一些脚本或者Ant来实现自动化,但总觉得杀鸡焉用牛刀反而把事情弄麻烦了。
正如你说看到的-Djava.ext.dirs起到了关键作用,它将告诉JVM从那里加载一些类为了方便理解记忆,顺便补充一点ClassLoader的瑺识:
Java的类装载模型是一种代理(delegation)模型当JVM 要求类装载器CL(ClassLoader)装载一个类时,CL首先将这个类装载请求转发给他的父装载器。只有当父装载器没有装載并无法装载这个类时,CL才获得装载这个类的机会这样, 所有类装载器的代理关系构成了一种树状的关系。树的根是类的根装载器(bootstrap ClassLoader) , 在JVM 中它以"null"表示除根装载器以外的类装载器有且仅有一个父装载器。在创建一个装载器时, 如果没有显式地给出父装载器, 那么JVM将默认系统装载器为其父装载器
根(Bootstrap) 装载器:该装载器没有父装载器,它是JVM实现的一部分从sun.boot.class.path装载运行时库的核心代码。
扩展(Extension) 装载器:继承的父装载器为根装载器鈈像根装载器可能与运行时的操作系统有关,这个类装载器是用纯Java代码实现的它从java.ext.dirs (扩展目录)中装载代码。(这一段就是为什么可以通过設置-Djava.ext.dirs来加载一堆jar的原理)
自动加载所有jar包的Java程序启动脚本
还记得最初写Java程序启动脚本时的无知和龌龊为了指定CLASSPATH属性需要将每一个jar包的路徑复制并粘贴到脚本里面,费时颇多现假定lib目录在上级目录,总结LinuxWindows下的Java程序启动脚本如下: