Java平台扩展机制#2:Services
来源:互联网 发布:手机淘宝下载安装 编辑:程序博客网 时间:2024/06/01 09:48
上一篇文章已经聊完了Java平台在jar包级别的扩展,现在来看看另一个在接口级别上的扩展方案。
ServiceLoader
这个方案里面,有三个东东要先搞清楚,Service,ServiceProvider,ServiceLoader。
A service is a well-known set of interfaces and (usually abstract) classes. A service provider is a specific implementation of a service.
而ServiceLoader就是用来找到提供了Service的ServiceProvider,有点依赖注入的意思。ServiceLoader如何找到ServiceProvider呢?
A service provider is identified by placing a provider-configuration file in the resource directory META-INF/services. The file's name is the fully-qualified binary name of the service's type. The file contains a list of fully-qualified binary names of concrete provider classes, one per line.
ServiceProvider可以理解为是第三方提供的jar包,ServiceLoader就是用来按照约定找出jar包中具体提供服务的Class。
这其实就是一个面向接口编程的思想。talk is cheap,下面还是举个栗子,直观一些。
举个栗子
The DriverManager methods getConnection and getDrivers have been enhanced to support the Java Standard Edition Service Provider mechanism. JDBC 4.0 Drivers must include the file META-INF/services/java.sql.Driver. This file contains the name of the JDBC drivers implementation of java.sql.Driver. For example, to load the my.sql.Driver class, the META-INF/services/java.sql.Driver file would contain the entry:my.sql.Driver
接下来看看使用DriverManager的方式。
public Connection getConnection() throws SQLException { Connection conn = null; Properties connectionProps = new Properties(); connectionProps.put("user", this.userName); connectionProps.put("password", this.password); if (this.dbms.equals("mysql")) { conn = DriverManager.getConnection( "jdbc:" + this.dbms + "://" + this.serverName + ":" + this.portNumber + "/", connectionProps); } else if (this.dbms.equals("derby")) { conn = DriverManager.getConnection( "jdbc:" + this.dbms + ":" + this.dbName + ";create=true", connectionProps); } System.out.println("Connected to database"); return conn;}
冲进DriverManager内部看看它是怎么使用ServiceLoader的。
/** * 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"); }
初始化的就时候就去loadInitialDrivers,
private static void loadInitialDrivers() { ... ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class); ...}
到MySQL官网下载JDBC驱动来瞧瞧,
java.sql.Driver文件里面的内容是
com.mysql.jdbc.Drivercom.mysql.fabric.jdbc.FabricMySQLDriver
其他配置点
我把调用了ServiceLoader.load去需找ServiceProvider的地方称为配置点,因为在这些地方我们可以去订制我们的Service。除了上面DriverManager的栗子,我们再来看看其他一些配置点。
- Annotation Processor?这是个Service,Lombok就是用它来实现的,只是我还没找着这个Service对应的配置点是在哪,囧。
参考资料
- http://docs.oracle.com/javase/tutorial/ext/basics/spi.html
- http://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html
- Java平台扩展机制#2:Services
- Java平台扩展机制#1:Extensions
- Java平台扩展机制#3:SLF4J怪招
- Java 动态代理机制分析及扩展,第 2 部分
- Java 动态代理机制分析及扩展,第 2 部分
- Java 动态代理机制分析和扩展,第 2 部分
- Web Services平台
- Web Services 平台元素
- java平台-不断扩展的计算平台
- Java 动态代理机制分析及扩展
- Java 动态代理机制分析及扩展
- Java 动态代理机制分析及扩展
- Java 动态代理机制分析及扩展
- Java动态代理机制及扩展
- Java 动态代理机制分析及扩展
- Java 动态代理机制分析及扩展
- Java 动态代理机制分析及扩展
- Java动态代理机制分析及扩展
- Metasploit2: tcp port 111 – rpcbind
- hdu 2795 线段树--点更新
- 请确保此文件可访问并且是一个有效的程序集或COM组件
- 定:定时执行下面的代码 20140729
- c++公用体union、结构体struct内存分配问题
- Java平台扩展机制#2:Services
- 面向程序员的设计模式 ——GoF《设计模式》读书总结(零)
- cluster-overview
- ACM
- 救基友记3——三维数组记录BFS
- Pots(BFS)
- Cocos2d-x 3.x开发 叠加触摸的问题
- 详细解析cocos2dx 3.x的事件中的点击事件
- 可以把PDF批量转换成PPT的PDF转ppt转换器