如何自己实现一个Spring Boot Starter

news2024/10/1 19:39:29

现在很多开源的组件都会提供对应的 springboot-starter 包给我们去用,要做一个 starter 包并不难。参照Spring内置的实现就好了:
1、在工程里引入 starter 打包相关的依赖。
2、在我们工程内建 spring.factories 文件,编写我们配置类的全限类名。

一、自定义步骤详解

使用AOP实现拦截方法执行和打印日志的功能

1.1、创建Starter项目

名称 zhinian-log-spring-boot-starter , 版本号是 1.0-SNAPSHOT 。且同时引入下方依赖。

1.2、引入pom依赖

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zn.opit.base</groupId>
    <artifactId>zhinian-log-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <version>2.7.13</version>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
            <version>2.7.13</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <classifier>exec</classifier>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

1.3、定义Starter需要的配置类(Properties)

package com.zn.opit.base.config;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "zn.log")
public class ZhiNianLogProperties {

    private boolean enabled;

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
}

如果我们需要从 application.yaml 或 application.properties 中拿到一些使用者配置的数据,那么我们就需要定义一个properties类。这个properties类主要作用是将 application.yaml 或 application.properties 中的配置信息映射成实体类,比如我们这里指定 prefix = “zn.log” 这样,我们就能将以zn.log为前缀的配置项拿到了。

1.4、编写Starter项目的业务功能

AOP切面逻辑

package com.zn.opit.base.component;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class WebLogAspect {
    @Pointcut("execution(* *..*Controller.*(..))")
    public void webLog(){}

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        //方法开始前,打印开始日志
        System.out.println("zn-starter --------doBefore");

    }

    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 处理完请求,打印结束日志
        System.out.println("zn-starter --------doAfterReturning");
    }
}

1.5、编写自动配置类

package com.zn.opit.base.config;

import com.zn.opit.base.component.WebLogAspect;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration // 表示该类是一个配置类
@EnableConfigurationProperties({ZhiNianLogProperties.class}) // 该注解的作用是为 xxxProperties 开启属性配置功能,并将这个类以组件的形式注入到容器中
@ConditionalOnProperty(prefix = "zn.log", value = "enabled") // 当指定的配置项等于你想要的时候,配置类生效
public class ZnLogAutoConfig {

    @Bean // @Bean:该注解用于将方法的返回值以 Bean 对象的形式添加到容器中
    @ConditionalOnMissingBean // @ConditionalOnMissingBean(xxx.class):该注解表示当容器中没有 xxx 类时,该方法才生效
    public WebLogAspect webLogAspect() {
        return new WebLogAspect();
    }
}

1.6、编写spring.factories文件加载自动配置类

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.zn.opit.base.config.ZnLogAutoConfig

1.7、构建starter制品包

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <classifier>exec</classifier>
            </configuration>
        </plugin>
    </plugins>
</build>

在项目根目录下执行mvn clean install,打包并放到maven仓库中(maven仓库地址和配置有关)

显示build success,表示starter制品包打包完成

二、其它项目引用验证

2.1、pom中引入自定义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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zn.opit.base</groupId>
    <artifactId>zhinian-log-starter-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.7.13</version>
        </dependency>

        <dependency>
            <groupId>com.zn.opit.base</groupId>
            <artifactId>zhinian-log-spring-boot-starter</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

2.2、写一个Controller接口

(要符合starter里的aop拦截表达式规则,否则拦截不到)

package com.zn.opit.base.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/hello")
@RestController
public class HelloController {

    @GetMapping("/test")
    public String test() {
        return "SUCCESS";
    }
}

2.3、配置文件 application.properties

zn.log.enabled=true
server.port=8077

2.4、验证

启动业务项目,访问接口,验证
在这里插入图片描述
在这里插入图片描述

至此,一个简单的starter示例就写完了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1402526.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ETLCloud:实现数据库快速输入输出的利器

在当今大数据时代&#xff0c;数据的高效处理和管理成为企业发展的关键。而数据库作为数据存储和管理的核心&#xff0c;其输入输出效率的提升对于企业来说至关重要。ETLCloud数据集成工具&#xff0c;为企业提供了快速、灵活、稳定的数据库输入输出解决方案&#xff0c;极大地…

最好的超声波清洗机有哪些?怎么样能选购到好用超声波清洗机?

眼镜党们在挑选超声波清洗机时候真的会非常苦恼&#xff0c;市面上的超声波清洗机品牌真的五花八门&#xff0c;让人挑得眼花缭乱&#xff0c;作为一个佩戴眼镜时间超达10年&#xff0c;使用超声波清洗机洗眼镜有五年的来说&#xff0c;我在选购超声波清洗机这条道路上吃的苦比…

线性代数:矩阵的定义

目录 一、定义 二、方阵 三、对角阵 四、单位阵 五、数量阵 六、行&#xff08;列&#xff09;矩阵 七、同型矩阵 八、矩阵相等 九、零矩阵 十、方阵的行列式 一、定义 二、方阵 三、对角阵 四、单位阵 五、数量阵 六、行&#xff08;列&#xff09;矩阵 七、同型矩…

04 单链表

目录 链表的概念和结构单链表OJ练习 1. 链表的概念和结构 1.1 链表的概念 链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的 1.从上图可以看出链式结构在逻辑上是连续的&#xff0c;物理上不一定连续 2.现…

SpringBoot之文件上传

1、文件上传原理&#x1f618; 表单的enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。 当表单的enctype"application/x-www-form-urlencoded"&#xff08;默认&#xff09;时&#xff0c;form表单中的数据格式为&#xff1a;keyvalue&keyvalue …

༺༽༾ཊ—Unity之-01-单例模式—ཏ༿༼༻

在游戏开发过程中&#xff0c;我们会创建各种各样的类&#xff0c;再用new生成实例&#xff0c;有些时候我们需要这个类在整个游戏中是唯一出现的&#xff0c;比如一些管理器比如声音管理器等&#xff0c;没必要创建很多实例&#xff0c;就算有很多模块需要各种声音功能&#x…

【C++】模板类vector的简单实现

文章目录 1. 迭代器2.构造和析构3. 容量4. 访问5.修改6.测试完整代码总结&#xff1a; 在C的STL库中&#xff0c;vector是一个非常常用的容器&#xff0c;它提供了动态数组的功能。今天我们将一起来实现一个简化版的vector模板类&#xff0c;以便更好地理解它的原理和实现过程。…

红日靶场2打点记录

因为之前成功用冰蝎免杀360&#xff0c;把权限反弹到了MSF上&#xff0c;然后MSF把权限反弹到CS上 所以这次咱们走捷径直接通过反序列化漏洞连接&#xff08;就是关掉360&#xff09;因为权限弹来弹去感觉好麻烦 提示 大家如果想要免杀360千万别学我&#xff0c;我是之前免杀3…

springboot116基于java的教学辅助平台

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的基于java的教学辅助平台 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四…

前后端分离项目中实现图形验证码

图形验证码在我们的日常生活中时经常用到的&#xff0c;一般用于用户的登录、注册等。 图形验证码在互联网应用中的作用是提高安全性、防止滥用和保护用户隐私。它是一种简单而有效的人机验证技术&#xff0c;帮助保护系统和用户免受自动化攻击的影响。 本次我们通过spring b…

【深度学习每日小知识】NLP 自然语言处理

自然语言处理 (NLP) 是人工智能 (AI) 的一个子领域&#xff0c;处理计算机和人类&#xff08;自然&#xff09;语言之间的交互。它涉及使用算法和统计模型使计算机能够理解、解释和生成人类语言。 NLP 是人工智能领域的重要工具&#xff0c;广泛应用于语言翻译、文本分类和聊天…

短信平台搭建注意什么|网页版短信系统开发源码

短信平台搭建注意什么|网页版短信系统开发源码 短信平台是企业进行市场营销、客户关系管理和即时通讯的重要工具。为了确保短信平台的稳定运行和高效利用&#xff0c;以下是在搭建短信平台时需要注意的几个重要方面。 1. 需求分析&#xff1a;在搭建短信平台之前&#xff0c;需…

Springboot+vue的校园疫情防控系统(有报告),Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的校园疫情防控系统&#xff08;有报告&#xff09;&#xff0c;Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的校园疫情防控系统&#xff0c;采用M&#xff…

实时语音克隆,准确复制音色:OpenVoice | 开源日报 No.150

myshell-ai/OpenVoice Stars: 9.6k License: NOASSERTION OpenVoice 是一个通过 MyShell 进行即时语音克隆的开源项目。 OpenVoice 可以准确地克隆参考音色&#xff0c;并生成多种语言和口音的语音。OpenVoice 允许对声音风格进行细粒度控制&#xff0c;如情感、口音以及节奏…

数据库入门:快速了解数据库

目录 序言 一、什么是数据库&#xff1f; 二、DBMS 数据库管理系统&#xff08;DataBase Management System&#xff09; 三、数据库与文件系统的区别 四、数据库的发展和规划 五、常见数据库 5.1 关系型数据库 5.2 非关系型数据库 六、DBMS支持的数据模型 6.1 层次模…

【代码实战】从0到1实现transformer

获取数据 import pathlibimport tensorflow as tf# download dataset provided by Anki: https://www.manythings.org/anki/ text_file tf.keras.utils.get_file(fname"fra-eng.zip",origin"http://storage.googleapis.com/download.tensorflow.org/data/fra-…

Ultimate Crafting System

终极制作系统是您制作游戏的完整解决方案。从流畅的物品和配方创建的基础知识到强大的放置和能量转移系统,它拥有一切。可用于3D和2D游戏。非常适合独立简单的游戏,但程序员可以扩展其终极力量! — 内容 — - 点击式第三人称演示场景 - 第一人称演示场景 - 库存系统 - 从易于…

PIG框架学习3——Redisson 实现业务接口幂等

零、前言 ​ 业务接口幂等问题是在开发中遇到的&#xff0c;如果对业务接口代码不进行幂等控制&#xff0c;并且在前端没有对请求进行限制的情况下&#xff0c;可能会出现多次对接口调用&#xff0c;导致错误异常的发生。就上述情况&#xff0c;对PIGX自带的业务接口幂等实现进…

sql数据库的相关概念与底层介绍

本文中的数据库指的是磁盘数据库。如果有sql语言&#xff08;CRUD&#xff0c;增删改查&#xff09;的使用经验会更容易理解本文的知识点。 数据库与redis的区别 数据库&#xff1a;数据存储长期在磁盘中&#xff0c;小部分频繁需要的数据会被临时提取在内存中。 Redis&…

数组oj 移除元素

思路用双指针更简单&#xff0c;直接用一个数组&#xff0c;开始src和dst都为0&#xff0c;一起往后走(先走dst)&#xff0c;当dst遇到val就停下&#xff0c;src接着走&#xff0c;走到不是val的地方&#xff0c;然后把src赋值给dst&#xff0c;在一起&#xff0c;往后面走。结…