01_Jdk自带SPI

【SPI的设计目标】

面向对象的设计里,模块之间是基于接口编程,模块之间不对实现类进行硬编码。

一旦代码里设计具体的实现类,就违法了可插拔的原则,如果需要替代一种实现,就要修改代码。

为了实现在模块装配的时候,不在模块里面写死代码,就需要一种服务发现机制。

Java spi 就是提供了这样一种机制:

为某个接口寻找服务实现的机制。有点类似IOC的思想,就是讲装配的控制权转移到代码之外。

【SPI的具体约定】

当服务的提供者(provider),提供了一个接口多种实现时,

一般会在jar包的META-INF/services目录下,创建该接口的同名文件。

该文件里面的内容就是该服务的具体实现类的名称。

当外部加载这个模块的时候,就能通过该jar包的META-INF/services/里面的配置文件得到具体的实现类名,并加载实例化,完成模块的装配。

【工厂目录结构】 

【service相关的接口和类】

package com.jdk.spi.service;

/**
 *  Service类
 * Created by HigginCui on 2018/9/5.
 */
public interface AnimalService {

    void eat();

}



package com.jdk.spi.service.impl;
import com.jdk.spi.service.AnimalService;
/**
 *  Service实现类CatServiceImpl
 * Created by HigginCui on 2018/9/5.
 */
public class CatServiceImpl implements AnimalService{
    public void eat() {
        System.out.println("猫爱吃鱼...");
    }
}



package com.jdk.spi.service.impl;
import com.jdk.spi.service.AnimalService;
/**
 *  Service实现类CatServiceImpl
 * Created by HigginCui on 2018/9/5.
 */
public class DogServiceImpl implements AnimalService {
    public void eat() {
        System.out.println("狗爱啃骨头...");
    }
}

【com.jdk.spi.service.AnimalService文件中的内容】

com.jdk.spi.service.impl.DogServiceImpl

【JDKSpiTest类】

package com.jdk.spi;

import com.jdk.spi.service.AnimalService;

import java.util.ServiceLoader;

/**
 * Created by HigginCui on 2018/9/5.
 */
public class JdkSpiTest {

    public static void main(String[] args) {
        ServiceLoader<AnimalService> loader = ServiceLoader.load(AnimalService.class);
        for (AnimalService animalService:loader){
            animalService.eat();
        }
    }
}

【运行结果】

原文地址:https://www.cnblogs.com/HigginCui/p/9589470.html