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

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

2.实例代码

直接上代码吧
1) 接口
package com.ctrip.lzyan.test.element.serviceloader.sample1;

public interface Command {

    public void execute(); 

}

2) 实现类

package com.ctrip.lzyan.test.element.serviceloader.sample1;

public class StartCommand implements Command {

    public void execute() {
System.out.println("start....");
} }
package com.ctrip.lzyan.test.element.serviceloader.sample1;

public class ShutdownCommand implements Command {

    @Override
public void execute() {
System.out.println("shutdown....");
} }

3) 配置文件

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

4) 测试类

package com.ctrip.lzyan.test.element.serviceloader.sample1;

import java.util.ServiceLoader;

public class CommandTester {

    public static void main(String[] args) {
ServiceLoader<Command> serviceLoader = ServiceLoader.load(Command.class);
for(Command command:serviceLoader){
command.execute();
}
} }

5) 编译执行

mvn clean install -Dmaven.test.skip=true
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的代 码:
    ArrayList<Command> getCommands() {
ServiceLoader<Command> loader = ServiceLoader.load(Command.class);
Iterator<Command> iterator = loader.iterator();
ArrayList<Command> rc = new ArrayList<Command>();
boolean done = false;
while (!done) {
try {
if( iterator.hasNext() ) {
rc.add(iterator.next());
} else {
done = true;
}
} catch (ServiceConfigurationError e) {
// it's ok, some commands may not load if their dependencies
// are not available.
}
}
return rc;
}

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

回头看一下runTask方法:
    protected void runTask(List<String> tokens) throws Exception {  

        // Process task token
if (tokens.size() > 0) {
Command command=null;
String taskToken = (String)tokens.remove(0); for( Command c: getCommands() ) {
if( taskToken.equals(c.getName()) ) {
command = c;
break;
}
}
if( command == null ) {
if (taskToken.equals("help")) {
printHelp();
} else {
printHelp();
}
} if( command!=null ) {
command.setCommandContext(context);
command.execute(tokens);
}
} else {
printHelp();
} }

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

问题:

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

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

转自:

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. 关于Python打包运行的一些思路

    需求 本地开发python django应用程序,然后放到生产环境运行.使用了tensorflow,手动安装包很麻烦.生产环境不能联网,不能使用 pip freeze. 思路: 使用docker,直接 ...

  2. Top useful .Net extension methods

    Special extension methods were released in C# 3.0. Developers have continuously been looking for way ...

  3. Go语言_iota用法

    一.介绍 iota,特殊常量,可以认为是一个可以被编译器修改的常量. 在每一个const关键字出现时,被重置为0,然后再下一个const出现之前,每出现一次iota,其所代表的数字会自动增加1. io ...

  4. Zookeeper系列四:Zookeeper实现分布式锁、Zookeeper实现配置中心

    一.Zookeeper实现分布式锁 分布式锁主要用于在分布式环境中保证数据的一致性. 包括跨进程.跨机器.跨网络导致共享资源不一致的问题. 1. 分布式锁的实现思路 说明: 这种实现会有一个缺点,即当 ...

  5. Git -- 使用GitHub

    我们一直用GitHub作为免费的远程仓库,如果是个人的开源项目,放到GitHub上是完全没有问题的.其实GitHub还是一个开源协作社区,通过GitHub,既可以让别人参与你的开源项目,也可以参与别人 ...

  6. [AWS] Deploy react project on EC2

    如何在aws部署项目 申请到亚马逊AWS免费账户后,我们可以拥有很多的免费云服务产品项目,其中包括: EC2云服务器. Amazon S3存储. Amazon RDS数据库. Amazon Cloud ...

  7. 揭秘IT人才特点:中美印日四国程序员比较

    不知道大家是否已经看过这篇文章,感觉比较客观.   来自:http://www.programmer.com.cn/282/        最近以裁判的身份参加了公司举办的编程大赛,发现高手云集,对公 ...

  8. rar压缩find查找到的文件

    find . -name 'CMakeLists.txt' | xargs /d/Program\ Files/WinRAR/rar.exe a -r ./out.rar $ ------------ ...

  9. CentOS7.5 Linux搭建全文检索--Solr7.4.0单机服务

    一.Solr安装环境 1.官方参考文档 Solr教程参考指南:http://lucene.apache.org/solr/guide/7_4/solr-tutorial.html 2.Solr运行环境 ...

  10. Media Session API 为当前正在播放的视频,音频,提供元数据来自定义媒体通知

    google 文档 https://developers.google.cn/web/updates/2017/02/media-session <html lang="zh-cmn- ...