双亲委派模型&动态生成Java类
启动类加载器(Bootstrap Class-Loader),加载 jre/lib 下面的 jar 文件,如 rt.jar。
修改核心类库可以使用下面的命令:
# 指定新的 bootclasspath,替换 java.* 包的内部实现
java -Xbootclasspath:<your_boot_classpath> your_App
# a 意味着 append,将指定目录添加到 bootclasspath 后面
java -Xbootclasspath/a:<your_dir> your_App
# p 意味着 prepend,将指定目录添加到 bootclasspath 前面
java -Xbootclasspath/p:<your_dir> your_App
我们可以使用public final ClassLoader getParent();来获取父类加载器,但是在通常的JDK/JRE实现中,扩展类加载器getParent()都只能返回null。
扩展类加载器(Extension or Ext Class-Loader),负责加载我们放到jre/lib/ext/目录下的jar包。这就是所谓的extension机制。该目录可以通过设置“java.ext.dirs”来覆盖。
java -Djava.ext.dirs=your_ext_dir HelloWorld
应用类加载器(Application or App Class-Loader),就是加载我们最熟悉的 classpath 的内容。这里有一个容易混淆的概念,系统(System)类加载器,通常来说,其默认就是 JDK 内建的应用类加载器,但是它同样是可能修改的,比如:
java -Djava.system.class.loader=com.yourcorp.YourClassLoader HelloWorld
对于一个普通的 Java 动态代理,其实现过程可以简化成为:
- 提供一个基础的接口,作为被调用类型(com.mycorp.HelloImpl)和代理类之间的统一入口,如 com.mycorp.Hello。
- 实现InvocationHandler,对代理对象方法的调用,会被分派到其 invoke 方法来真正实现动作。
- 通过 Proxy 类,调用其 newProxyInstanc方法,生成一个实现了相应基础接口的代理类实例,可以看下面的方法签名。