鹏叔(https://pengtech.net)

导航

如何手动创建一个springBoot项目

1. 介绍

在本文中,您将学习如何创建一个简单的Spring Boot应用程序,以及您需要哪些依赖项和技术需要了解。
此外,我们将更深入地了解基本原理。我将解释一些最关键的工作机制,如果你想成为一名专业开发人员,你需要了解这些机制。

2. 创建一个SpringBoot项目

2.1. 先决条件

要创建新的Spring Boot应用程序,我们需要以下开发环境:

Java 1.8或更高版本

IDE: Spring STS, Intellij Idea或者vscode

包管理工具: Maven 3.2+ 或者gradle 4+

2.2. 初始化项目

初始化Spring Boot项目, 可以使用web版的Initializer创建, 也可以手动创建. 我们首先使用web ininitializer创建, 然后在此基础上讲解手动创建Spring Boot工程的一些要点.

2.2.1. 使用Spring boot initializer初始化项目

使用Spring boot initializer初始化项目, 请执行以下操作:

  • 导航到https://start.spring.io.此服务将获取应用程序所需的所有依赖项,并为您完成大部分设置。
  • 选择Gradle或Maven以及您要使用的语言。本指南假设您选择了Java。
  • 单击Dependencies并选择SpringWeb。
  • 单击“生成”。
  • 下载生成的ZIP文件,该文件是根据您的选择配置的web应用程序的存档。

spring web ininitializer


demo
├── README.md
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
    ├── main
    │   ├── java
    │   │   └── Demo
    │   │       └── App.java
    │   └── resources
    └── test
        ├── java
        │   └── DemoTest
        └── resources

2.2.2. 手动创建Spring boot项目

如果要手动创建Spring Boot项目, 可以参考以下步骤.

  • 创建一个文件夹用来包含Spring Boot项目
mkdir demo
  • 获取Gradle wrapper相关文件, 并将其拷贝到Spring Boot项目文件夹
    gradle wrapper涉及到的文件主要有如下一些.
demo
├── README.md
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat

如果你已经安装了gradle runtime, 可以使用gradle task创建gradle wrapper

gradle wrapper
> Task :wrapper

如果不指定参数, 那么创建出来的gradle wrapper的版本是和gradle runtime一致的版本. 但是有时候或者大多数时候我们的项目的要求的版本和gradle runtime是不一样的, 所以这个时候我们需要在gradle wrapper命令中指定gradle的版本. 此时可以使用类似如下命令创建gradle wrapper, 将其中的版本替换成你所需要的版本.

$ gradle wrapper --gradle-version 7.5 --distribution-type all
> Task :wrapper

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

此处使用到了两个选项, --gradle-version 和 --distribution-type

--gradle-version
用于指定下载和执行Wrapper的Gradle版本。

--distribution-type
用于指定采用的Gradle分发包类型, Gradle分发包分为两种类型bin和all, 并包含了必要binary文件, 包体积更小一些, all 不仅包含binary文件, 还包含了documents和source code文件。可用选项为bin和all。默认值为bin。

--gradle-distribution-url

由于执行以上命令需要到远程服务器去下载Gradle分发包, 由于众所周知的原因, 可能会出现超时的情况. 此时可以使用另外选项 --gradle-distribution-url来指定gradle分发包的位置. 也可以参考我早年写的教程获取gradle分发包 Linux下安装gradle

如果没有在本机安装gradle, 可以从其它gradle项目拷贝gradle wrapper文件到Spring Boot项目文件夹, 这些文件都是可以重用的.
如果你手上没有gradle项目, 那就从上一步Spring boot initializer初始化项目生成的文件中拷贝过来.

2.2.2.1. gradle wrapper文件介绍

执行完gradle wrapper后, 项目的文件结构如下, 下面简单介绍一下这些文件

gradle-wrapper.jar

Wrapper JAR文件包含用于下载Gradle分发的代码。有人可能会问在执行gradle wrapper时不是已经下载过gradle分发包了吗, 为什么这里还需要gradle-wrapper.jar,
这主要是方便, 将项目源码分析给项目成员时使用的, 当我们共享项目或将项目纳入source control时, 是不会共享gradle分发包的, 当成员拿到源代码时, 就依赖这个jar文件去相应位置下载gradle分发包. 或者当我们的环境完全的destroy, 我们要重建项目, 也需要使用这个文件, 而不需要将构建gradle环境再执行一遍.

gradle-wrapper.properties

主要提供gradle wrapper运行时需要的一些参数, 比如去哪里下载分发包, 是否需要代理, 代理配置等信息. gradle wrapper执行的环境千差万别, 依赖此配置文件, gradle wrapper就能在任何环境下, 完成它的任务和使命.

gradlew, gradlew.bat

用于使用Wrapper执行构建的shell脚本和Windows批处理脚本。简单来说gradlew 是在Linux 或者Unix, Unix like环境也可以在git bash, cygwin下执行的gradle wrapper命令, 而gradlew.bat是在windows dos上执行的gradle wrapper命令.

设置完成后运行一些gradlew 命令来查看一下版本


$./gradlew -v

------------------------------------------------------------
Gradle 7.5.1
------------------------------------------------------------

Build time:   2022-08-05 21:17:56 UTC
Revision:     d1daa0cbf1a0103000b71484e1dbfe096e095918

Kotlin:       1.6.21
Groovy:       3.0.10
Ant:          Apache Ant(TM) version 1.10.11 compiled on July 10 2021
JVM:          1.8.0_321 (Oracle Corporation 25.321-b07)
OS:           Windows 11 10.0 amd64

2.2.2.2. 初始化Java项目

安装配置完gradle wrapper后, 我们就可以使用gradle wrapper来初始化一个java项目了.

步骤如下:

此处, 虽然我的开发环境是windows的, 但是我是在git bash下执行命令, 所以我使用的是./gradlw init, 如果是在windows dos下请替换成gradle.bat init

$./gradlew init
Starting a Gradle Daemon (subsequent builds will be faster)

Select type of project to generate:
  1: basic
  2: application
  3: library
  4: Gradle plugin
Enter selection (default: basic) [1..4] 2

Select implementation language:
  1: C++
  2: Groovy
  3: Java
  4: Kotlin
  5: Scala
  6: Swift
Enter selection (default: Java) [1..6] 3

Split functionality across multiple subprojects?:
  1: no - only one application project
  2: yes - application and library projects
Enter selection (default: no - only one application project) [1..2] 1

Select build script DSL:
  1: Groovy
  2: Kotlin
Enter selection (default: Groovy) [1..2] 1

Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no]


Select test framework:
  1: JUnit 4
  2: TestNG
  3: Spock
  4: JUnit Jupiter
Enter selection (default: JUnit Jupiter) [1..4] 1

Project name (default: demo):
Source package (default: demo):

> Task :init
Get more help with your project: https://docs.gradle.org/7.5.1/samples/sample_building_java_applications.html

BUILD SUCCESSFUL in 1m 34s
2 actionable tasks: 2 executed

通过以上步骤, 就可以创建一个基本的java项目

创建完成后的项目结构如下, 可以看出, init task帮我 添加了src目录, 其中的内容是java项目常见的一些结构, 此处不做展开.
此处可以看到init task帮我们在项目的根目录下创建了一个settings.gradle文件并在app目录下创建了app/build.gradle文件.

demo
├── app
│   ├── build.gradle
│   └── src
│       ├── main
│       │   ├── java
│       │   │   └── demo
│       │   │       └── App.java
│       │   └── resources
│       └── test
│           ├── java
│           │   └── demo
│           │       └── AppTest.java
│           └── resources
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
2.2.2.3. settings.gradle

下面重点介绍一些, settings.gradle和build.gradle文件.

一个gradle项目通常含有三个重要文件 build.gradle, gradle.properties和settings.gradle, 在init项目的使用由于项目还没有变得很复杂, 所以还没有必要定义属性, 所以初期看不到 gradle.properties文件, 而该文件是用来定义一些公用属性的.

settings.gradle中配置的是gradle中要build的项目信息:

rootProject.name = 'demo'
include('app')

上面的例子中,rootProject.name指定了项目的名字,include('app')表示需要引入一个叫做app的子项目,这个子项目中包含着实际的要打包的内容。

如果要更加深入的了解settings.gradle可以继续参考下面的详细介绍.

Gradle构建生命周期由三个阶段组成:初始化(initialization)、配置(configuration)和执行(execution)。settings.gradle在初始化阶段并用到。

Gradle查看settings.gradle文件,以便识别不同的项目。在初始化阶段结束时,Gradle将为每个项目(Project)或子项目(sub-project)创建一个对应的org.Gradle.api.Project的实例。

settings.gradle文件是一个Groovy脚本。settings.gradle脚本在整个构建声明周期中只会在初始化阶段被执行一次(与多项目构建中的多个build.gradle脚本相比)。
settings.grade脚本将在任何构建之前执行。甚至在创建Project实例之前, 因此,它将对Settings对象产生影响。

settings.gradle的主要作用是定义所有被包含的子模块, 将一个大的工程按模块分解为子模块, 更加符合模块化设计的思路.

settings.gradle可能包含以下一些属性

属性 描述
buildCache build cache configuration
extentions The container of extensions
gradle the Gradle instance for the current build
pluginManager The plugin manager for this plugin aware object
plugins the container of plugins that have been applied to this object
rootDir The root directory of the build. The root directory is the project directory of the root project.
rootProject The root project of the build.
settings Returns this settings object.
settingsDir The settings directory of the build. The settings directory is the directory containing the settings file.
startParameter The set of parameters used to invoke this instance of Gradle.

settings.gradle 可能含有以下一些方法.

方法 描述
apply(closure) Applies zero or more plugins or scripts.
apply(options) Applies a plugin or script, using the given options provided as a map. Does nothing if the plugin has already been applied.
apply(action) Applies zero or more plugins or scripts.
buildCache(action) Configures build cache.
findProject(projectDir) Returns the project with the given project directory.
findProject(path) Returns the project with the given path.
include(projectPaths) Adds the given projects to the build. Each path in the supplied list is treated as the path of a project to add to the build. Note that these path are not file paths, but instead specify the location of the new project in the project hierarchy. As such, the supplied paths must use the ‘:’ character as separator (and NOT ‘/’).
includeBuild(rootProject) Includes a build at the specified path to the composite build.
includeBuild(rootProject, configuration) Includes a build at the specified path to the composite build, with the supplied configuration.
includeFlat(projectNames) Adds the given projects to the build. Each name in the supplied list is treated as the name of a project to add to the build.
project(projectDir) Returns the project with the given project directory.
project(path) Returns the project with the given path.
2.2.2.4. build.gradle

build.gradle是gradle中非常重要的一个文件,因为它描述了gradle中可以运行的任务,今天本文将会带大家体验一下如何创建一个build.gradle文件和如何编写其中的内容。

先看看app中的build.gradle文件


plugins {
    // Apply the application plugin to add support for building a CLI application in Java.
    id 'application'
}

repositories {
    // Use Maven Central for resolving dependencies.
    mavenCentral()
}

dependencies {
    // Use JUnit test framework.
    testImplementation 'junit:junit:4.13.2'

    // This dependency is used by the application.
    implementation 'com.google.guava:guava:31.0.1-jre'
}

application {
    // Define the main class for the application.
    mainClass = 'demo.App'
}

很简单,指定了插件,仓库地址,依赖包和应用程序的main class路径。

一切准备好之后,我们就可以进行构建和运行了。
如果我们运行项目已经可以看到"hello world"消息了

$./gradlew run
Starting a Gradle Daemon (subsequent builds will be faster)

> Task :app:run
Hello World!

BUILD SUCCESSFUL in 6s
2 actionable tasks: 2 executed

plugin{}闭包:配置Gradle插件

语法格式: id: '插件名称', 如果需要用到多个插件, 可以添加多个id:'插件名称'
示例中的application插件用来帮助构建一个命令行应用程序, 如果是libary或gradle插件程序需要做相应替换.如果是java libary需要替换为'java-library', 如果是java编写的gradle plugin需要替换为'java-gradle-plugin', 当然目录结构和命名规范也要做相应调整.

repositories{}闭包: 配置依赖包仓库, 即告诉gradle去哪里查找和下载dependencies{}闭包中定义的依赖包.

dependencies{}闭包: 定义依赖包的版本, 以及何时使用该依赖包, 编译阶段, 还是运行阶段, 测试阶段等等.

application{}闭包: 是application插件需要的, 用来指定主函数, 用于启动项目.

build.gradle还有更多高级用法, 这里不做展开, 英文好的同学可以到gradle官网详细了解.

至此项目的骨架已经建立, 接下来我们将讲述, 如何添加springboot相关依赖, 来创建restful api和web application.

3. 引入spring boot

要引入spring boot首先我们要了解spring boot starter.

starter是SpringBoot中的一个新发明,它有效的降低了项目开发过程的复杂程度,对于简化开发操作有着非常好的效果. 简单来说就是spring boot start简化了我们创建一个项目的配置过程. 在spring boot starter出现之前, 首先我们要引入一堆依赖包, 比如spring bean, spring-context, spring-mvc, spring-jdbc, struts 2, hibernate 或者mybatis等等一堆的依赖包, 并执行解决包版本的依赖性, 然后写一堆的配置文件, 比如spring的配置文件, hibernate的配置文件, struts配置文件等等一堆的配置文件后才能正式开始写业务代码. 自从spring boot starter出现以后这些统统都不需要了, 只需要找到合适的starter, 引入它就够了.

去哪里找合适的spring boot starter?

starter 有官方为我们提供了很多的spring boot starters, 也有第三方组件厂商提供的starters,

spring boot 官方starters 可以在下面位置找到;
https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.build-systems.starters

这里简单列举一些starters和starters的描述信息.

1、application starters

这一个表格是 Spring Boot 所有应用程序级的 Starters,一起来看都有哪些。

starters名称 starter描述
spring-boot-starter 核心starter, 包括自动配置, 日志及YAML支持
spring-boot-starter-activemq 集成Apache ActiveMQ, 基于JMX消息队列
spring-boot-starter-Artemis 集成Apache Artemis, 基于JMX消息队列
spring-boot-starter-amqp 集成 spring amqp 和Rabbit MQ消息队列
spring-boot-starter-aop 集成 spring AOP 和 AspectJ面向切面编程
spring-boot-starter-batch 集成 spring Batch (批处理)
spring-boot-starter-cache 集成 spring cache (缓存)
spring-boot-starter-data-cassandra 集成cassandra(分布式数据库) 和 Spring Data Cassandra
spring-boot-starter-data-cassandra-reactive 集成cassandra(分布式数据库) 和 Spring Data Cassandra Reactive
spring-boot-starter-data-couchbase 集成 Couchbase(文档型数据库) 和 Spring Data Couchbase
spring-boot-starter-data-couchbase-reactive 集成 Couchbase(文档型数据库) 和 Spring Data Couchbase Reactive
spring-boot-starter-data-elasticsearch 集成 Elasticsearch(搜索引擎) 和 Spring Data Elasticsearch
spring-boot-starter-data-solr 集成Apache Solr(搜索引擎) 和 Spring Data Solr
spring-boot-starter-data-jdbc 集成Spring Data JDBC
spring-boot-starter-data-jpa 集成Spring Data JPA 和 Hibernate
spring-boot-starter-data-ldpa 集成Spring Data LDPA
spring-boot-starter-data-mongodb 集成MongoDB (文档型数据库) 和 Spring Data MongoDB
spring-boot-starter-data-mongodb-reactive 集成MongoDB (文档型数据库) 和 Spring Data MongoDB Reactive
spring-boot-starter-data-neo4j 集成neo4j (图形数据库) 和 Spring Data Neo4j
spring-boot-starter-data-r2dbc 集成Spring Data R2DBC
spring-boot-starter-data-redis 集成Redis(内存数据库) 结合 Spring Data Redis 和 Lettuce 客户端
spring-boot-starter-data-redis-reactive 集成Redis(内存数据库) 结合 Spring Data Redis Reactive 和 Lettuce 客户端
spring-boot-starter-data-redis-rest 集成 Spring Data REST 暴露 Spring Data repositories 输出REST资源
spring-boot-starter-thymeleaf 集成 thymeleaf 视图构建 MVC Web 应用
spring-boot-starter-freemarker 集成 FreeMarker 视图构建 MVC Web 应用
spring-boot-starter-groovy-templates 集成 Groovy 模板视图构建 MVC Web 应用
spring-boot-starter-groovy-hateoas 集成 Spring MVC 和 HATEOAS 构建超媒体 RESTful Web 应用程序
spring-boot-starter-integration 集成 Spring Integration
spring-boot-starter-jdbc 集成 JDBC 结合 HikariCP 连接池
spring-boot-starter-jersey 集成 JAX-RS 和 jersey 构建 RESTful web 应用, 是 spring-boot-starter-web 的一个替代starter
spring-boot-starter-jooq 集成 JOOQ 访问SQL数据库, 是spring-boot-starter-jdbc 和 spring-boot-starter-data-jpa的替代starter
spring-boot-starter-json 用于读写json
spring-boot-starter-jta-automikos 集成Automikos实现JTA事务
spring-boot-starter-jta-bitronix 集成Bitronix实现JTA事务(从2.3.0标识为Deprecated)
spring-boot-starter-mail 集成Java mail和Spring 框架的发邮件功能
spring-boot-starter-mustache 集成Mustache 视图构建 web应用
spring-boot-starter-security 集成Spring Security
spring-boot-starter-oauth2-client 集成Spring Security's OAuth2/OpenID连接客户端功能
spring-boot-starter-oauth2-resource-server 集成Spring Security's OAuth2资源服务器功能
spring-boot-starter-quartz 集成Quartz任务调度
spring-boot-starter-rsocket 构建RSocket客户端和服务端
spring-boot-starter-test 集成Junit Jupiter, Hamcrest 和Mockito 测试Spring Boot 应用和类库
spring-boot-starter-validation 集成Java Bean Validation 结合Hibernate Validator
spring-boot-starter-web 集成Spring MVC 构建RESTful web应用, 使用Tomcat作为默认内嵌服务器
spring-boot-starter-web-services 集成Spring Web Services
spring-boot-starter-webflux 集成Spring Reactive Web 构建WebFlux应用
spring-boot-starter-websocket 集成Spring Websocket 构建Websocket应用

而在我们手工创建Spring boot应用时, 由于我想创建的是一个RESTful风格的服务器, 所以我们选择spring-boot-starter-web, 测试starter选择spring-boot-starter-test.

接下来我们在build.gradle中添加这两个依赖.


dependencies {
    // This dependency is used by the application.
    implementation 'com.google.guava:guava:29.0-jre'
    implementation 'org.springframework.boot:spring-boot-starter-web'

    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    // Use JUnit Jupiter API for testing.
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'

    // Use JUnit Jupiter Engine for testing.
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.2'
}

这里不需要指定starter的版本, 但是我们要引入两个plugins, 在plugins中指定版本.

在plugin{}闭包中, 引入'org.springframework.boot' 和 'io.spring.dependency-management' 这两个plugin, 并分别指定版本 '2.7.6' 和 '1.0.15.RELEASE'


plugins {
    id 'java'
    id 'org.springframework.boot' version '2.7.6'
    id 'io.spring.dependency-management' version '1.0.15.RELEASE'
    id 'application'
}

4. 创建Idea工程

由于我的Intellij Idea版本较低, 对高版本的gradle支持不是很好, 不能支持直接导入高版本的gradle项目, 所以我需要引入idea plugin将项目手动转换成idea项目, 再导入Idea.


plugins {
    id 'java'
    // 添加idea plugin用于转换成idea工程
    id 'idea'
    id 'org.springframework.boot' version '2.7.6'
    id 'io.spring.dependency-management' version '1.0.15.RELEASE'
    id 'application'
}


./gradlew idea

5. 创建Controllers

现在,您可以为一个简单的web应用程序创建一个web控制器,如下所示

(src/main/java/comple/springboot/HelloController.java)所示:

package demo;

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

@RestController
public class HelloController {

    @GetMapping("/")
    public String index() {
        return "Greetings from Spring Boot!";
    }

}

6. 创建主函数


package demo;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.SpringApplication;

@SpringBootApplication
public class App {

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

$./gradlew bootRun

> Task :app:bootRun

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.7.6)

2022-12-21 08:57:07.468  INFO 23232 --- [           main] demo.App                                 : Starting App using Java 1.8.0_321 on eagle_hw with PID 23232 (C:\dev\proj\demo\app\build\classes\java\main started by eagle in C:\dev\proj\demo\app)
2022-12-21 08:57:07.468  INFO 23232 --- [           main] demo.App                                 : No active profile set, falling back to 1 default profile: "default"
2022-12-21 08:57:08.823  INFO 23232 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2022-12-21 08:57:08.829  INFO 23232 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2022-12-21 08:57:08.829  INFO 23232 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.69]
2022-12-21 08:57:08.963  INFO 23232 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2022-12-21 08:57:08.963  INFO 23232 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1456 ms
2022-12-21 08:57:09.240  INFO 23232 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2022-12-21 08:57:09.251  INFO 23232 --- [           main] demo.App                                 : Started App in 2.094 seconds (JVM running for 2.427)
2022-12-21 08:57:17.484  INFO 23232 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2022-12-21 08:57:17.484  INFO 23232 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2022-12-21 08:57:17.484  INFO 23232 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
<==========---> 80% EXECUTING [55s]
> :app:bootRun

访问RESTful api, 可以通过curl命令行工具访问, 也可以通过浏览器访问http://localhost:8080查看结果.


$curl localhost:8080
Greetings from Spring Boot!

至此一个简单的spring boot 应用就创建完成了.

7. 参考文档

Building an Application with Spring Boot

The gradle wrapper

What is settings.gradle in Gradle?

gradle中的build script详解

Spring Boot Starters是什么

54 个官方 Spring Boot Starters 出炉!别再重复造轮子了

posted on 2022-12-21 09:07  eagle.supper  阅读(635)  评论(0编辑  收藏  举报