组件化框架设计之Java SPI机制(三)

本文深入探讨了Java SPI(Service Provider Interface)机制,并通过jdbc设计的实例阐述了其在组件化框架设计中的重要性。SPI允许服务接口与实现解耦,增强了程序的可扩展性。文章还提供了Android高级技术资源,包括架构师进阶教程、BAT面试题等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

11/12号文档资料已全面更新!;《【阿里P7】移动互联网架构师高级教程+BAT面试题》,点击下方链接前往领取:
【阿里P7】移动互联网架构师进阶高级教程+BAT面试题
本篇文章将从深入理解java SPI机制来介绍组件化框架设计:

一、SPI机制定义

SPI机制(Service Provider Interface)其实源自服务提供者框架(Service Provider Framework,参考【EffectiveJava】page6),是一种将服务接口与服务实现分离以达到解耦、大大提升了程序可扩展性的机制。引入服务提供者就是引入了spi接口的实现者,通过本地的注册发现获取到具体的实现类,轻松可插拔。

二、典型实例:jdbc的设计

通常各大厂商(如Mysql、Oracle)会根据一个统一的规范(java.sql.Driver)开发各自的驱动实现逻辑。客户端使用jdbc时不需要去改变代码,直接引入不同的spi接口服务即可。
Mysql的则是com.mysql.jdbc.Drive,Oracle则是oracle.jdbc.driver.OracleDriver。

伪代码如下:

	//注:从jdbc4.0之后无需这个操作,spi机制会自动找到相关的驱动实现
	//Class.forName(driver);
	
	//1.getConnection()方法,连接MySQL数据库。有可能注册了多个Driver,这里通过遍历成功连接后返回。
	con = DriverManager.getConnection(mysqlUrl,user,password);
	//2.创建statement类对象,用来执行SQL语句!!
	Statement statement = con.createStatement();
	//3.ResultSet类,用来存放获取的结果集!!
	ResultSet rs = statement.executeQuery(sql);

jdbc连接源码分析

  1. java.sql.DriverManager静态块初始执行,其中使用spi机制加载jdbc具体实现
 //java.sql.DriverManager.java   
 //当调用DriverManager.getConnection(..)时,static会在getConnection(..)执行之前被触发执行
    /**
     * Load the initial JDBC drivers by checking the System property
     * jdbc.properties and then use the {@code ServiceLoader} mechanism
     */
    static {
        loadInitialDrivers();
        println("JDBC DriverManager initialized");
    }

2.loadInitialDrivers()中完成了引入的数据库驱动的查找以及载入,本示例只引入了oracle厂商的mysql,我们具体看看。

//java.util.serviceLoader.java

   private static void loadInitialDrivers() {
        String drivers;
        try {
            drivers = AccessController.doPrivileged(new PrivilegedAction<String>() {
                public String run() {
                //使用系统变量方式加载
                    return System.getProperty("jdbc.drivers");
                }
            });
        } catch (Exception ex) {
            drivers = null;
        }
        //如果spi 存在将使用spi方式完成提供的Driver的加载
        // If the driver is packaged as a Service Provider, load it.
        // Get all the drivers through the classloader
        // exposed as a java.sql.Driver.class service.
        // ServiceLoader.load() replaces the sun.misc.Providers()

        AccessController.doPrivileged(new PrivilegedAction<Void>() {
            public Void run() {
//查找具体的provider,就是在META-INF/s
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值