SpringBoot:手动创建应用

Spring提供了在线的Spring Initialzr在线创建Spring Boot项目,为了更好的理解Spring Boot项目,这里我们选择手动创建。

1.新建Web应用

1.1 生成工程

首先要做是创建一个Java项目,这里我们选择使用Maven来支持,使用archetype:generate生成一个项目。

mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes 
    -DarchetypeArtifactId=maven-archetype-quickstart 
    -DarchetypeVersion=1.4 
    -DgroupId=com.keyniu.dis 
    -DartifactId=DiveInSpring 
    -Dversion=0.1 
    -Dpackage=com.keyniu.dis 
    -DinteractiveMode=false

生成的项目结构很简单,整个目录结果如下图,根目录下存放pom.xml、src目录,src目录下又分为主目录(main)和测试目录(test)

1.2 添加Spring Boot依赖

为了让应用支持SpringBoot,只需要在pom.xml里添加Spring Boot依赖即可。这里我们目标是让项目支持Spring Boot提供Web接口。首先是设置项目的parent

<project>
    ...
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.0</version>
    </parent>
    ....
</project>

然后是添加spring-boot-starter-web依赖,支持Web接口开发

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

为了支持当前项目的启动,需要定义SpringBootApplication注解,使用SpringApplication.run执行当前工程,我们创建一个引导类

package com.keyniu.dis;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DiveInMain {

    @GetMapping("/hello")
    public String hello(@RequestParam("name") String name) {
        return "hello," + name;
    }

    public static void main(String[] args) {
        SpringApplication.run(DiveInMain.class);
    }
}

通过DiveInMain.main方法启动后,我们通过curl查看/hello调用已经正常工作了。

randy@Randy:~$ curl -s http://192.168.31.52:8080/hello?name=randy
hello,randy

2. 不依赖<parent>

将pom.xml的parent设置为spring-boot-starter-parent确实很方便,然而有的时候,组织内部会有自己的parent pom定义,pom是单根继承,无法额外再加一个。我们需要拆解一下spring-boot-starter-parent的定义,它主要分为3部分:

  1. 依赖的版本管理,通过spring-boot-dependencies的dependencyManagement定义各个依赖的推荐版本
  2. 插件的使用管理,通过pluginManagement定义推荐的插件版本
  3. 自定义的profile,在spring-boot-starter-parent里定义了各种各样的profile实现特定场景定制的能力
2.1 依赖的版本管理

上面提到spring-boot-starter-parent提供了3个能力,分别是依赖的版本管理、插件的版本管理、自定义的Profile。想要在工程能不依赖spring-boot-starter-parent,通过引入spring-boot-dependencies,我们能做到继续使用Spring官方推荐的依赖版本,看如下的pom.xml定义,相比之前的版本,唯一的差异就是在dependencyManagement中使用了spring-boot-dependencies。

<?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.keyniu.dis</groupId>
    <artifactId>DiveInSpring</artifactId>
    <version>0.1</version>

    <name>DiveInSpring</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>3.3.0</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>3.3.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>
2.2 插件的使用管理

使用spring-boot-dependencies能实依赖的版本管理,通过IDEA执行DiveInMain看起来一切正常,直到我们脱离IDEA运行的时候,执行java -jar发现执行报错

PS D:\Workspace\DiveInSpring\target> java -jar .\DiveInSpring-0.1.jar
.\DiveInSpring-0.1.jar中没有主清单属性

我们知道java -jar执行的时候会查找MANIFEST.MF文件里定义的Main-Class配置,解压jar文件还发现MANIFEST.MF并没有设置Main-Class启动类,jar文件并不是FatJar,没有包含被依赖的组件

这个操作是由spring-boot-maven-plugin这个Maven插件完成的,不适用parent的话,我们要手动这个插件,配置start-class作为mainClass,startClass可能是JarLauncher、WarLauncher,它们定义在spring-boot-loader模块中。添加插件后,重新打包并使用java -jar执行,这个时候工程就能正常运行了。

<properties>
    <spring-boot.run.main-class>${start-class}</spring-boot.run.main-class>
</properties>


<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <id>repackage</id>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <mainClass>${spring-boot.run.main-class}</mainClass>
            </configuration>
        </plugin>
    </plugins>
</build>

3. <parent>的完整能力

通过使用spring-boot-maven-plugin,我们的jar已经能够正常执行了。不过spring-boot-starter-parent提供的能力要比这个多得多。

3.1 资源文件处理

spring-boot-starter-parent默认会将src/main/resource下的所有文件当成资源文件,这些资源文件会被分成两类处理:

  1. application*,做变量引用(${变量名})替换,然后包含在资源文件中
  2. 其他,不做处理,直接复制进资源文件
<build>
    <resources>
        <resource>
            <directory>${basedir}/src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
            <include>**/application*.yml</include>
            <include>**/application*.yaml</include>
            <include>**/application*.properties</include>
        </includes>
        </resource>
        <resource>
            <directory>${basedir}/src/main/resources</directory>
            <excludes>
            <exclude>**/application*.yml</exclude>
            <exclude>**/application*.yaml</exclude>
            <exclude>**/application*.properties</exclude>
            </excludes>
        </resource>
    </resources>
</build>
3.2 插件默认配置

此外spring-boot-starter-parent对插件还做了额外的配置,这里我们捡紧要的说

插件

配置

作用

maven-compiler-plugin

配置parameters=true,在编译的时候调用javac -parameters

在.class文件里保留参数名,供反射时读取

maven-jar-plugin

配置mainClass为start-class的值,JarLauncher

设置可执行jar的启动引导类

maven-war-plugin

配置mainClass为start-class的值,WarLauncher

设置可执行jar的启动引导类

git-commit-id-maven-plugin

配置git信息存储的文件,git.properties

获取打包时git仓库的版本号/分支等

spring-boot-maven-plugin

打包SpringBoot项目结构,包括第3方依赖

BOOT-INF/classes和BOOT-INF/lib

maven-shade-plugin

创建uber jar,资源的合并处理,创建可执行jar

META-INF下配置文件的合并处理,比如spring.handles

native-maven-plugin

使用GraalVM构建Spring成为native应用

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++进阶之AVL树+模拟实现

目录 目录 一、AVL树的基本概念 1.1 基本概念 二、AVL树的模拟实现 2.1 AVL树节点的定义 2.2 插入操作 2.3 旋转操作 2.4 具体实现 一、AVL树的基本概念 1.1 基本概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&…

【论文速读】Self-Rag框架,《Self-Rag: Self-reflective Retrieval augmented Generation》

关于前面的文章阅读《When to Retrieve: Teaching LLMs to Utilize Information Retrieval Effectively》&#xff0c;有网友问与Self-Rag有什么区别。 所以&#xff0c;大概看了一下Self-Rag这篇论文。 两篇文章的方法确实非常像&#xff0c;Self-Rag相对更加复杂一些。 When …

图数据库Neo4j——Neo4j简介、数据结构 Docker版本的部署安装 Cypher语句的入门

前言 MySQL是一种开源的关系型数据库管理系统&#xff0c;使用SQL作为其查询语言&#xff0c;常见的关系型数据库有MySQL、Oracle、SQL Server、PostgreSQL等。相关博客文章如下&#xff1a; 【合集】MySQL的入门进阶强化——从 普通人 到 超级赛亚人 的 华丽转身PostgreSQL数…

计算机系统结构之流水

一、标量流水线的主要性能 吞吐率是流水线单位时间里能流出的任务数或结果数(最大吞吐率&#xff1a;单位时间内计算机所能处理的最多指令条数)。 流水线中经过时间最长的子过程成为瓶颈子过程。最大吞吐率取决于瓶颈段的时间。 实际吞吐率&#xff1a; 加速比&#xff1a; …

教你搞一个比较简单的计时和进度条装饰器 (多线程进阶版)

简单的计时和进度条装饰器 - 多线程进阶版 这个进阶版有什么&#xff1f;话不多说上代码效果图 上一篇关于装饰器的Blog 这个进阶版有什么&#xff1f; 在上一个装饰器工作时&#xff0c;跑了20秒后就停止了。如果运行的函数跑了60秒&#xff0c;后面的40秒我们是只能等到结束…

CAD二次开发(7)- 实现Ribbon选项卡,面板,功能按钮的添加

1. 创建工程 2. 需要引入的依赖 如图&#xff0c;去掉依赖复制到本地 3. 代码实现 RibbonTool.cs 实现添加Ribbon选项卡&#xff0c;添加面板&#xff0c;以及给面板添加下拉组合按钮。 using Autodesk.Windows; using System; using System.Collections.Generic; using S…

悬剑武器库5.04版

工具介绍 悬剑5 基于“悬剑网盘”精选工具集悬剑5“飞廉”云武器库制作。 操作系统&#xff1a;Windows 10 专业版 锁屏密码&#xff1a;secquan.org 解压密码: 圈子社区secquan.org 镜像大小&#xff1a;33.1GB 系统占用空间63.0 GB 镜像导入 下载镜像&#xff0c;文末…

WordPress博客主题触屏版社区源码

下载地址&#xff1a;WordPress博客主题触屏版社区源码

【Unity之FGUI】黑神章Fairy GUI控件详解

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;就业…

python采集汽车价格数据

python采集汽车价格数据 一、项目简介二、完整代码一、项目简介 本次数据采集的目标是车主之家汽车价格数据,采集的流程包括寻找数据接口、发送请求获取响应、解析数据和持久化存储,先来看一下数据情况,完整代码附后: 二、完整代码 #输入请求页面url #返回html文档 imp…

6.3 Go 结构体(Struct)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

普华永道信任危机:上市公司解约风波与反思

在全球会计业界的星空中&#xff0c;普华永道无疑是那颗最为耀眼的星之一。然而&#xff0c;近日这颗星却遭遇了前所未有的信任危机。这家大名鼎鼎的四大会计师事务所之一&#xff0c;近期陷入了上市公司解约的风波之中&#xff0c;其声誉与地位正面临严峻挑战。 就在昨晚&…

Word2Vec模型的引入介绍与相关概念

一 、Word2Vec模型的背景引入 1.1 One-hot模型 One-hot模型是是用N位的状态寄存器对N个状态进行编码 如下所示&#xff0c;是有4个样本&#xff0c;每个样本都有三个特征&#xff0c;特征1表示当前样本的性别。 我们喂给算法怎么样的数据&#xff0c;算法就会给我们一个怎么…

学习笔记——IP地址网络协议——网络层(IP)协议

一、网络层(IP)协议 网络层(被称为IP层)但网络层协议并不只是IP协议&#xff0c;还包括ICMP(Internet Control Message Protocol)协议、IPX(Internet Packet Exchange)协议等。 1、IP协议 IP(Internet Protocol)本身是一个协议文件的名称&#xff0c;该协议文件的内容非常少&…

使用python统计word文档页数

使用python统计word文档页数 介绍效果代码 介绍 使用python统计word文档的页数 效果 代码 import os import comtypes.clientdef get_word_page_count(docx_path):try:# Initialize the COM objectword comtypes.client.CreateObject(Word.Application)word.Visible False…

【Qt】探索Qt绘图世界:自定义控件与视觉效果的全面指南

文章目录 前言&#xff1a;1. 绘图基本概念2. 绘制各种形状3. 绘制文字&#xff08;显示文字&#xff09;、设置画笔4. 画刷5. 绘制图片6. 特殊的绘图设备总结&#xff1a; 前言&#xff1a; 在软件开发中&#xff0c;图形用户界面&#xff08;GUI&#xff09;的设计是至关重要…

【面试题】CAP理论、BASE理论及其注册中心选型

1.CAP理论 CAP&#xff1a;指的是在一个分布式系统中&#xff0c;Consistency&#xff08;一致性&#xff09;、Availability&#xff08;可用性&#xff09;、Partition Tolerance&#xff08;分区容错性&#xff09;&#xff0c;三者不可同时获得 一致性&#xff08;C&#x…

成功解决“IndexError: pop index out of range”错误的全面指南

成功解决“IndexError: pop index out of range”错误的全面指南 引言 在Python编程中&#xff0c;处理列表&#xff08;list&#xff09;、双端队列&#xff08;deque&#xff09;或其他可迭代对象时&#xff0c;我们经常使用pop()方法来移除并返回指定索引处的元素。然而&am…

图解 Python 编程(10) | 错误与异常处理

&#x1f31e;欢迎来到Python的世界 &#x1f308;博客主页&#xff1a;卿云阁 &#x1f48c;欢迎关注&#x1f389;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f31f;本文由卿云阁原创&#xff01; &#x1f4c6;首发时间&#xff1a;&#x1f339;2024年6月2日&…

图解 IPv6 地址范围

1、 IPv6 多播地址范围 2、1 - 接口本地&#xff1c;2 - 链路本地&#xff1c;5 - 站点本地&#xff1c;8 - 组织本地&#xff1c;E - 全局 3、Well-Known Multicast Addresses