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删除数据库中的所有表

    连接:http://linben.blog.51cto.com/6205951/1293619 1.先禁用数据库中所有的约束 select 'alter table ' || table_name | ...

  2. 使用C#+Linq+SQL快速开发业务

    C#开发桌面程序的效率确实很高,今天就来总结下如何使用C#+Linq+SQL快速开发一个新的业务系统. Linq是微软官方的轻量级的ORM工具,使用它结合SQL可以快速的生成实体类,再通过Linq操作 ...

  3. 短信文本查找之 MATCH 与 LIKE

    最近发现原生短信应用的搜索功能的搜索结果十分不准确,所以就开始追踪代码: 关于android searchview的使用这里就不描述了,简单说一下,android的searchVIew是支持autoc ...

  4. Sql Server 数据类型与 C# 数据类型对照

    Sql Server 数据类型与 C# 数据类型对照 已验证类型(Sql Server 2012 & Visual Studio 2013) Sql Server C# 简写 bigint S ...

  5. tensflow自定义损失函数

    tensflow 不仅支持经典的损失函数,还可以优化任意的自定义损失函数. 预测商品销量时,如果预测值比真实销量大,商家损失的是生产商品的成本:如果预测值比真实值小,损失的则是商品的利润. 比如如果一 ...

  6. 试一下Markdown

    Markdown 没想到博客园居然能够有markdown这样的写法了,以前觉得有自定义CSS已经非常不错了,现在居然加入Markdown,太值得称赞了.国内的博客系统,应该首屈一指了. 强调 你要走, ...

  7. mysql8.0驱动问题

    <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</a ...

  8. 8月10日CSS总结

    1.三角形光标转换 CSS: .one{ width: 0;­­ height: 0; border-top: 100px solid #000; border-right:100px solid t ...

  9. 网络通信协议八之(传输层)TCP协议详解

    传输层协议 分段是为了提高传输效率,封装是指给每个数据段添加一个编号 端到端的传输是逻辑上的端到端,并不是真正意义上的发送方某层与接收方某层之间的传输 IP协议只是保证数据报文发送到目的地,为主机之间 ...

  10. datagrid---columns列

    { field:"city", //字段名,从后台传来的要一致 title:"城市",//列的标题文字. width:,//列的宽度 formatter:fun ...