【SpringBoot学习笔记 五】Spring Boot自定义starter场景启动器

简介: 【SpringBoot学习笔记 五】Spring Boot自定义starter场景启动器

上篇Blog我们学习了SpringBoot是如何实现自动配置的,通过@Configuration的全注解配置方式和Spring Factories 发现机制自动将组件注入到容器,然后依据配置绑定,确定组件的属性值该是多少,实现了全自动的实现方式,不用我们再操心。在第一篇Blog中我们就提到过场景启动器,那么本篇Blog结合SpringBoot自动配置以及前面学的yaml配置文件等知识来自己实现一个自定义的场景启动器。

starter基本概念

我们再回顾下starter的概念:starter 是 SpringBoot 中一种非常重要的机制,它可以繁杂的配置统一集成到 starter 中,我们只需要通过 maven 将 starter 依赖引入到项目中,SpringBoot 就能自动扫描并加载相应的默认配置。starter 的出现让开发人员从繁琐的框架配置中解放出来,将更多的精力专注于业务逻辑的开发,极大的提高了开发效率。在一些特殊情况下,我们也可以将一些通用功能封装成自定义的 starter 进行使用

命名规范

SpringBoot 提供的 starter 以 spring-boot-starter-xxx 的形式命名。为了与 SpringBoot 生态提供的 starter 进行区分,官方建议第三方开发者或技术(例如 Druid、Mybatis 等等)厂商自定义的 starter 使用 xxx-spring-boot-starter 的形式命名,例如 mybatis-spring-boot-starter、druid-spring-boot-starter 等等

模块规范

Spring Boot 官方建议我们在自定义 starter 时,创建两个 Module :autoConfigure Modulestarter Module,其中 starter Module 依赖于 autoConfigure Module。当然,这只是 Spring Boot 官方的建议,并不是硬性规定,若不需要自动配置代码和依赖项目分离,我们也可以将它们组合到同一个 Module 里

自定义starter步骤

自定义 starter 可以分为以下 7 步:创建工程—》添加 POM 依赖—》定义 propertie 类—》定义 Service 类–》定义自动配置类—》创建 spring.factories文件—》构建 starter,接下来我们按照步骤实现一遍

1 创建工程

在IDEA中新建一个空项目

填写项目信息:tml-spring-boot-starter

创建第一个模块:tml-spring-boot-starter

创建第二个模块:tml-spring-boot-starter-autoconfiguration

两个模块都按照如下选项创建:

两个模块选择好后如下:

创建完后项目界面如下:

2 添加 POM 依赖

tml-spring-boot-starter的 pom.xml 中添加以下代码,将 tml-spring-boot-starter-autoconfiguration 作为其依赖项

<!--添加自动配置模块为其依赖-->
     <dependency>
         <groupId>com.example</groupId>
         <artifactId>tml-spring-boot-starter-autoconfiguration</artifactId>
         <version>0.0.1-SNAPSHOT</version>
     </dependency>

3 定义 propertie 类

在 tml-spring-boot-starter-autoconfiguration 的properties 包中,创建一个实体类:PersonProperties,通过它来映射配置信息

package com.example.tmlspringbootstarterautoconfiguration.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
/**
 * 实体类,用来映射配置信息
 */
@Data
@ConfigurationProperties(prefix = "person")
@PropertySource(value = "classpath:application.properties")
public class PersonProperties {
    private String prefix;
    private String suffix;
}

4 定义 Service 类

在tml-spring-boot-starter-autoconfiguration 的 services包中,创建一个 Service 类:PersonService,供其他项目使用

package com.example.tmlspringbootstarterautoconfiguration.services;
import com.example.tmlspringbootstarterautoconfiguration.properties.PersonProperties;
import javax.annotation.Resource;
public class PersonService {
    @Resource
    PersonProperties personProperties;
    public String sayHello(String userName) {
        return personProperties.getPrefix() + userName + personProperties.getSuffix();
    }
}

5 定义自动配置类

在tml-spring-boot-starter-autoconfiguration的autoConfiguration包 中,创建一个配置类:PersonAutoConfiguration,其代码如下

package com.example.tmlspringbootstarterautoconfiguration.autoConfiguration;
import com.example.tmlspringbootstarterautoconfiguration.properties.PersonProperties;
import com.example.tmlspringbootstarterautoconfiguration.services.PersonService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(PersonProperties.class) //启用 PersonProperties,并默认将它添加到容器中
public class PersonAutoConfiguration{
        @ConditionalOnMissingBean(PersonService.class) //当容器中没有 PersonService 时生效
        @Bean
        public PersonService personService() {
            PersonService personService = new PersonService();
            return personService ;
        }
}

PersonAutoConfiguration使用了以下 4 个注解:

  • @Configuration:表示该类是一个配置类;
  • @EnableConfigurationProperties(HelloProperties.class):该注解的作用是为 HelloProperties 开启属性配置功能,并将这个类以组件的形式注入到容器中;
  • @ConditionalOnMissingBean(HelloService.class):该注解表示当容器中没有 HelloService 类时,该方法才生效;
  • @Bean:该注解用于将方法的返回值以 Bean 对象的形式添加到容器中。

这样自动配置类就将组件和配置绑定并且都注入到容器中了。

6 创建 spring.factories文件

由于 Spring Boot 的自动配置是基于 Spring Factories 机制实现的,因此我们自定义 starter 时,同样需要在项目类路径下创建一个 spring.factories 文件。在tml-spring-boot-starter-autoconfiguration 的类路径下(resources )中创建一个 META-INF 文件夹,并在 META-INF 文件夹中创建一个 spring.factories 文件

将 Spring Boot 的 EnableAutoConfiguration 接口与自定义 starter 的自动配置类 PersonAutoConfiguration组成一组键值对添加到 spring.factories 文件中,以方便 Spring Boot 在启动时,获取到自定义 starter 的自动配置,代码如下

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.tmlspringbootstarterautoconfiguration.autoConfiguration.PersonAutoConfiguration

7 构建 starter

接下来,我们需要对自定义 starter 进行构建,并将它安装到本地仓库或远程仓库中,供其他项目使用。由于我们是在本地的项目中引用和测试,因此只需要使用 install 命令安装到本地仓库即可,因为存在依赖关系,所以先构建tml-spring-boot-starter-autoconfiguration再构建tml-spring-boot-starter

构建过程中遇到一些问题,只要在pom中的build按照如下内容配置即可避免:

<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${project.parent.version}</version>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
            <!--添加配置跳过测试-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.1</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
            <!--添加配置跳过测试-->
        </plugins>
    </build>

使用自定义starter

我们来测试下自定义的starter

1 新建测试项目

新建一个Moudle来使用我们的自定义starter

在其 pom.xml 中引入依赖tml-spring-boot-starter(自定义 starter),配置如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>test-springboot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>test-springboot</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <!--引入自定义 starter -->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>tml-spring-boot-starter</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2 编写配置文件

在 Spring Boot 配置文件 application.yml中,添加以下属性配置

#自定义 starter prefix 属性
person:
   prefix: 兄弟 
#自定义 starter suffix 属性
   suffix: 欢迎一起玩儿SpringBoot!

3 创建测试控制器

在 controller包 中创建一个控制器类 PersonController

package com.example.testspringboot.controller;
import com.example.tmlspringbootstarterautoconfiguration.services.PersonService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
@Controller
public class PersonController {
    //自动装配自定义 starter 的 service
    @Resource
    PersonService personService;
    @ResponseBody
    @GetMapping("/personInfo")
    public String SayHello(String name) {
        return personService.sayHello(name);
    }
}

请求后结果如下,可以看到配置也被读取出来了

总结一下

其实实现一个自定义starter的过程就是把前面所有SpringBoot相关内容复习一遍的过程,通过SpringBoot自动配置,我们初始化好了自动配置类,把组件和配置信息绑定并注入到容器中,然后将这个场景启动器提供出来,供外边的第三方使用,我们成了一个starter的服务提供商,我觉得这样实现一遍后对SpringBoot的实现理解的更加透彻了。

相关文章
|
20天前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
190 2
|
1月前
|
人工智能 Java 机器人
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
Spring AI Alibaba集成Ollama,基于Java构建本地大模型应用,支持流式对话、knife4j接口可视化,实现高隐私、免API密钥的离线AI服务。
973 1
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
|
1月前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
366 4
存储 JSON Java
341 0
|
1月前
|
监控 安全 Java
使用 @HealthEndpoint 在 Spring Boot 中实现自定义健康检查
Spring Boot 通过 Actuator 模块提供了强大的健康检查功能,帮助开发者快速了解应用程序的运行状态。默认健康检查可检测数据库连接、依赖服务、资源可用性等,但在实际应用中,业务需求和依赖关系各不相同,因此需要实现自定义健康检查来更精确地监控关键组件。本文介绍了如何使用 @HealthEndpoint 注解及实现 HealthIndicator 接口来扩展 Spring Boot 的健康检查功能,从而提升系统的可观测性与稳定性。
142 0
使用 @HealthEndpoint 在 Spring Boot 中实现自定义健康检查
|
2月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
503 3
|
人工智能 Java Serverless
【MCP教程系列】搭建基于 Spring AI 的 SSE 模式 MCP 服务并自定义部署至阿里云百炼
本文详细介绍了如何基于Spring AI搭建支持SSE模式的MCP服务,并成功集成至阿里云百炼大模型平台。通过四个步骤实现从零到Agent的构建,包括项目创建、工具开发、服务测试与部署。文章还提供了具体代码示例和操作截图,帮助读者快速上手。最终,将自定义SSE MCP服务集成到百炼平台,完成智能体应用的创建与测试。适合希望了解SSE实时交互及大模型集成的开发者参考。
10790 60
|
7月前
|
安全 Java Apache
微服务——SpringBoot使用归纳——Spring Boot中集成 Shiro——Shiro 身份和权限认证
本文介绍了 Apache Shiro 的身份认证与权限认证机制。在身份认证部分,分析了 Shiro 的认证流程,包括应用程序调用 `Subject.login(token)` 方法、SecurityManager 接管认证以及通过 Realm 进行具体的安全验证。权限认证部分阐述了权限(permission)、角色(role)和用户(user)三者的关系,其中用户可拥有多个角色,角色则对应不同的权限组合,例如普通用户仅能查看或添加信息,而管理员可执行所有操作。
378 0