手撕SpringBoot的自定义启动器

news2024/11/25 7:04:19

一. 前言

哈喽,大家好,最近金九银十,又有不少小伙伴私信辉哥,说自己在面试时被问到SpringBoot如何自定义启动器,结果自己不知道该怎么回答。那么今天就手把手地带着大家,去看看在SpringBoot中到底该怎么实现自定义启动器。

二. 什么是SpringBoot自动装配?

在进行代码实现之前,我们先来看看什么是SpringBoot的自动装配。与自动装配对应的是手动装配,比如我们以前使用xml配置文件,引入spring或者引入mybatis时需要配置数据源、配置mybatis扫描、配置数据库连接池等。

而在SpringBoot中,我们只需要引入对应的mybatis启动器、druid启动器和数据库驱动,配置文件就可以自动根据配置数据库地址、用户和密码等信息快速地完成框架的搭建。也就是说,我们只要引入启动器,再配置一些必要的初始化连接参数,就可以直接使用,而不需要再自己创建很多复杂的配置,就可完成Bean类之间的依赖。

这一切都依赖于SpringBoot的自动装配!而自动装配则离不开starter启动器这个核心!那么starter启动器是怎么实现的呢?为了让大家搞明白这个问题,就给大家手写一个自定义的启动器。

三. 自定义启动器

1.第一步:首先创建一个java-maven的父工程

<?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.qfedu</groupId>
    <artifactId>springboot-auto</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/>
    </parent>
</project>

image.png

2.第二步:创建一个子工程

image.png

3.引入依赖

<?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">
    <parent>
        <artifactId>springboot-auto</artifactId>
        <groupId>com.qfedu</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>demo</artifactId>
    
    <dependencies>
        <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>
</project>

4.第三步:创建另一个子模块 java2113-starter作为启动器

image.png

5.引入依赖

<dependencies>
    <!-- 引入springboot  自动装配核心注解  -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-autoconfigure</artifactId>
    </dependency>
</dependencies>

6.第四步:编写代码

package com.qfedu.java2113;

public class HelloService {
    private String msg;
    public String sayHello(){
        return "hello" + msg;
    }
    
    public String getMsg() {
        return msg;
    }
    
    
    public void setMsg(String msg) {
        this.msg = msg;
    }
}

7.编写配置文件:application.properties

hello.msg=byebye

8.HelloServiceProperties类中读取配置文件的配置数据hello.msg

package com.qfedu.java2113;

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

// 读取配置文件中 以 hello为前缀的值 设置到  msg
@ConfigurationProperties(prefix = "hello")
public class HelloServiceProperties {
    private static  final String MSG = "world";
    private String msg = MSG;
    public String getMsg() {
        return msg;
    }
    
    public void setMsg(String msg) {
        this.msg = msg;
    }
}

9.完成自动配置的类HelloServiceAutoConfiguration.java

package com.qfedu.java2113;

import org.springframework.beans.factory.annotation.Autowired;
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;

/***
 * hello-2009-starter 启动器 对应的配置 类 HelloServiceAutoConfiguration
 * 每一个启动器都有一个 这样的配置类
 * HelloServiceAutoConfiguration 的 作用是
 * 将HelloServiceProperties 加入到容器
 * 将 HelloService 加入到容器 并且和  HelloServiceProperties 进行装配
 * HelloServiceAutoConfiguration 就是自动装配的配置类
 * 完成了 HelloServiceProperties  和 HelloService 之间的装配
 */
@Configuration //标记当前类是配置类,加载 HelloServiceProperties.class配置到容器中
@EnableConfigurationProperties(HelloServiceProperties.class)  // 让配置类HelloServiceProperties bean加入到容器中
public class HelloServiceAutoConfiguration {
    @Autowired
    private HelloServiceProperties helloServiceProperties;
    @Bean// 将HelloService 加入到容器
//    @ConditionalOnMissingBean(HelloService.class) // 只有当容器中没有 bean HelloService ,加入到容器,如果有就不需要加入到容器了
    public HelloService helloService(){
        HelloService helloService = new HelloService();
        helloService.setMsg(helloServiceProperties.getMsg());
        return helloService;
    }
}

image.png

10.第五步:让自动装配类生效

在resources 创建 resources\META-INF\spring.factories

# Auto Configure  让自定义的 自动配置类生效
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.qfedu.java2113.HelloServiceAutoConfiguration

11.安装到本地maven仓库

执行 mvn install命令。

12.第六步:在demo中引入java2113-starter 启动器

image.png

13.第七步:编写代码,使用自定义启动器

13.1 配置文件初始化

image.png

13.2 使用

    @Autowired
    private HelloService helloService;
    
    @RequestMapping("/getHellMsg")
    public String getHellMsg(){
        return  "获取msg:"+ helloService.getMsg();
    }

14.第八步:测试看效果

image.png

四. 总结

哈,现在你跟着写出来了吗?这样我们就通过自定义启动器,很好地理解了SpringBoot的运行原理,特别是SpringBoot的自动装配原理。大家可以跟着辉哥上面的实现步骤,一步步地来,只要效果出来了,再逆向反推实现过程。你就会发现,原来很多所谓的实现原理也并不难。

千锋教育Java入门全套视频教程(java核心技术,适合java零基础,Java自学必备)

 

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

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

相关文章

半导体制造工艺流程

本资料仅用于学习和讨论&#xff0c;如有侵权请反应 1、半导体制造工艺流程-要求 1.1 英特尔50亿纳米的制作工艺 2、第一步 晶圆加工 2.1 第一步 晶圆加工 2.2 第二步 氧化 2.3 第三步 光刻 2.4第四步 刻蚀 2.5 第五步 薄膜沉积 2.6 第六步 互连 2.7 第七步 测试 2.8…

奥威软件SaaS BI系统:一站式数据可视化解决方案

SaaS BI 系统是 Software as a Service 商业智能的缩写&#xff0c;是一种基于云计算的商业智能解决方案。它允许用户通过互联网访问和分析数据&#xff0c;而无需安装和维护昂贵的硬件和软件。如今将BI系统SaaS化已成趋势&#xff0c;越来越多的企业开始寻找SaaS BI系统&#…

IDA分析实例android_crackme/EasyJNI/Transformers/pingan2

文章目录 第一个实例android_crackme将32位的android_server放到手机目录下给android_server赋予root更改root用户组运行android_serverpc端端口转发安装apk&#xff0c;并运行app打开32位IDA并attach到进程先使用jadx看java层逻辑定位要分析的方法IDA 给两个方法打断点 第二个…

无涯教程-jQuery Mock Test函数

本节介绍了与 jQuery Framework 相关的各种模拟测试。您可以在本地计算机上下载这些样本模拟测试,并在方便时离线解决。每个模拟测试均随附一个模拟测试键,可让您验证最终分数并为自己评分。 Mock Test I Mock Test II Mock Test III Mock Test IV Q 1 -关于jQuery,以下哪项是…

【LeetCode 75】第十六题(1004)最大连续1的个数

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码运行结果&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 给一个只有0和1的数组&#xff0c;可以将K个0变成1&#xff0c;问最大能得到的全是1的子数组的长度是多少。 这算是很经典的滑动…

领域驱动设计(五) - 战术设计 - 【3/3】聚合与模型的构建方法

这一小章主要阐述下如何组织上述分析后的模型。 使用聚合&#xff08;Aggergate&#xff09;进行建模&#xff0c;并且在设计中结合工厂&#xff08;Factory&#xff09;和资源库&#xff08;Repositiory&#xff0c;注意Orm映射出的持久化对象不是领域模型的范围&#xff0c;在…

深入理解ClickHouse跳数索引教程

跳数索引 影响ClickHouse查询性能的因素很多。在大多数场景中&#xff0c;关键因素是ClickHouse在计算查询WHERE子句条件时是否可以使用主键。因此&#xff0c;选择适用于最常见查询模式的主键对于表的设计至关重要。 然而&#xff0c;无论如何仔细地调优主键&#xff0c;不可…

Java导出数据到Excel

Java导出数据到Excel分3步处理 1、构建Workbook 数据 2、设置Workbook 格式 3、导出到Excel 1、构建Workbook 数据 public static void buildData(Workbook wb, List<Person> list) {Sheet sheetName wb.createSheet("sheetName");Row row sheetName.creat…

macOS 环境变量加载探究

使用 macOS 安装环境&#xff0c;见到过很数种环境变量配置方法&#xff0c;每次也都是按照别人的代码&#xff0c;人家配置在哪 我就配置在哪&#xff0c;其实不太清楚有什么区别&#xff0c;决定记录下。 本机 macOS 13.3&#xff0c;从 macOS Catalina(10.15) 开始&#xf…

软件测试入门基础知识

目录 1.软件测试的定义 2.软件测试的生命周期 3.如何描述一个bug 4.bug的级别如何定义 5.bug生命周期 6.软件测试策略 7.软件测试模型 7.1传统瀑布模型 7.2V模型 7.3W模型&#xff08;双V模型&#xff09; 7.4敏捷模型 7.5X模型 1.软件测试的定义 首先要明确测试的定义…

systemVerilog基础9——类的继承

1、 描述子类继承父类的关键词&#xff1a;extends 之前定义过的类Packet&#xff0c;可以进一步扩展构成一个它的子类LinkedPacket。类Packet的定义如下&#xff1a; class Packet ;//class定义类 类名 packet//类 packet的成员//数据或类属性bit [3:0] command; bit [40:0] …

【css】背景图片附着

属性&#xff1a;background-attachment 属性指定背景图像是应该滚动还是固定的&#xff08;不会随页面的其余部分一起滚动&#xff09;。 background-attachment: fixed&#xff1a;为固定&#xff1b; background-attachment: scroll为滚动 代码&#xff1a; <!DOCTYPE h…

TypeScript基础学习

目录 一、安装 1、下载国内镜像 2、安装 3、查看安装情况 4、使用例子 二、变量声明 1、规则 2、声明的四种方式 3、注意 4、类型断言 5、类型推断 6、变量作用域 三、基础类型&#xff08;共11种&#xff09; 1、Any 类型 2、Null 和 Undefined 3、never 类型…

医药化工企业洁净厂房改造消防防爆安全的重要性

设计 【摘要】&#xff1a;近年来&#xff0c;我国医药化工企业规模不断扩大。医药化工企业的情况复杂&#xff0c;稍有不慎将发生火灾或者爆炸&#xff0c;对人员生命以及财产安全造成巨大的损害&#xff0c;酿成悲剧。所以&#xff0c;“三同时”原则的落实&#xff0c;如何…

伊语IM即时通讯源码/im商城系统/纯源码IM通讯系统安卓+IOS前端纯原生源码

伊语IM即时通讯源码/im商城系统/纯源码IM通讯系统安卓IOS前端纯原生源码&#xff0c; 后端是java源码。

tinkerCAD案例:30. 冰球挑战赛

tinkerCAD案例&#xff1a;30. 冰球挑战赛 这些简单易学、循序渐进的 Tinkercad 课程将指导你设计出属于自己的超棒曲棍球冰球&#xff1b;这些设计将性能和风格推向了极限&#xff01; 本课有两个目标利用科学方法提高曲棍球球的性能。通过在冰球上添加图案&#xff0c;发挥设…

rust怎么搞的,这么简单的代码也报“borrow of moved value“?

奇了怪了&#xff0c;这么简单的代码也编译不过&#xff1f; let hello String::from("hello");let world hello;hello.push_str("world"); // error[E0382]: borrow of moved value: hello看下完整报错 error[E0382]: borrow of moved value: hello--&…

picgo 图床 七牛云的设置

网站 PicGo github Molunerfinn/PicGo: &#x1f680;A simple & beautiful tool for pictures uploading built by vue-cli-electron-builder PicGo/Awesome-PicGo: A collection of awesome projects using PicGo. 设置 AcccessKey (AK) SecretKey(SK) 在个人中心&…

HarmonyOS学习路之方舟开发框架—学习ArkTS语言(状态管理 三)

Link装饰器&#xff1a;父子双向同步 子组件中被Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。 概述 Link装饰的变量与其父组件中的数据源共享相同的值。 装饰器使用规则说明 Link变量装饰器 说明 装饰器参数 无 同步类型 双向同步。 父组件中State, Stor…

无法访问Microsoft Store

可以先试试把代理工具关了 如果不行 winr, 输入inetcpl.cpl 勾上TLS 1.1,TSL1.2 重启&#xff0c;再试试