如何写自己的springboot starter?自动装配原理是什么?

官方文档地址:https://docs.spring.io/spring-boot/docs/2.6.13/reference/html/features.html#features.developing-auto-configuration

1. 不用starter有什么弊端?

  • 我们开发需要引入maven依赖,如果我们需要的依赖又有它自身所需要的依赖。我们需要同时去引入才能去使用,这种模式让我们苦不堪。例如要在项目中使用 Spring Data JPA 进行数据库操作,需要手动添加 Spring Data JPA、Hibernate、数据库驱动等相关依赖,这不仅需要开发者了解每个依赖的具体信息,还容易出现版本不兼容的问题,因为不同版本的依赖之间可能存在冲突。
  • 配置麻烦,在SSM时期,大量的配置让我们晕头转向,没有starter的自动配置功能,需要手动编写大量的配置类和配置文件来启用和配置各种功能。例如,配置 Spring Data JPA 时,需要手动配置数据源、实体管理器工厂、事务管理器等
  • 如果另一个项目也需要同时去做同样的功能,如果不用starter只能使用CV大法把之前配置的都移过来,CV有可能出错,也让项目臃肿。

针对以上缺点,starter诞生它只需要引入一个依赖,搞定!

常见的starter例如:

spring-boot-starter
spring-boot-starter-web
spring-boot-starter-test
spring-cloud-starter-alibaba-nacos-discovery
druid-spring-boot-starter

2. springboot自动装配

要想自定义一个starter就要知道springboot是怎么样自动装配bean的

2.1 核心注解:

  • @SpringBootApplication:这是一个组合注解,相当于同时使用了 @Configuration、@EnableAutoConfiguration 和 @ComponentScan 注解。它标记了主应用程序类,并告诉 Spring Boot 开始组件扫描、自动配置和装配。
  • @EnableAutoConfiguration:该注解用于启用 Spring Boot 的自动配置功能。它会根据应用程序的依赖关系和当前环境,自动注册所需的 bean。
  • @ComponentScan:该注解用于启用组件扫描,以便 Spring Boot 可以自动发现和注册标有 @Component、@Service、@Repository 和 @Controller 注解的类。
  • @ConditionalOnClass 和 @ConditionalOnMissingClass:这两个条件化注解用于根据类路径上是否存在特定的类来决定是否注册 bean。@ConditionalOnClass 在类路径上存在指定类时生效,而 @ConditionalOnMissingClass 在类路径上不存在指定类时生效。
  • @ConditionalOnBean 和 @ConditionalOnMissingBean:这两个条件化注解用于根据是否存在特定的 bean 来决定是否注册 bean。@ConditionalOnBean 在容器中存在指定的 bean 时生效,而 @ConditionalOnMissingBean 在容器中不存在指定的 bean 时生效。
  • @ConditionalOnProperty:该条件化注解用于根据配置属性的值来决定是否注册 bean。它可以根据配置文件中的属性值来决定是否启用或禁用特定的 bean。

tips: 如果官方给你的注解不够满足需求可以自己创建一个Conditional,@Conditional(value = TestCondition.class)

public class TestCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return true;
}
}

2.2 自动装配大白话

  1. springboot启动类注解@SpringBootApplication是一个组合注解 里面包含了@EnableAutoConfiguration,即开启自动装配
  2. @Import(AutoConfigurationImportSelector.class),导入AutoConfigurationImportSelector,并通过 selectImports 方法读取 META-INF/spring.factories 文件中配置的全类名

    tips: 从spring boot2.7开始,慢慢不支持META-INF/spring.factories文件了需要导入的自动配置类可以放在

    /META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  3. 并按照@ConditionalOnClass这样条件过滤的注解,如果满足条件注入bean

3. starter前知

3.1 取名该怎么样取?

spring官方文档上是这样说的 https://docs.spring.io/spring-boot/docs/2.0.0.M5/reference/htmlsingle/#boot-features-custom-starter-naming



翻译:

请确保为启动器提供合适的名称空间。不要以spring-boot作为模块名的开头,即使您使用的是不同的Maven groupId。我们可能会在将来为您自动配置的东西提供官方支持。

这是一条经验法则。假设您正在为“acme”创建一个启动器,将自动配置模块命名为acme-spring-boot-autoconfigure,将启动器命名为acme-spring-boot-starter。如果只有一个模块结合了这两个模块,那么使用acme-spring-boot-starter。

此外,如果启动器提供了配置键,请为它们使用适当的名称空间。特别是,不要在Spring Boot使用的命名空间(例如server、management、Spring等)中包含键。这些都是“我们的”,我们可能会在将来改进/修改它们,这样可能会破坏你的东西。

确保触发元数据生成,以便也为您的键提供IDE帮助。您可能需要查看生成的元数据(META-INF/spring-configuration-metadata.json),以确保正确地记录了密钥。

一般来说取名 xxx-spring-boot-starter就可以了

3.2 starter项目目录介绍

  • maven.spring-cloud-starter-alibaba-nacos-discovery

    这个是有关于maven的文件
  • additional-spring-configuration-metadata.json
{"properties": [
{
"name": "spring.cloud.loadbalancer.nacos.enabled",
"type": "java.lang.Boolean",
"defaultValue": false,
"description": "Integrate LoadBalancer or not."
}
]}

这个文件是配置元数据,很多时候我们可能会不知道这个starter有哪些是可以配置的,就可以来找这个文件,name就是属性名,defaultValue是默认值,description是描述。idea中配置文件里的补全提示也是读取这里的进行提示

  • MANIFEST.MF

    该文件包含了该 JAR 包的版本、创建人和类搜索路径等信息。
  • spring.factories

    spring.factories文件里的内容就是我们需要自启动装配的bean全路径
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure

官方tips:不要让这些类被组件扫描到

还有一些另外可能出现的键

org.springframework.boot.autoconfigure.EnableAutoConfiguration:用于自动配置类

org.springframework.context.ApplicationContextInitializer:应用上下文初始化器org.springframework.context.ApplicationListener:应用事件监听器

org.springframework.boot.SpringApplicationRunListener:应用运行监听器

org.springframework.boot.env.PropertySourceLoader:属性源加载器

org.springframework.boot.diagnostics.FailureAnalyzer:失败分析器

org.springframework.boot.env.EnvironmentPostProcessor:环境后处理器

org.springframework.boot.autoconfigure.AutoConfigurationImportFilter:自动配置导入过滤器

org.springframework.boot.autoconfigure.AutoConfigurationPackage:自动配置包

4. 实战需求来了

要实现一个starter,打印请求详细信息。

  1. 创建request-log-spring-boot-starter项目,打包方式为jar,引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope> <!-- 确保不重复引入 -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional> <!-- 生成配置元数据 -->
</dependency>
</dependencies>
  1. 创建RequestLogProperties类读取配置文件
@ConfigurationProperties(prefix = "request-log")
public class RequestLogProperties { private boolean enabled = true; // 是否启用日志
private boolean logHeaders = true; // 是否记录请求头
private boolean logBody = false; // 是否记录请求体(默认关闭,可能影响性能) public boolean isEnabled() {
return enabled;
} public void setEnabled(boolean enabled) {
this.enabled = enabled;
} public boolean isLogHeaders() {
return logHeaders;
} public void setLogHeaders(boolean logHeaders) {
this.logHeaders = logHeaders;
} public boolean isLogBody() {
return logBody;
} public void setLogBody(boolean logBody) {
this.logBody = logBody;
}
}
  1. resources下新建META-INF文件夹
  2. META-INF文件夹下新建spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.example.config.RequestLogAutoConfiguration

RequestLogAutoConfiguration类被spring.factories引入不需要@Configuration注解了

  1. 编写RequestLogAutoConfiguration类,加入条件判断
@ConditionalOnProperty(name = "request-log.enable", matchIfMissing = true)
@EnableConfigurationProperties(RequestLogProperties.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
  1. 写RequestLoggingFilter类继承OncePerRequestFilter实现doFilterInternal进行业务逻辑
  2. 完工,测试

5. 代码提交到git上了:

https://gitee.com/isyuesen/request-log/tree/main/-

如何写自己的springboot starter?自动装配原理是什么?的更多相关文章

  1. 【springboot】自动装配原理

    摘自:https://mp.weixin.qq.com/s/ZxY_AiJ1m3z1kH6juh2XHw 前言 Spring翻译为中文是"春天",的确,在某段时间内,它给Java开 ...

  2. SpringBoot启动流程分析(五):SpringBoot自动装配原理实现

    SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...

  3. springboot自动装配原理,写一个自己的start

    springboot自动装配原理 第一次使用springboot的时候,都感觉很神奇.只要加入一个maven的依赖,写几行配置,就能注入redisTemple,rabbitmqTemple等对象. 这 ...

  4. springboot自动装配原理

    最近开始学习spring源码,看各种文章的时候看到了springboot自动装配实现原理.用自己的话简单概括下. 首先打开一个基本的springboot项目,点进去@SpringBootApplica ...

  5. 深入理解SpringBoot之自动装配

    SpringBoot的自动装配是拆箱即用的基础,也是微服务化的前提.其实它并不那么神秘,我在这之前已经写过最基本的实现了,大家可以参考这篇文章.这次主要的议题是,来看看它是怎么样实现的,我们透过源代码 ...

  6. 【Springboot】Springboot自动装配原理

    1.核心注解就是 EnableAutoConfiguration  该注解会激活SpringBoot的自动装配功能: 代码如下: @Target(ElementType.TYPE) @Retentio ...

  7. SpringBoot | 2.1 SpringBoot自动装配原理

    @ 目录 前言 1. 引入配置文件与配置绑定 @ImportResource @ConfigurationProperties 1.1 @ConfigurationProperties + @Enab ...

  8. SpringBoot自动装配原理解析

    本文包含:SpringBoot的自动配置原理及如何自定义SpringBootStar等 我们知道,在使用SpringBoot的时候,我们只需要如下方式即可直接启动一个Web程序: @SpringBoo ...

  9. Spring Boot系列(二):Spring Boot自动装配原理解析

    一.Spring Boot整合第三方组件(Redis为例) 1.加依赖 <!--redis--> <dependency> <groupId>org.springf ...

  10. Eureka 系列(03)Spring Cloud 自动装配原理

    Eureka 系列(03)Spring Cloud 自动装配原理 [TOC] 0. Spring Cloud 系列目录 - Eureka 篇 本文主要是分析 Spring Cloud 是如何整合 Eu ...

随机推荐

  1. 【Java 温故而知新系列】基础知识-01 概述

    1.什么是Java Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了 C++里难以理解的多继承. 指针等概念,因此Java语言具有功能强大和简单易 用两个特征.Java语言作为 ...

  2. 16. C++快速入门--模板和Concept

    待修改 1 定义模板 1.1 模板形参 模板参数 模板可以有两种参数, 一种是类型参数, 一种是非类型参数 这两种参数可以同时存在, 非类型参数 的类型 可以是 模板类型形参 template < ...

  3. ABC 384(A~F)

    期末周的第二把网瘾,vp了一把abc.这把打得还是比较舒服的,做出了A~E.但最后两道题还是出得太慢了(一道思路太慢,一道调试太慢).什么时候能够在赛时做出F题呢qwq... ABC 这场abc的AB ...

  4. C#/.NET/.NET Core技术前沿周刊 | 第 21 期(2025年1.6-1.12)

    前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录.追踪C#/.NET/.NET Core领域.生态的每周最新.最实用.最有价值的技术文章.社区动态.优质项目和学习资源等. ...

  5. linux:搭建 WordPress 个人站点

    参考:链接 介绍 WordPress 是一款使用 PHP 语言开发的博客平台,您可使用通过 WordPress 搭建属于个人的博客平台.本文以 CentOS 6.5 操作系统为例,手动搭建 WordP ...

  6. [ARC 058 - E]Iroha and Haiku

    传送门 解题步骤 首先可以发现题目范围非常小,尤其是\(X,Y,Z\),所以考虑类似状压.数位dp.双向搜索等算法. 官方题解中给的是数位dp,那我这里就讲讲状压了 对于\(N \leq 40\),很 ...

  7. 去除小程序scroll-view产生的横向滚动条

    <template> <view class="page-demo"> <scroll-view class="scrool-more&qu ...

  8. dart变量类型详解

    1==> 三个单引号的作用 String Str = ''' qijqowjdo 哈哈嘿嘿黑 '''; print(Str); 这样使用三个单引号,输出来换行:方便我们观看而已哈 2==> ...

  9. 更换Linux系统镜像源

    更换Linux系统镜像源 切换镜像源通常是为了提高软件包下载的速度和稳定性.以下是CentOS 7切换镜像源的一般步骤: 一.安装wget(如果尚未安装) 首先,需要确保系统中安装了wget工具,因为 ...

  10. Atcoder ABC389E Square Price 题解 [ 蓝 ] [ 二分 ] [ 贪心 ]

    Square Price:垃圾卡精度,垃圾卡精度,垃圾卡精度,傻逼出题人,傻逼出题人,傻逼出题人,傻逼出题人,傻逼出题人,傻逼出题人,傻逼出题人. 把 ll 改 __int128 前 WA*22,改 ...