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. [转]RabbitMQ入门教程(概念,应用场景,安装,使用)

    原文地址:https://www.jianshu.com/p/dae5bbed39b1 RabbitMQ 简介 RabbitMQ是一个在AMQP(Advanced Message Queuing Pr ...

  2. AI金融知识自学偏量化方向-了解不同类型的机器学习2

    有监督学习 vs 无监督学习 迭代和评估 偏差方差权衡 结合有监督学习和无监督学习(半监督学习)

  3. vue.js是什么

    Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的 渐进式框架.与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计.Vue 的核心库只关注视图层,并且非常容易学习, ...

  4. (转载)Redis5.0重量级特性Stream尝鲜

    转 导读:Redis5.0最新重点推出了Stream的支持,给众多架构师在消息队列方面带来了新的选择,特别是Redis粉丝们绝对是一个福音.那么Redis的Stream有哪些特别的功能?跟kafka有 ...

  5. hadoop 在centos中的搭建

    总体思路,准备主从服务器,配置主服务器可以无密码SSH登录从服务器,解压安装JDK,解压安装Hadoop,配置hdfs.mapreduce等主从关系. 1.环境,3台CentOS7,64位,Hadoo ...

  6. irc

    https://www.irccloud.com/ webchat.freenode.net http://blog.csdn.net/wcc526/article/details/16993069 ...

  7. 2 salt-masterless架构

    minion无master的使用用法 需要更改minion配置文件的三个配置项 [root@linux-node2 ~]# vim /etc/salt/minion file_client: loca ...

  8. [Tensorflow] Cookbook - Object Classification based on CIFAR-10

    Convolutional Neural Networks (CNNs) are responsible for the major breakthroughs in image recognitio ...

  9. [Node.js] 04 - Event and Callback

    回调函数 回调函数在完成任务后就会被调用,Node 使用了大量的回调函数,Node 所有 API 都支持回调函数. 异步读取文件的回调函数: var fs = require("fs&quo ...

  10. 06建造者模式Builder

    一.什么是建造者模式 Builder模式也叫建造者模式或者生成器模式, 是由GoF提出的23种设计模式中的一种. Builder模式是一种对象创建型模式之一,用来 隐藏复合对象的创建过程,它把复合对象 ...