1. 几个不错的关于ServiceLoader的文章,大家可以先参考一下

1) http://www.myexception.cn/program/1355384.html 这篇的后面的问题分析不错

2.实例代码

直接上代码吧
1) 接口
  1. package com.ctrip.lzyan.test.element.serviceloader.sample1;
  2.  
  3. public interface Command {
  4.  
  5. public void execute();
  6.  
  7. }

2) 实现类

  1. package com.ctrip.lzyan.test.element.serviceloader.sample1;
  2.  
  3. public class StartCommand implements Command {
  4.  
  5. public void execute() {
  6. System.out.println("start....");
  7. }
  8.  
  9. }
  1. package com.ctrip.lzyan.test.element.serviceloader.sample1;
  2.  
  3. public class ShutdownCommand implements Command {
  4.  
  5. @Override
  6. public void execute() {
  7. System.out.println("shutdown....");
  8. }
  9.  
  10. }

3) 配置文件

由于是使用maven构建的项目,所以就在resources下面新建目录META-INF/services,在该目录下新建文件com.ctrip.lzyan.test.element.serviceloader.sample1.Command, 即完整的接口名
文件内容如下:
  1. com.ctrip.lzyan.test.element.serviceloader.sample1.StartCommand
  2. com.ctrip.lzyan.test.element.serviceloader.sample1.ShutdownCommand

4) 测试类

  1. package com.ctrip.lzyan.test.element.serviceloader.sample1;
  2.  
  3. import java.util.ServiceLoader;
  4.  
  5. public class CommandTester {
  6.  
  7. public static void main(String[] args) {
  8. ServiceLoader<Command> serviceLoader = ServiceLoader.load(Command.class);
  9. for(Command command:serviceLoader){
  10. command.execute();
  11. }
  12. }
  13.  
  14. }

5) 编译执行

  1. mvn clean install -Dmaven.test.skip=true
  2. mvn exec:java -Dexec.mainClass=com.ctrip.lzyan.test.element.serviceloader.sample1.CommandTester

3.activemq中的使用实例

第一次接触到ServiceLoader就是在activemq的启动过程中,所以学习了一下
activemq broker启动时,调用的是org.apache.activemq.console.command.ShellCommand 类,ShellCommand.main调用runTask,runTask会调用getCommands方法,下面看一下getCommands的代 码:
  1. ArrayList<Command> getCommands() {
  2. ServiceLoader<Command> loader = ServiceLoader.load(Command.class);
  3. Iterator<Command> iterator = loader.iterator();
  4. ArrayList<Command> rc = new ArrayList<Command>();
  5. boolean done = false;
  6. while (!done) {
  7. try {
  8. if( iterator.hasNext() ) {
  9. rc.add(iterator.next());
  10. } else {
  11. done = true;
  12. }
  13. } catch (ServiceConfigurationError e) {
  14. // it's ok, some commands may not load if their dependencies
  15. // are not available.
  16. }
  17. }
  18. return rc;
  19. }

ServiceLoader会读取META-INF/services/org.apache.activemq.console.command.Command 配置的类并在迭代时将其实例化。

回头看一下runTask方法:
  1. protected void runTask(List<String> tokens) throws Exception {
  2.  
  3. // Process task token
  4. if (tokens.size() > 0) {
  5. Command command=null;
  6. String taskToken = (String)tokens.remove(0);
  7.  
  8. for( Command c: getCommands() ) {
  9. if( taskToken.equals(c.getName()) ) {
  10. command = c;
  11. break;
  12. }
  13. }
  14. if( command == null ) {
  15. if (taskToken.equals("help")) {
  16. printHelp();
  17. } else {
  18. printHelp();
  19. }
  20. }
  21.  
  22. if( command!=null ) {
  23. command.setCommandContext(context);
  24. command.execute(tokens);
  25. }
  26. } else {
  27. printHelp();
  28. }
  29.  
  30. }

该方法根据类名选择Command,并执行。

问题:

1.配置文件为什么要放在META-INF/services下面?
ServiceLoader.PREFIX定义如下:

  1. private static final String PREFIX = "META-INF/services/";
  1. 但是如果ServiceLoaderload时提供Classloader,则可以从其他的目录读取。
  1. ServiceLoader.LazyIterator.nextService中实例化,即load的结果迭代时才会被实例化。
  2.  

转自:

http://blog.csdn.net/unei66/article/details/47051017

Java ServiceLoader(SPI)学习的更多相关文章

  1. Java之SPI机制

    之前开阿里的HSF框架,里面用到了Java的SPI机制,今天闲暇的时候去了解了一下,通过写博客来记录一下 SPI的全名为Service Provider Interface,我对于该机制的理解是为接口 ...

  2. java 的SPI机制

    今天看到spring mvc 使用Java Validation Api(JSR-303)进行校验,需要加载一个 其具体实现(比如Hibernate Validator), 本来没有什么问题,但是突然 ...

  3. Java的SPI机制与简单的示例

    一.SPI机制 这里先说下SPI的一个概念,SPI英文为Service Provider Interface单从字面可以理解为Service提供者接口,正如从SPI的名字去理解SPI就是Service ...

  4. java的spi 的简单应用

    1.什么是java的spi SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制. 目前有不少框架用它来做服务的扩展发现, 简单来说,它就是一 ...

  5. JAVA的SPI简单应用

    最近在研究dubbo时,发现了JAVA的SPI特性.SPI的全名为Service Provider Interface,是JDK内置的一种服务发现机制. 具体实现: 1.定义一个接口 public i ...

  6. Java的spi介绍和简单应用

    1.什么是java的spi SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制. 目前有不少框架用它来做服务的扩展发现, 简单来说,它就是一 ...

  7. 深入理解 Java 中 SPI 机制

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/vpy5DJ-hhn0iOyp747oL5A作者:姜柱 SPI(Service Provider ...

  8. JAVA中SPI机制

    之前研究dubbo的时候就很好奇,里面各种扩展机制,期间也看过很多关于SPI的机制,今日有缘再度看到有文章总结,故记录一下, 首先了解一下 JAVA中SPI简单的用法 可参考这篇文章,https:// ...

  9. java的spi(Service Provider Interface)机制及源码(java8)

    1.什么是java的spi spi 全称为 service provider interface 即 服务提供接口,用来作为服务的扩展发现.在运行时动态添加接口的实现,是对接口的实现类的创建管理. 2 ...

随机推荐

  1. 海量数据中找top K专题

    1. 10亿个数中找出最大的1000个数 这种题目就是分治+堆排序. 为啥分治?因为数太多了,全部加载进内存不够用,所以分配到多台机器中,或者多个文件中,但具体分成多少份,视情况而定,只要保证满足内存 ...

  2. android开发(46) 使用 textview实现文字的阴影效果,浮雕效果

    前言 最近看到一些文字的阴影效果很有意思,尝试了下,形成本文.“平面效果“是我们平时常见的平面的样子.“阴影效果”会给人一种凸起的感觉.浮雕效果会给一种雕刻“凹陷”的感觉. 演示效果图 方法 使用 t ...

  3. hdoj:2035

    #include <iostream> using namespace std; int main() { long a, b; && b != ) { long resu ...

  4. No service of type Factory<LoggingManagerInternal> available in ProjectScopeService

    导入GitHub上下载的项目时报错 No service of type Factory<LoggingManagerInternal> available in ProjectScope ...

  5. WPF Input Validation Using MVVM

    Data validation is a key part in WPF.Validation is used to alert the user that the data he entered i ...

  6. MAC下Myeclipse SVN插件安装

    1.下载SVN插件包:http://download.csdn.net/detail/frankyanchen/4512899 2.在myeclipse文件夹下创建一个文件夹为svntool并复制下载 ...

  7. offsetHeight,clientHeight,scrollHeight,offsetY等属性的理解

    el.offsetHeight = height + padding + border(滚动条是在边框内的,自然也包括在内) el.clientHeight = 可视化看到的高度 (就是content ...

  8. U3D常用题

    最先执行的方法是:1.(激活时的初始化代码)Awake,2.Start.3.Update[FixUpdate.LateUpdate].4.(渲染模块)OnGUI.5.再向后,就是卸载模块(TearDo ...

  9. C#模拟登录后请求查询

    需求是这样子的,想开发一个外挂程序,能够抓取别的系统的数据,从而实现数据验证. 比如这样一个界面: 使用Chrome浏览器分析http请求和响应过程以及页面的html代码,发现这是一个ajax请求,于 ...

  10. Django----From组件

    Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 1.创建Form类 from django.f ...