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. oracle 函数to_char(数据,'FM999,999,999,999,990.00') 格式化数据(转)

    转载自:https://blog.csdn.net/fupengyao/article/details/52778565 遇到了oracle 取数格式问题,这里记一下 我们通常在做数据算数后,会想要让 ...

  2. uboot i2c 操作函数记录

    I2C 在 u-boot 上面,有直接操作 I2C 的函数 // drivers/i2c/i2c_core.c // 设置在哪个 I2C bus 上工作 276 int i2c_set_bus_num ...

  3. 机器学习&深度学习基础(目录)

    从业这么久了,做了很多项目,一直对机器学习的基础课程鄙视已久,现在回头看来,系统的基础知识整理对我现在思路的整理很有利,写完这个基础篇,开始把AI+cv的也总结完,然后把这么多年做的项目再写好总结. ...

  4. 命令查看linux主机配置

    查看cpu: # 总核数 = 物理CPU个数 X 每颗物理CPU的核数 # 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数 # 查看物理CPU个数 cat /proc/cp ...

  5. WebApi XML,Json格式自定义,IEnumerable<T>,ArrayOf

    global.ascx中application-start() GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSeri ...

  6. BigDecimal提供了8种舍入方式

    BigDecimal提供了8种舍入方式 1.ROUND_UP:舍入远离零的舍入模式.在丢弃非零部分之前始终增加数字(始终对非零舍弃部分前面的数字加1).注意,此舍入模式始终不会减少计算值的大小. 2. ...

  7. SpringMVC Jsp include 错误404 不显示页面

    一.问题描述: 1. 新建了taglibs.jsp存放jstl标签库和 jsp建站基本变量ctx 和basPath 如下  (位置WEB-INF\common) <%@ page import= ...

  8. MTK 修改默认时区

    首先介绍应用程序修改 : AlarmManager mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); mA ...

  9. [Object Tracking] Overview of algorithms for Object Tracking

    From: https://www.zhihu.com/question/26493945 可以载入史册的知乎贴 目标跟踪之NIUBILITY的相关滤波 - 专注于分享目标跟踪中非常高效快速的相关滤波 ...

  10. [Hinton] Neural Networks for Machine Learning - RNN

    Link: Neural Networks for Machine Learning - 多伦多大学 Link: Hinton的CSC321课程笔记 补充: 参见cs231n 2017版本,ppt写得 ...