应用
SPI
**ServiceLoader.load(Driver.class)是Java提供加载spi的接口 **
common-logging Apache的日志门面接口
它提供了一个接口供其他日志组件实现org.apache.commons.logging.LogFactory 这里以Spring Boot的demo作为例子 用slf4j做日志管理 当我们启动一个application 我们会先去加载SpringApplication.class 从而加载到它的静态块
我们只关注重点方法getFactory() debug进去会走到这里 通过spi机制 会直接去读最终利用spi拿到这个SLF4JLogFactory去实现这个org.apache.commons.logging.LogFactory日志接口
JDBC
jdbc4.0以前,开发人员还需要基于Class.forName("xxx")的方式来装载驱动,jdbc4也基于spi的机制来发现驱动提供商了,可以通过META-INF/services/java.sql.Driver文件里指定实现类的方式来暴露驱动提供
//4.0以前 拿数据库连接
Class.forName("com.mysql.jdbc.Driver");//初始化class(不是实例化) 加载static块
Connection con = DriverManager.getConnection(url,user,psw);
复制代码
//4.0以后 拿数据库连接
Connection con = DriverManager.getConnection(url,user,psw);
复制代码
开始分析 这里我们使用mysql的驱动 mysql-connector-java.jar
首先DriverManager有这么段静态代码static {
loadInitialDrivers();
println("JDBC DriverManager initialized");
}
复制代码
进入loadInitialDrivers 重要代码如下
ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
Iterator<Driver> driversIterator = loadedDrivers.iterator();
while(driversIterator.hasNext()) {
driversIterator.next();
}
复制代码
使用spi获取driver的实现 这里也会初始化Driver.class 从而调用
DriverManager加载mysql的驱动实现 具体内部代码有兴趣可以自己看看 待补充
动态代理
待补充
加密
待补充
记 可以有两个一样权限包名的class文件 如果去复制一个String然后修改到一样相同权限包名下 由于双亲委派机制 最终被加载的类还是rt.jar包下的