有哪些类加载器
引导类加载器(Bootstrap ClassLoader)
c++编写,无法直接引用,主要负责加载jre/lib目录下的核心类库
扩展类加载器(Extension ClassLoader)
主要负责加载jre/lib/ext目录下的标准扩展类库
应用类加载器(Application ClassLoader)
主要负责加载CLASSPATH环境变量下的类,应用中的类基本是用的这个类加载器
自定义类加载器(Custom ClassLoader)
可以通过继承java.lang.ClassLoader,覆盖相应的方法来创建一个自定义的类加载器
双亲委派模型(Parents Delegation Model )
什么是双亲委派模型
当一个类加载器收到类加载任务时,它首先会给其父类加载器去尝试加载,只有当父类加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去加载。这种层次模型被称为双亲委派模型。
为什么要使用双新委派机制
1、为了保证安全。开发者无法变更核心类库,因为核心类库都是由bootstrap classloader进行加载的。
2、可以保证类的唯一性。父类加载器加载过的类,子类加载器不会重复加载。
双亲委派机制的具体流程
1、类装载子系统(ClassLoader Sub-System)在收到JAVA虚拟机加载类的指令后,会把这个加载任务先交给Application ClassLoader;
2、Application ClassLoader委派给父类Extension ClassLoader去尝试加载;
3、Extension ClassLoader又会把这个请求委派给Bootstrap ClassLoader;
4、如果Bootstrap ClassLoader会在jre/lib下面未找到所需类,就会让Extension ClassLoader尝试加载;
5、如果Extension ClassLoader会在jre/lib/ext下面未找到所需类,就会让Application ClassLoader尝试加载;
6、Application ClassLoader如果加载失败,就会使用自定义加载器去尝试加载;
7、如果都失败了,就会报ClassNotFoundException异常.
破坏双亲委派模型
此部分参考:什么是双亲委派模型?违背双亲委派模型? - Dgvt - 博客园
双亲委派模型因为不是一个强制性的约束模型,某些情况下会破坏这种约束模型:
1、重写了ClassLoader的loadClass()方法
自定义ClassLoader时,如果重写loadClass()没有委派父类去加载,就会破坏这种模型,最佳实践是重写findClass()。
2、SPI(Service Provider Interface,服务提供者接口)
Java提供了很多SPI,允许第三方为这些接口提供实现,常见的SPI有JDBC、JNDI、JCE、JAXB和JBI等。
简单的说,SPI是在Java核心类库中定义,是通过Bootstrap类加载器加载的,如果需要用到具体实现类,则会通过线程上下文类加载器(Thread Context ClassLoader)去加载,这个加载器通Thread.currentThread().getContextClassLoader()来获得,默认返回的就是应用程序类加载器。这样就破坏了
3、OSGi(Open Service Gateway Initiative,开放服务网关协议)
这个东西目前没用过,就暂不叙述了。