java SPI机制的初步学习
2017-04-14 00:00
701 查看
java SPI机制的初步学习
1. SPI机制
SPI的全名为Service Provider Interface.大多数开发人员可能不熟悉,因为这个是针对厂商或者插件的。在java.util.ServiceLoader的文档里有比较详细的介绍。简单的总结下java spi机制的思想。我们系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块的方案,xml解析模块、jdbc模块的方案等。面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。 java spi就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。
2. SPI具体约定
java spi的具体约定为:当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。 基于这样一个约定就能很好的找到服务接口的实现类,而不需要再代码里制定。jdk提供服务实现查找的一个工具类:java.util.ServiceLoader
入门实验:
tspi这个为接口包
alogger这个为ALogger实现tspi的实现包
blogger这个为BLogger实现tspi的实现包
tspiTest这个项目为测试包
把这4个做成4个单独的项目
(1) tspi项目(接口项目)
新建一个Logger的接口分别有debug,info,warn,error这4个方法。
在来个工具类LoggerFactory来获取Logger,(这里就使用了spi机制)
这个项目到包成jar 由于没有什么依赖,pom.xml基本是默认内容。
(2)alogger项目(A实现项目)
这里有个ALogger为Logger的实现类:
在资源目录下创建 ”META-INF/Services目录” 在这个目录下,新建一个为 “com.imddy.tspi.Logger” 的文件(接口全限定名称),其内容为 “com.imddy.alogger.ALogger” (实现类全限定名称)
pom.xml中需要依赖接口项目,这个项目也是打包成一个jar包。
(3)blogger项目(B实现项目)
这里有个BLogger为Logger的实现类:
在资源目录下创建 ”META-INF/Services目录” 在这个目录下,新建一个为 “com.imddy.tspi.Logger” 的文件(接口全限定名称),其内容为 “com.imddy.blogger.BLogger” (实现类全限定名称)
pom.xml中需要依赖接口项目,这个项目也是打包成一个jar包。
(4)tspiTest项目 (测试项目)
pom.xml中的依赖添加:
写代码只需要接口项目依赖,运行是有pathclass有A实现就使用A实现,有B实现就使用B实现。
测试代码如下:
运行效果如图:
1. SPI机制
SPI的全名为Service Provider Interface.大多数开发人员可能不熟悉,因为这个是针对厂商或者插件的。在java.util.ServiceLoader的文档里有比较详细的介绍。简单的总结下java spi机制的思想。我们系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块的方案,xml解析模块、jdbc模块的方案等。面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。 java spi就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。
2. SPI具体约定
java spi的具体约定为:当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。 基于这样一个约定就能很好的找到服务接口的实现类,而不需要再代码里制定。jdk提供服务实现查找的一个工具类:java.util.ServiceLoader
入门实验:
tspi这个为接口包
alogger这个为ALogger实现tspi的实现包
blogger这个为BLogger实现tspi的实现包
tspiTest这个项目为测试包
把这4个做成4个单独的项目
(1) tspi项目(接口项目)
新建一个Logger的接口分别有debug,info,warn,error这4个方法。
package com.imddy.tspi; public interface Logger { public void debug(String logger); public void info(String logger); public void warn(String logger); public void error(String logger); }
在来个工具类LoggerFactory来获取Logger,(这里就使用了spi机制)
package com.imddy.tspi; import java.util.Iterator; import java.util.ServiceLoader; public class LoggerFactory { public LoggerFactory() { } public static Logger getLogger() { Logger logger = null; ServiceLoader<Logger> serviceLoader = ServiceLoader.load(Logger.class); Iterator<Logger> loggers = serviceLoader.iterator(); if (loggers.hasNext()) { logger = loggers.next(); } return logger; } }
这个项目到包成jar 由于没有什么依赖,pom.xml基本是默认内容。
(2)alogger项目(A实现项目)
这里有个ALogger为Logger的实现类:
package com.imddy.alogger; import com.imddy.tspi.Logger; public class ALogger implements Logger{ public ALogger() { } public void debug(String logger) { System.out.println("ALogger-->debug: " + logger); } public void info(String logger) { System.out.println("ALogger-->info: " + logger); } public void warn(String logger) { System.out.println("ALogger-->warn: " + logger); } public void error(String logger) { System.out.println("ALogger-->error: " + logger); } }
在资源目录下创建 ”META-INF/Services目录” 在这个目录下,新建一个为 “com.imddy.tspi.Logger” 的文件(接口全限定名称),其内容为 “com.imddy.alogger.ALogger” (实现类全限定名称)
pom.xml中需要依赖接口项目,这个项目也是打包成一个jar包。
(3)blogger项目(B实现项目)
这里有个BLogger为Logger的实现类:
package com.imddy.blogger; import com.imddy.tspi.Logger; public class BLogger implements Logger{ public BLogger() { } public void debug(String logger) { System.out.println("BLogger-->debug: " + logger); } public void info(String logger) { System.out.println("BLogger-->info: " + logger); } public void warn(String logger) { System.out.println("BLogger-->warn: " + logger); } public void error(String logger) { System.out.println("BLogger-->error: " + logger); } }
在资源目录下创建 ”META-INF/Services目录” 在这个目录下,新建一个为 “com.imddy.tspi.Logger” 的文件(接口全限定名称),其内容为 “com.imddy.blogger.BLogger” (实现类全限定名称)
pom.xml中需要依赖接口项目,这个项目也是打包成一个jar包。
(4)tspiTest项目 (测试项目)
pom.xml中的依赖添加:
<dependency> <groupId>com.imddy</groupId> <artifactId>tspi</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!-- <dependency> <groupId>com.imddy</groupId> <artifactId>alogger</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> --> <dependency> <groupId>com.imddy</groupId> <artifactId>blogger</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
写代码只需要接口项目依赖,运行是有pathclass有A实现就使用A实现,有B实现就使用B实现。
测试代码如下:
package com.imddy.tspiTest; import com.imddy.tspi.Logger; import com.imddy.tspi.LoggerFactory; public class App { private static Logger logger = LoggerFactory.getLogger(); public static void main(String[] args) { logger.debug("this is use debug... "); logger.info("this is use info... "); logger.warn("this is use warn... "); logger.error("this is use error... "); } }
运行效果如图:
相关文章推荐
- 0032 Java学习笔记-类加载机制-初步
- 初步学习Java并发中的锁机制
- JavaSPI机制学习笔记
- Java和dubbo中的SPI机制学习
- java序列化机制学习
- java学习之反射机制
- Java学习笔记_身份验证机制
- Java学习笔记_身份验证机制
- Java 学习笔记 (13) - 基本内存分析 和 垃圾回收机制
- JAVA学习一运行机制
- java线程初步学习
- Java 学习笔记 (9) - Java 事件机制 内部匿名类的应用
- java学习 java 的继承机制 暑假第三天
- JAVA的反射机制--学习心得
- Java基础学习(02Java语言的特点、机制与规范)
- JAVA TCP/IP 同步传递消息 初步 学习
- Java学习笔记_身份验证机制
- 学习心得:Java为什么支持反射机制?
- JAVA序列化机制学习札记
- 学java初步,现在不知如何学习