• JAVA使用ServiceLoader加载服务


    JAVA使用ServiceLoader加载服务

    https://blog.csdn.net/jianggujin/article/details/81030983

    serviceLoader就是spi的一种实现,spi服务的提供者接口也就是spi service provider  interface

    主要是创建一个接口让第三方框架去实现,比如jdbc.driver这个可以被mysql,oracle,SQLServer去实现

    还有像日志logger,有slf4j

    版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/jianggujin/article/details/81030983
    ServiceLoader是SPI的是一种实现,所谓SPI,即Service Provider Interface,用于一些服务提供给第三方实现或者扩展,可以增强框架的扩展或者替换一些组件。
    其实关于ServiceLoader,我们平时虽然很少用到,但是却在背后为我们做了很多事情,最常见的就是JDBC的操作了,相信大家对DriverManager类并不陌生,我们可以通过该类加载驱动并获得数据库连接,在这个类中其实就用到了ServiceLoader。

    private static void loadInitialDrivers() {
    String drivers;
    try {
    drivers = AccessController.doPrivileged(new PrivilegedAction<String>() {
    public String run() {
    return System.getProperty("jdbc.drivers");
    }
    });
    } catch (Exception ex) {
    drivers = null;
    }
    // If the driver is packaged as a Service Provider, load it.
    // Get all the drivers through the classloader
    // exposed as a java.sql.Driver.class service.
    // ServiceLoader.load() replaces the sun.misc.Providers()

    AccessController.doPrivileged(new PrivilegedAction<Void>() {
    public Void run() {

    ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
    Iterator<Driver> driversIterator = loadedDrivers.iterator();

    /* Load these drivers, so that they can be instantiated.
    * It may be the case that the driver class may not be there
    * i.e. there may be a packaged driver with the service class
    * as implementation of java.sql.Driver but the actual class
    * may be missing. In that case a java.util.ServiceConfigurationError
    * will be thrown at runtime by the VM trying to locate
    * and load the service.
    *
    * Adding a try catch block to catch those runtime errors
    * if driver not available in classpath but it's
    * packaged as service and that service is there in classpath.
    */
    try{
    while(driversIterator.hasNext()) {
    driversIterator.next();
    }
    } catch(Throwable t) {
    // Do nothing
    }
    return null;
    }
    });

    println("DriverManager.initialize: jdbc.drivers = " + drivers);

    if (drivers == null || drivers.equals("")) {
    return;
    }
    String[] driversList = drivers.split(":");
    println("number of Drivers:" + driversList.length);
    for (String aDriver : driversList) {
    try {
    println("DriverManager.Initialize: loading " + aDriver);
    Class.forName(aDriver, true,
    ClassLoader.getSystemClassLoader());
    } catch (Exception ex) {
    println("DriverManager.Initialize: load failed: " + ex);
    }
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    接下来我们就还看看如何使用ServiceLoader,假设我们需要一个日志的服务,那么首先我们需要定义一个服务的接口

    package com.jinggujin.service;

    public interface LogService {
    void log(String msg);
    }
    1
    2
    3
    4
    5
    针对这个服务我们再来提供一个实现

    package com.jinggujin.service;

    public class DefaultLogService implements LogService {

    @Override
    public void log(String msg) {
    System.out.println(msg);
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    好了下面我们需要提供我们的服务,我们需要在META-INF中添加services文件夹,然后在该文件夹中创建一个文件,文件名为服务接口的全限定类名,那么这里完整的文件路径应为:META-INF/services/com.jinggujin.service.LogService,最后我们需要在该文件中添加服务实现的全限定类名,一行数据一个实现全限定类名,文件内容如下:

    com.jinggujin.service.DefaultLogService
    1
    准备工作已经完成,我们就来使用ServiceLoader加载我们提供的服务。

    package test;

    import java.util.ServiceLoader;

    import org.junit.Test;

    import com.jinggujin.service.LogService;

    public class ServiceLoaderTest {
    @Test
    public void test() {
    ServiceLoader<LogService> loader = ServiceLoader.load(LogService.class);

    for (LogService service : loader) {
    System.out.println(service.getClass());
    }
    }
    }
    ---------------------
    作者:蒋固金
    来源:CSDN
    原文:https://blog.csdn.net/jianggujin/article/details/81030983
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    关于阿里JSON的方法使用
    Xcode自带Git的使用
    IOS学习随笔
    python站点配置相关
    Kingfisher基本入门介绍
    Swift Package Manager使用
    swift中json编码解码
    Weapon项目笔记
    wxj的图片
    类似西瓜视频、抖音的自动播放库
  • 原文地址:https://www.cnblogs.com/handsome1013/p/9946855.html
Copyright © 2020-2023  润新知