类加载器的种类:
类加载器机制:
全盘负责委托机制
当一个ClassLoader加载一个类的时候,除非显式的使用另一个ClassLoader,该类和所有引用的类也由这个ClassLodader载入
2.双亲委派机制(父类委托机制),默认为双亲委派机制(ClassLoader的除外)
双亲委派模型的工作过程是:如果一个类加载器收到了类加载请求,它首先不会自己尝试加载这个类,而是把这个请求委派给父类加载器去完成,每个层都是如此,因此所有加载请求最终都传送给顶层的启动类加载器,只有父加载器反馈自己无法加载这个加载请求时(它的搜索范围没有找到所需的类),子加载器才会尝试自己去完成加载,双亲委派机制说简单点就是,先找父亲加载,不行再由儿子自己加载
好处
1.不会被重复加载。例如java.lang.Object类,它放在rt.jar之中,无论那个类加载器加载这个类,都会向上委派给模型的最顶端启动类加载器加载,因此Object类在程序的各个类加载器中都能保证是一个类,从而保证被加载类的唯一性,且父类已经加载了Object类子类就不需要再加载一次
2.沙箱安全机制:可以防止核心API库被随意篡改,如自定义Object类,编译不会报错, 但将不会被加载,永远是一直委托父类加载的是系统内置的Object
如何打破双亲委派
为什么要打破?
举一个最常见的例子:我们常用数据库驱动Driver接口,Driver定义在jdk当中,当其实现却是各个数据库服务商,例如,mysql的MYSQL CONNECROR,所以这就有个问题,DriverManger要加载各个Driver接口实现类,然后进行管理,但是DriverManager是由启动类加载器进行加载的,而这个启动类加载器默认值加载JAVA_HOME下面的lib,但我们真正要加载的是各个实现类,需要有系统类加载器进行加载,这个时候就需要启动类加载器委托系统类加载器去加载Driver实现类,从而破坏了双亲委派。
打破的方法:
1.自定义类加载器 ,重写loadclass方法
2.SPI(Service Provider InterFace) 服务提供接口,SPI机制绕开loadclass 方法。当前线程设定关联类加载器,加载数据库驱动用此方法
3.OSGI 热部署 热更新
Open Service Gateway Initiative,直译为“开放服务网关”,OSGi联盟给出的最新OSGi定义是The Dynamic Module System for Java,即面向Java的动态模块化系统。
热部署,就是在不停止服务运行时(或者说在不影响用户体验前提下)动态更新其服务内容,最终达到100%在线率的目标。而Java中,由于类加载机制的原因,导致一个类一旦加载进去就再也无法释放,因此,OSGi引入了基于插件的类加载机制