java-spi开发

SPI(Service Provide Interface)即服务提供接口规范,其功能是为了实现可插拔的服务提供,比如javax的validator框架就是借此实现的,java只是定义接口规范,具体实现方之一由hibernate提供。

参考

名词解释

Service Implementer: 服务的实现
Service Provide: 服务的提供
Service Interface: 服务的接口

开发流程

  • 定义服务接口(工程exchange-rate-api)

package com.baeldung.rate.spi;

import com.baeldung.rate.api.QuoteManager;

public interface ExchangeRateProvider {
    QuoteManager create();
}
  • 服务实现(工程exchange-rate-impl)

package com.baeldung.rate.impl;

import com.baeldung.rate.api.QuoteManager;
import com.baeldung.rate.spi.ExchangeRateProvider;

public class YahooFinanceExchangeRateProvider implements ExchangeRateProvider {
    @Override
    public QuoteManager create() {
        return new YahooQuoteManagerImpl();
    }
}
  • 服务的提供或发布(工程exchange-rate-impl)

在META-INF/service目录下定义服务接口文件com.baeldung.rate.spi.ExchangeRateProvider,内容为服务实现com.baeldung.rate.impl.YahooFinanceExchangeRateProvider


image.png
com.baeldung.rate.impl.YahooFinanceExchangeRateProvider
  • 服务调用

通过ServiceLoader.load()去加载调用

package com.baeldung.rate;

import com.baeldung.rate.exception.ProviderNotFoundException;
import com.baeldung.rate.spi.ExchangeRateProvider;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;

public class ExchangeRate {

    private static final String DEFAULT_PROVIDER = "com.baeldung.rate.spi.YahooFinanceExchangeRateProvider";

    public static List providers() {
        List services = new ArrayList<>();
        ServiceLoader loader = ServiceLoader.load(ExchangeRateProvider.class);
        loader.forEach(exchangeRateProvider -> {
            services.add(exchangeRateProvider);
        });
        return services;
    }

    public static ExchangeRateProvider provider() {
        return provider(DEFAULT_PROVIDER);
    }

    private static ExchangeRateProvider provider(String providerName) {
        ServiceLoader loader = ServiceLoader.load(ExchangeRateProvider.class);
        Iterator it = loader.iterator();
        while (it.hasNext()) {
            ExchangeRateProvider provider = it.next();
            if (providerName.equals(provider.getClass().getName())) {
                return provider;
            }
        }
        throw new ProviderNotFoundException("Exchange Rate provider " + providerName + " not found");
    }
}

你可能感兴趣的:(java-spi开发)