故事
首页
指南
  • Java
  • Python
  • Linux
  • 前端
  • Docker
  • 实践
  • 折腾
  • 分类
  • 标签
  • 归档
壁纸 (opens new window)
GitHub (opens new window)
首页
指南
  • Java
  • Python
  • Linux
  • 前端
  • Docker
  • 实践
  • 折腾
  • 分类
  • 标签
  • 归档
壁纸 (opens new window)
GitHub (opens new window)
  • Java基础

    • String类的深入学习
    • HashMap源码学习
    • Java8新特性回顾
  • Java框架

    • POI事件模式解析并读取Excel文件数据
    • SpringMVC的执行流程源码分析
    • netty+websocket实现即时通讯功能
    • 分布式定时任务解决方案xxl-job
    • spring-session实现集群session共享
    • springcloud优雅下线服务
    • Java日志发展历史
    • Mybatis Generator配置
    • JavaSPI机制和Springboot自动装配原理
      • SPI机制
        • JAVA SPI的规范要素
        • 场景
        • 总结
        • 简单实例
      • springboot的自动装配
        • 总结
    • Spring Cloud Config接入
    • 使用spring validation进行参数校验
    • dubbo接口超时配置
    • ConfigurationProperties注解
    • EasyExcel导出excel
  • 中间件

    • 分布式锁解决方案
    • 关于消息中间件MQ
    • kafka学习记录
    • kakfa实践
    • kakfa重复消费问题处理
  • 数据库

    • MySql索引
    • SQL优化学习
    • Otter实现数据全量增量同步
  • 开发工具

    • Maven的生命周期
    • nexus无法下载依赖的问题记录
  • 其他

    • linux服务器安装OpenOffice踩坑
    • POI踩坑-zip file is closed
    • OpenJDK没有jstack等命令的解决办法
    • 微信小程序加密数据对称解密工具类
    • mybatis的classpath配置导致的jar包读取问题
    • feign请求导致的用户ip获取问题记录
    • ribbon刷新服务列表间隔和canal的坑
    • cpu占用率高排查思路
  • 简介
  • java
  • Java框架
storyxc
2022-04-13

JavaSPI机制和Springboot自动装配原理

# JavaSPI机制和Springboot自动装配原理

# SPI机制

SPI(Service Provider Interface)是一种服务发现机制,提供服务接口,且为该接口寻找服务的实现。

从Java6开始引入,是一种基于ClassLoader类加载器发现并加载服务的机制。

标准的SPI构成:

  • Service:公开的接口或抽象类,定义一个抽象的功能模块
  • Service Provider:Service接口/抽象类的具体实现
  • ServiceLoader:SPI中的核心组件,负责在运行时发现并加载Service Provider

# JAVA SPI的规范要素

  • 规范的配置文件
    • 文件路径:必须要在JAR中的META-INF/services下
    • 文件名称:Service接口全限定名
    • 文件内容:Service实现类的全限定名,如果有多个,则每个类单独占一行
  • ServiceProvider必须有无参构造方法,因为要通过反射实例化
  • 保证能加载到配置文件和ServiceProvider类
    • 将jar包放到classpath下
    • jar包安装到jre的扩展目录下
    • 自定义一个ClassLoader

# 场景

SPI在JDBC中的应用:JDBC要求Driver实现类在类加载的时候将自身的实例注册到DriverManager中,从而加载数据库驱动,在SPI出现之前,加载数据库驱动时要执行Class.forName("com.mysql.jdbc.Driver"), 在SPI出现后,只需要引入对应依赖的JAR包后,ServiceLoader会自动去约定的路径下寻找需要加载的类。

# 以mysql-connector-java的jar文件为例

  • 配置文件

image-20220410224243304

  • 无参构造器

image-20220410224639940

# 总结

  • SPI提供了一种组件发现和注册的方式,可以用于各种插件、组件的灵活替换
  • 可以实现模块间解耦
  • 面向接口+配置文件+反射
  • 应用:JDBC、SLF4J。。。

# 简单实例

image-20220410231011833

image-20220410231049522

image-20220410231109810

当spi-company依赖spi-lt时运行main方法:

image-20220410231225984

当spi-company依赖spi-yd时运行main方法:

image-20220410231313507

# springboot的自动装配

自动装配,即auto-configuration,是基于引入的依赖jar包对springboot应用进行自动配置,提供自动配置的jar包通常以starter结尾,比如mybatis-spring-boot-starter等等。

springboot默认会扫描项目下所有的配置类并注入到ioc容器中,但集成到其他框架并不能直接注入。为了实现真正的auto configuration,springboot的自动装配也采用了和spi类似的设计思想:

  • 使用约定的配置文件:自动装配的配置文件为META-INF/spring.factories,文件内容为org.springframework.boot.autoconfigure.EnableAutoConfiguration=class1,class2,..classN,class是自动配置类的类名
  • 提供自动配置类的jar包中,需要提供配置文件META-INF/spring.factories
  • 使用ClassLoader的getResource和getResources方法,读取classpath中的配置文件并使用反射实例化

例如mybatis-spring-boot-starter的包结构:

image-20220410232256701

# 总结

springboot的自动装配核心流程:springboot程序启动,通过spring factories机制加载classpath下的META-INF/spring.factories文件,筛选出所有EnableAutoConfiguration的配置类,反射实例化后注入到springIOC容器中。

todo:实现一个自定义springboot-starter

编辑 (opens new window)
#springboot
上次更新: 2022/04/21, 18:12:24
Mybatis Generator配置
Spring Cloud Config接入

← Mybatis Generator配置 Spring Cloud Config接入→

Theme by Vdoing | Copyright © 2019-2023 story | 豫ICP备19046036号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式