SpringBoot的SPI机制源码解析

SpringBoot的SPI机制源码解析

什么是SPI?

SPI全称为Service Provider Interface(Service Provider Interface),是JDK内置的一种面向接口编程的机制。SPI的作用就是为这些接口寻找实现类。具体来说,当服务接口的实现类存在于classpath路径下的第三方jar包中,可以通过SPI机制自动发现并加载实现类,而无需在代码中显示的指定对象的创建。

SpringBoot中的SPI

SpringBoot中的SPI是基于JDK的SPI机制进行二次开发后的一种轻量级的SPI实现。在SpringBoot中,我们可以通过扩展SPI接口的方式轻松地实现插件扩展,在实现上还提供了比JDK SPI更灵活、易用和便捷的方式。

在SpringBoot中,插件的实现有两种方式:

  1. 实现指定的接口
  2. 使用@Service注解

SPI原理

1.在SPI机制中,服务接口部分称作Service,而具体实现服务的类称为Service Provider。
2.可以使用Java提供的SPI进行动态扩展,所以在使用SPI服务的过程中,需要编写一个服务接口,在服务提供者中编写该接口的实现类,并在服务配置文件中配置实现类的全路径地址。
3.在代码中可以使用ServiceLoader进行服务加载。

SpringBoot中的SPI注解扫描

SpringBoot在版本2.1后为我们提供了一个很方便的工具类用于自动侦测classpath下所有的SPI实现类,即SPI自动配置机制。

SpringBoot通过@EnableAutoConfiguration注解自动侦测classpath下所有的auto-configuration包以及META-INF/spring.factories文件。spring.factories文件内部存放当前应用需要启动的配置类列表。而配置类中可以使用@Conditional注解来控制当前应用装载此配置类。

SpringBoot处理SPI的过程

SpringBoot将SPI进行了二次封装,对Spring的ApplicationContext进行包装。其流程如下:

  1. SpringBoot创建BeanFactory实例,并注册相关的BeanDefinition
  2. SpringBoot创建ApplicationContext并使用BeanFactory作为其内部beanFactory
  3. SpringBoot启动ApplicationContext
  4. 扫描SPI注解
  5. 注册注解标注的SPI服务
  6. 启动初始化

两个示例

示例一:实现指定的接口

1.创建一个SPI接口:

public interface DemoService {
    String sayHello(String name);
}

2.编写DemoServiceImpl实现DemoService:

public class DemoServiceImpl implements DemoService {
    @Override
    public String sayHello(String name) {
        return "Hello, " + name + "!";
    }
}

3.在classpath下创建/META-INF/services/com.example.demo.DemoService,编写实现类的全路径名称:

com.example.demo.impl.DemoServiceImpl

4.在代码中使用ServiceLoader进行服务加载:

ServiceLoader<DemoService> serviceLoader = ServiceLoader.load(DemoService.class);
for (DemoService demoService : serviceLoader) {
    System.out.println(demoService.sayHello("world"));
}

输出结果为:Hello, world!

示例二:使用@Service注解

1.编写API接口:

public interface ApiService {
    String sayHello(String name);
}

2.编写实现类:

@Service
public class ApiServiceImpl implements ApiService{
    @Override
    public String sayHello(String name) {
        return "Hello, " + name + "!";
    }
}

3.在启动类中使用@ComponentScan注解,指定扫描com.example.demo包:

@SpringBootApplication
@ComponentScan("com.example.demo")
public class SpiApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpiApplication.class, args);
    }
}

4.使用@Autowired注解进行注入

@RestController
@RequestMapping("/api")
public class ApiController {
    @Autowired
    private ApiService apiService;
    @GetMapping("/hello/{name}")
    public String sayHello(@PathVariable String name){
        return apiService.sayHello(name);
    }
}

5.访问:http://localhost:8080/api/hello/world

输出结果为:Hello, world!

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot的SPI机制源码解析 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • Flex与.NET互操作 使用FileReference+HttpHandler实现文件上传/下载

    Flex与.NET互操作 使用FileReference+HttpHandler实现文件上传/下载 概述 本文主要介绍如何通过Flex和.NET相互配合,实现文件上传/下载。 在介绍具体步骤之前,先简单介绍FileReference和HttpHandler。 FileReference是Flex中处理文件上传/下载的类,使用FileReference类可以实…

    Java 2023年6月15日
    00
  • 数据库中经常用到的操作和管理数据库的语句总结

    下面是数据库中经常用到的操作和管理数据库的语句总结的攻略。 数据库的操作 创建数据库 创建数据库的语句如下: CREATE DATABASE db_name; 其中,db_name 为数据库的名称。在执行此命令时,数据库的名称必须是唯一的。 删除数据库 删除数据库的语句如下: DROP DATABASE db_name; 其中,db_name 为要删除的数据…

    Java 2023年6月15日
    00
  • BaseJDBC和CRUDDAO的写法实例代码

    恩,关于“BaseJDBC和CRUDDAO的写法实例代码”的完整攻略,下面是我准备的详细讲解: 1. 什么是BaseJDBC和CRUDDAO? BaseJDBC是一种基于JDBC的框架,可以简化JDBC的使用,在开发过程中提升开发效率; CRUDDAO(即CRUD DAO)是一个数据访问对象(DAO)的通用接口,可以对任意类型的实体类型进行简单的CRUD操作…

    Java 2023年6月16日
    00
  • java中List集合及其实现类的方法详解

    Java中List集合及其实现类的方法详解 什么是List集合? List集合是Java中最常用的集合之一,它可以存储有序、可重复的数据。 List实现类 Java中常见的List实现类有3种: ArrayList LinkedList Vector 其中,Vector常用于多线程并发访问的场景中,由于其性能较慢,因此本文不再赘述。下面详细讲解ArrayLi…

    Java 2023年5月18日
    00
  • Java date format时间格式化操作示例

    当我们在Java中操作日期和时间相关业务时,经常需要进行时间格式化的操作,这时候就需要用到Java的Date和SimpleDateFormat类来进行转化和格式化。下面就是Java date format时间格式化操作示例的完整攻略。 步骤1:导入相关类库 在进行Java时间格式化操作前,需要先导入相关的类库。 import java.util.Date; …

    Java 2023年5月26日
    00
  • 基于spring-security 401 403错误自定义处理方案

    基于Spring Security的401和403错误自定义处理方案 介绍 Spring Security是一个强大的安全框架,它提供了许多用于身份验证、授权和保护Web应用程序的功能。当用户未被授权或未经过身份验证时,应用程序可能会响应401未经授权或403禁止访问的错误。在这种情况下,Spring Security提供了一种非常好的方法来自定义处理这些错…

    Java 2023年5月20日
    00
  • Java基于Dijkstra算法实现校园导游程序

    Java基于Dijkstra算法实现校园导游程序攻略 1. 确定算法 首先,我们需要确定使用什么算法来实现校园导游程序,此处我们选择使用Dijkstra算法。 Dijkstra算法是一种用于带权图的单源最短路径算法,可以帮助我们找到两点之间的最短路径。在本程序中,我们需要将所有景点看作节点,将各个景点之间的距离看作边权,应用Dijkstra算法求解距离最短的…

    Java 2023年5月19日
    00
  • Java 栈与队列超详细分析讲解

    《Java 栈与队列超详细分析讲解》是一篇介绍Java中栈与队列数据结构的文章,以下为该文章的详细攻略: 一、栈的介绍 1.1 栈的定义 栈是一种后进先出(LIFO)的数据结构。栈只允许在栈顶进行插入和删除操作,因此它是一个不可复用的数据结构。 1.2 栈的应用 栈在计算机科学中有广泛的应用,包括函数调用、表达式求解、内存管理等方面。 1.3 Java中栈的…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部