Java Extension Mechanism

Java 1.2引入了扩展机制(the extension mechanism)。

Extensions 是一组packages和classes,通过the extension mechanism来增加Java平台功能。 扩展机制让我们运行应用时,不用在classpath写extension classes的路径,就能让Java运行环境查找和装载这些extension classes。 Extension classes 如同Java 平台的core classes一样。 这就是为啥叫他们extentions的原因 --它们扩展Java的core API。

This figure shows the relationships between Application, Java Platform, and Extensions.

如上图所示,extensions充当Java平台的插件模块。他们的classes 和 public APIs可被平台上的所有应用使用。

扩展机制同时还为applets提供了下载远程extension classes的机制。

 

创建和使用Extensions

任意的packages或者classes都可以充当一个extension。Extensions用Jar文件来包装。可以通过如下2种方式来扩展extensions:

  1. install extensions - 把这个extension文件放到JRE的特殊的文件夹下
  2. download extensions - 把另一个jar文件的Manifest中引用这个extension文件。 

Install extensions

Installed extensions and java runtime environment directory.

把jar文件放到 <jdk_home>/jre/lib/ext文件夹下。

在Java 6 中,extension的搜索路径(java.ext.dirs)可以是多个,所以extension jar文件可以放置在任意文件路径下,没有上面必须放置在jre/lib/ext目录下的限制。这将是机器上的所有JRE都可以共享同一个扩展。

 

Download extensions

 一个jar文件的Mainfest可以通过下面2中方式,在其headers中引用1个或多个extensions:

  1. Class-Path
  2. Extension-List

这2种方式是互斥的,也就是只能在headers使用任一种方式。Class-Path的方式不会把extension装在jre/lib/ext目录下,所以它每次都会下载所需的extensions,并且部署简单。 Extension-List方式只会在第一次下载extensions,然后安装在jre/lib/ext目录。缺点是部署系统时常常增加复杂性。

 

例如:

Class-Path: myapp/area.jar servlet.jar images/

在Class-Path中,任何不是以“/”结尾的路径,都被认作jar文件。以“/”结尾的路径表明时文件目录。

 

注:

  1. 在Manifest文件中,只可有一个Class-Path 头信息,并且每行长度不能超过72个字符长度。
  2. extensions的Manifest中也可以包含Class-Path头信息,也就是extensions可以是链状层次结构(daisy chained)。

Extension-List的例子请参考: http://java.sun.com/docs/books/tutorial/ext/basics/download.html

 

Extensions 的类加载策略

Java 的extension 框架采用委派方式加载类。当JRE需要加载一个类时,它按如下的路径顺序寻找该类:

  1. Bootstrap classes:rt.jar、i18n.jar等中的类。
  2. Installed extensions:先找java.ext.dirs路径中的类(install extensions),比如lib/ext目录下的类,然后再找download extensions。
  3. Class path:java.class.path路径下的类。

 Java 类加载策略

Java平台用委派模型来加载类。每个类加载器都有一个“父”类加载器。当其需要加载一个类时,它首先从自己开始,层层向上委托检查是否已经加载,如果检查到,直接返回该类。如果没有查到,从根加载器(bootstrap)开始,层层向下委托,尝试加载。如果加载成功,返回该类。 如果最终所有的类加载器没有加载成功,抛出ClassNotFoundException异常。

 

如下是类加载api的一些提要:

  • java.lang.ClassLoader及其子类的构造函数,在初始化时都允许指定一个“父”类加载器。如果没有指定,JVM会用system类加载器作为其默认的“父”类加载器。
  • loadClass()方法执行如下任务:
    1. 如果这个类已经被加载,直接返回该类。
    2. 否则,委托让其“父”类加载器去加载该类(即调用父类的loadClass()方法)。
    3. 如此递归,如果“父”及其“祖先”类加载器加载该类失败,调用findClass()去查找并加载该类。
  • findClass() 方法在其“父”及其“祖先”类加载器加载该类失败的情况下,才会自己查找该类。你可能要覆盖这个方法,如果你的应用需要开发使用自己的加载器的话。
  • java.net.URLClassLoader作为extensions和其他jar文件的基础加载器类。它覆盖了java.lang.ClassLoader的findClass()方法,从而实现从1个或多个URL去查找类。

附: ClassLoader.loadClass()的源码

protected synchronized Class<?> loadClass(String name, boolean resolve)
	throws ClassNotFoundException
    {
	// First, check if the class has already been loaded 
	// Returns the class with the given binary name if this
	// loader has been recorded by the Java virtual machine as an initiating
	// loader of a class with that binary name.  Otherwise
	// null is returned.
	Class c = findLoadedClass(name);
	if (c == null) {
	    try {
		if (parent != null) {
		    c = parent.loadClass(name, false);
		} else {
		    c = findBootstrapClass0(name);
		}
	    } catch (ClassNotFoundException e) {
	        // If still not found, then invoke findClass in order
	        // to find the class.
	        c = findClass(name);
	    }
	}
	if (resolve) {
	    resolveClass(c);
	}
	return c;
    }

 

类加载和java命令

  1. 执行Java的命令时,如果指定-classpath或-cp命令行参数的值,会覆盖环境变量CLASSPATH的值。
  2. -jar 选项:如果通过java -jar 来运行一个可执行的jar包,这当前jar包会覆盖CLASSPATH的值。换句话说,-jar 后面所跟的jar包的优先级别最高,如果指定了-jar选项,所有环境变量和命令行制定的搜索路径都将被忽略。JVM APPClassloader将只会以jar包为搜索范围。

你可能感兴趣的:(java,C++,c,ext,C#)