java9类加载器_Java9+中的服务加载器

Java的ServiceLoader(java.util.ServiceLoader,服务加载器)不是Java9中才出现的,Java6就开始使用了。这里的服务,可以简单的理解为Java接口,加载器加载的是接口的实现类(也可以说成服务是实现了接口的类)。在Java9以前主要用于实现spi机制,也就是动态加载实现类。Java9赋予了它新的功能,这篇文章简单讲一下ServiceLoader的使用。

36c6cef243336b0f5a54a265f5226544.png

面向对象编程会将how和what分开,所以有接口和实现:接口定义了what,实现阐明了how。

SPI 机制

关于spi的介绍网上能搜出来一大把,很多还讲得不错。

如果你懒得去搜,这里简单演示一下它的用法。定义了一个接口 IMovable,表示一种可以移动的特征。

package com.j11.spi;

public interface IMovable {

void move();

}

实现类可以有一个或多个。为了演示,这里实现两个:

package com.j11.spi;public class Human implements IMovable {@Overridepublic void move() {System.out.println("human steps……");}}

package com.j11.spi;public class Car implements IMovable {@Overridepublic void move() {System.out.println("Car wheels……");}}

ServiceLoader要求被加载服务的描述符文件必须在/META-INF/services目录下。创建该目录,并在该目录下创建文件com.j11.spi.IMovable,内容如下:

com.j11.spi.Humancom.j11.spi.Car

每个实现类写一行。

SPI全称Service Provider Interface,即服务提供方接口,创建一个main方法类,方法体如下:

ServiceLoader shouts = ServiceLoader.load(IMovable.class);for (IMovable s : shouts) {s.move();if (s instanceof Car) {System.out.println("match");}}

输出

human steps……Car wheels……match

IDEA 内置对spi机制的支持,如果接口和描述符不匹配则会立即警告。

9dab641872a8efa2b85a3eca3ab8ec60.png

Java9+模块对spi的支持

Java9+中,依然可以写出上面这种代码。不过显示模块化的话,可以使用provides、uses和with关键字(注意,它们和其他的模块关键字一样都不是保留字,可以用做变量名称),provides就是spi中的p。

创建一个模块,只包含服务接口和服务提供接口:

package com.j11.spi;public interface IService {String getName();void serve();void halt();}package com.j11.spi;public interface IServiceProvider {IService provide();}module service {exports com.j11.spi;}

创建模块实现接口:

package com.j11.service.impl;import com.j11.spi.IService;public class Server1 implements IService {@Overridepublic String getName() {return "s1";}@Overridepublic void serve() {System.out.println("s1 is serving");}@Overridepublic void halt() {System.out.println("s1 stopped");}}package com.j11.service.impl;import com.j11.spi.IService;public class Server2 implements IService {@Overridepublic String getName() {return "s2";}@Overridepublic void serve() {System.out.println("s2 is serving");}@Overridepublic void halt() {System.out.println("s2 stopped");}}

服务提供方实现:

package com.j11.provider.impl;import com.j11.service.impl.Server1;import com.j11.spi.IService;import com.j11.spi.IServiceProvider;public class S1Provider implements IServiceProvider {@Overridepublic IService provide() {return new Server1();}}package com.j11.provider.impl;import com.j11.service.impl.Server2;import com.j11.spi.IService;import com.j11.spi.IServiceProvider;public class S2Provider implements IServiceProvider {@Overridepublic IService provide() {return new Server2();}}

模块描述符中暴露服务,使用provides IX with Y,Z:

module provider {requires transitive service;provides com.j11.spi.IServiceProvider with com.j11.provider.impl.S1Provider, com.j11.provider.impl.S2Provider;}

最后,应用模块要使用服务,用到了uses关键字:

module customer {requires provider;uses com.j11.spi.IServiceProvider;}

启动应用:

package com.j11.spi.customer;import com.j11.spi.IService;import com.j11.spi.IServiceProvider;import java.util.ServiceLoader;public class Customer {public static void main(String[] args) {ServiceLoader sl = ServiceLoader.load(IServiceProvider.class);for (IServiceProvider provider : sl) {IService server = provider.provide();server.serve();if (server.getName().equals("s2")) {server.halt();}}}}

输出

s1 is servings2 is servings2 stopped

希望今天的内容对大家有帮助!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值