在上一篇class文件和执行引擎这部分中,用户能参与的部分不是太多。class格式、加载、链接、解释执行都是虚拟机规定的,能通过程序操作的有:类加载器和字节码生成。下面看看几个相关的精彩案例:
Tomcat的加载器架构
java web服务器通常有多个自定义类,来解决这些问题
- 不同web项目间的类库隔离
- 不同web项目间类库的共享
- java编写的服务器本身和项目类库间的隔离,保证安全
- /common 可以被tomcat和所有web项目共享
- /server 只能被tomcat使用
- /shared tomcat 不可见,能被web项目共享
- 项目的/WebApp/WEB-INF 当前web项目自己可见
上面灰色的三个是JDK提供的。按照双亲委派模型的规则,很清晰的看到这个架构是怎么实现上面说的目标的。其中WebApp类加载器可能有多个,一个web项目一个;Jsp类加载器也有多个,一个JSP文件一个,它的出现是为了被丢弃:当JSP文件发生变动时,丢弃它并新建一个加载器替换它,实现JSP文件的HotSwap功能。
OSGI的类加载架构
OSGI的加载器模型不再是简单树形模型,而是更为复杂的、运行时确定的网状模型。
它的这种加载器间的关系只是一种概念上的依赖关系,例如模块A依赖模块B,模块B发布了自己为B。运行时模块A发现依赖了B,仅在找到了发布B的模块之后,将依赖的加载任务交给发布B的模块的加载器。
字节码生成和动态代理
Java中有很多字节码生成的类库,javac就是最为原始的一个。动态代理就是一个相对简单的应用。动态代理相比静态代理而言,优势不是在于少些的那点代码,而是在原始类和接口未知的时候就确定了代理的内容。当原始和代理脱离关系后,代理就可以被灵活的用到各种场景中!其实质就是按照字节码格式和规则拼装字节码,最终被类加载器加载,然后实例化成对象使用。