通过JDBC了解服务提供者框架

通过JDBC了解服务提供者框架

这篇博客引用了一些《Effective Java》书中的内容

一.服务提供者框架组成及作用

  • 服务接口(Server Interface)
  • 提供者注册API(Service Registration API)
  • 服务提供者接口(Service Provider Interface)
  • 服务访问API(Service Acess API)

作用:

  • 服务接口:定义了提供哪些服务
  • 提供者注册API:注册提供者
  • 服务提供者接口:返回一个实现了服务接口的类的实例
  • 服务访问API:在注册过的所有提供者中寻找合适的提供者,然后调用该提供者的方法,返回一个实现了服务接口的对象

    //服务接口
    public interface Service{
        //...服务所调用的方法声明
    }
    //服务提供者接口
    public interface Provider{
        //返回服务接口的实现类的实例
        Service newService();
    }
    public class Services{
        private Services() {}
        private static final Map<String, Provider> providers = 
                new ConcurrentHasMap<String, Provider>();
        //服务提供者注册API
        public static void registerProvider(String name, Provider p) {
            providers.put(name, p)
        }
        //服务访问API
        public static Service getService(String name) {
            Provider p = providers.get(name);
            if(p != null)
                return p.newService();
        }
    }
    
    //服务接口的实现类
    public class ServiceImpl implements Service{
        //实现接口中的所有服务
    }
    //服务提供者接口的实现类
    public class ProviderImpl implements Provider{
        //返回服务接口的实现类的实例
        public Service newService() {
            return new ServiceImpl();
        }
    }
    

对应的UML图如下:

二.简单分析JDBC

首先看源码(删减部分代码)

public interface Connection  extends Wrapper, AutoCloseable {

    Statement createStatement() throws SQLException;

    PreparedStatement prepareStatement(String sql)
        throws SQLException;
}

上述代码为java.sql.Connection的部分源码,在服务提供者框架中,扮演着Service(服务接口)的角色。

public interface Driver {
    //这个方法返回java.sql.Connection(服务接口)
    Connection connect(String url, java.util.Properties info)
        throws SQLException;
}

上述代码为java.sql.Driver的部分源码,在服务提供者框架中,扮演者Provider(服务提供者接口)的角色

public class DriverManager {

    private final static CopyOnWriteArrayList<DriverInfo> 
        registeredDrivers = new CopyOnWriteArrayList<>();

    private DriverManager(){}

    //服务提供者注册API
    public static synchronized void registerDriver(java.sql.Driver driver,
            DriverAction da)
        throws SQLException {
        if(driver != null) {
            registeredDrivers.addIfAbsent(new DriverInfo(driver, da));
        } else {

            throw new NullPointerException();
        }

    //服务访问API
    public static Connection getConnection(String url)
        throws SQLException {

        java.util.Properties info = new java.util.Properties();
        return (getConnection(url, info, Reflection.getCallerClass()));
    }
}

所谓的JDBC驱动包,其实就是对服务接口和服务提供者接口的实现

public class NonRegisteringDriver implements java.sql.Driver {

    public java.sql.Connection connect(String url, Properties info) 
        throws SQLException {
            ...
    }
}

//这里的Driver是com.mysql.cj.jdbc.Driver
public class Driver extends NonRegisteringDriver 
    implements java.sql.Driver {

    static {
        try {
            java.sql.DriverManager.registerDriver(new Driver());
        } catch (SQLException E) {
            throw new RuntimeException("Can't register driver!");
        }
    }
}

上述就是对服务提供者接口的实现。 使用JDBC的第一步就是使用类加载器加载com.mysql.cj.jdbc.Driver的原因,就是调用静态代码块,注册服务提供者接口的实现类

public interface JdbcConnection extends java.sql.Connection...{
    ...
}

public class ConnectionImpl implements JdbcConnection {
    ...//实现java.sql.Connection接口
}

上述代码为服务接口的实现类

简单的画一个类图

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值