Spring Boot Hello World的实现代码

本篇文章是SpringBoot最入门的介绍。我们不借助任何额外的工具,从无到有创建一个Spring Boot的web项目,并运行这个项目。

项目构建

归根结底,Spring Boot就只是一个框架,几个jar而已,没什么神奇的。但使用Spring Initializr创建项目的过程把很多信息屏蔽掉了,这样我们就很难搞清楚Spring Boot的本质是什么。下面仅使用maven从无到有构建一个Spring Boot的web项目。
先创建一个maven空工程如下所示,项目的名字叫spring-boot-hello。

<?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.poype</groupId>
  <artifactId>spring-boot-hello</artifactId>
  <version>1.0-SNAPSHOT</version>

  <dependencies>

  </dependencies>
</project>

现在这还是一个空的maven项目,我们可以在dependencies标签中添加我们需要的依赖,例如添加Spring Boot的依赖。但是Spring Boot为了减少配置,方便我们开发,提供了一个parent maven工程spring-boot-starter-parent,我们只要让我们的这个项目继承spring-boot-starter-parent工程,就能减少好多配置。修改我们的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.poype</groupId>
  <artifactId>spring-boot-hello</artifactId>
  <version>1.0-SNAPSHOT</version>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.4.RELEASE</version>
  </parent>

  <dependencies>

  </dependencies>
</project>

目前我们的这个maven项目还没有导入任何dependency,这点可以通过执行mvn dependency:tree命令确定。
我们要创建的是一个web项目,所以添加spring-boot-starter-web这个依赖。修改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.poype</groupId>
  <artifactId>spring-boot-hello</artifactId>
  <version>1.0-SNAPSHOT</version>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.4.RELEASE</version>
  </parent>

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

由于在spring-boot-starter-parent的dependencyManagement中已经用声明了spring-boot-starter-web,所以此处我们可以省略它的version配置。

再次执行mvn dependency:tree命令获得如下结果:

[INFO] Scanning for projects...
[INFO]
[INFO] --------------------< com.poype:spring-boot-hello >---------------------
[INFO] Building spring-boot-hello 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:3.1.1:tree (default-cli) @ spring-boot-hello ---
[INFO] com.poype:spring-boot-hello:jar:1.0-SNAPSHOT
[INFO] \- org.springframework.boot:spring-boot-starter-web:jar:2.1.4.RELEASE:compile
[INFO]  +- org.springframework.boot:spring-boot-starter:jar:2.1.4.RELEASE:compile
[INFO]  | +- org.springframework.boot:spring-boot:jar:2.1.4.RELEASE:compile
[INFO]  | +- org.springframework.boot:spring-boot-autoconfigure:jar:2.1.4.RELEASE:compile
[INFO]  | +- org.springframework.boot:spring-boot-starter-logging:jar:2.1.4.RELEASE:compile
[INFO]  | | +- ch.qos.logback:logback-classic:jar:1.2.3:compile
[INFO]  | | | +- ch.qos.logback:logback-core:jar:1.2.3:compile
[INFO]  | | | \- org.slf4j:slf4j-api:jar:1.7.26:compile
[INFO]  | | +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.11.2:compile
[INFO]  | | | \- org.apache.logging.log4j:log4j-api:jar:2.11.2:compile
[INFO]  | | \- org.slf4j:jul-to-slf4j:jar:1.7.26:compile
[INFO]  | +- javax.annotation:javax.annotation-api:jar:1.3.2:compile
[INFO]  | +- org.springframework:spring-core:jar:5.1.6.RELEASE:compile
[INFO]  | | \- org.springframework:spring-jcl:jar:5.1.6.RELEASE:compile
[INFO]  | \- org.yaml:snakeyaml:jar:1.23:runtime
[INFO]  +- org.springframework.boot:spring-boot-starter-json:jar:2.1.4.RELEASE:compile
[INFO]  | +- com.fasterxml.jackson.core:jackson-databind:jar:2.9.8:compile
[INFO]  | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.9.0:compile
[INFO]  | | \- com.fasterxml.jackson.core:jackson-core:jar:2.9.8:compile
[INFO]  | +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.9.8:compile
[INFO]  | +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.9.8:compile
[INFO]  | \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.9.8:compile
[INFO]  +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.1.4.RELEASE:compile
[INFO]  | +- org.apache.tomcat.embed:tomcat-embed-core:jar:9.0.17:compile
[INFO]  | +- org.apache.tomcat.embed:tomcat-embed-el:jar:9.0.17:compile
[INFO]  | \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:9.0.17:compile
[INFO]  +- org.hibernate.validator:hibernate-validator:jar:6.0.16.Final:compile
[INFO]  | +- javax.validation:validation-api:jar:2.0.1.Final:compile
[INFO]  | +- org.jboss.logging:jboss-logging:jar:3.3.2.Final:compile
[INFO]  | \- com.fasterxml:classmate:jar:1.4.0:compile
[INFO]  +- org.springframework:spring-web:jar:5.1.6.RELEASE:compile
[INFO]  | \- org.springframework:spring-beans:jar:5.1.6.RELEASE:compile
[INFO]  \- org.springframework:spring-webmvc:jar:5.1.6.RELEASE:compile
[INFO]    +- org.springframework:spring-aop:jar:5.1.6.RELEASE:compile
[INFO]    +- org.springframework:spring-context:jar:5.1.6.RELEASE:compile
[INFO]    \- org.springframework:spring-expression:jar:5.1.6.RELEASE:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.018 s
[INFO] Finished at: 2019-05-19T22:54:50+08:00
[INFO] ------------------------------------------------------------------------

可以看到在添加spring-boot-starter-web这个依赖后,有许多的jar都被导入了。

除了更多的spring-boot-starter-*被导入了之外,更重要的是很多Spring Framework的jar也被导入了,包括spring-core、spring-beans、spring-context、spring-aop等等。另外还有与tomcat相关的jar也被导入了,也就是说现在我们已经有了可以运行web程序的servlet容器了。

工程配置已经完成,新建一个HelloController测试类,输入如下代码:

package com.poype.springboot.web;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@EnableAutoConfiguration
public class HelloController {

  @RequestMapping("/hello")
  String home() {
    return "Hello World!";
  }

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

现在,我们已经完成了一个简单的web应用开发,可以启动我们这个应用了。

由于我们的工程继承了spring-boot-starter-parent的POM配置,它提供了启动spring-boot应用的相关插件(该插件的run目标用于启动应用),可以通过执行mvn spring-boot:run命令启动应用,得到如下运行结果。

从运行结果中可以看到,spring-boot启动了Tomcat服务器,并监听在8080端口。下面我们打开浏览器,输入地址http://localhost:8080/hello就可以看到程序运行结果。

应用打包

应用构建好之后,需要build出一个应用包才能用于生产部署。为此需要在POM配置中新增一个插件,修改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.poype</groupId>
  <artifactId>spring-boot-hello</artifactId>
  <version>1.0-SNAPSHOT</version>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.4.RELEASE</version>
  </parent>

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

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>

接着我们执行mvn clean package命令,可以在target目录下发现构建好的应用包 spring-boot-hello-1.0-SNAPSHOT.jar

执行java -jar ./target/spring-boot-hello-1.0-SNAPSHOT.jar命令就可以启动应用了。

Spring Boot是怎么做到的

上面的例子虽然非常简单,但却也是一个标准的spring web应用。我们可以回忆一下,如果没有Spring Boot,创建一个这样的web应用都需要哪些步骤呢?首先要在maven的POM中导入N多相关dependency(包括Spring的、servlet的、json的...)。然后添加各种复杂配置(包括servlet的、Spring的、Spring MVC的...)。最后写完代码build好一个war包,我们还需要下载一个Tomcat,并将war包放到tomcat下的指定路径,启动tomcat部署应用。这个过程即使是工作几年的老司机,从无到有创建一个项目估计也要十几分钟,如果是新手再遇到一些问题,解决起来就更麻烦了,可能几个小时也不一定能搞得出来。
使用Spring Boot构建应用,即便我们仅仅使用maven,也几乎没有什么配置。如果使用Spring Initializr的话,创建好工程无需任何配置就直接可以写代码了,非常的方便,即使是新手几分钟也能搞出来这个HelloWorld应用。这就是Spring Boot给我的最初印象,但是它是如何做到这些的呢?

约定大于配置

Spring Boot提供了很多Starter依赖,每种类型的Starter提供了这种类型应用可能需要的一系列dependency(利用maven间接依赖的特性)。例如我们这里创建的是一个web应用,所以我们的项目依赖spring-boot-starter-web,而spring-boot-starter-web会将web开发可能需要的依赖全部帮我们导入,省去很多配置的工作。spring-boot-starter-parent是一个特殊的starter,它提供了许多maven默认配置,如dependenceManagment。
另一个比较重要的是注解@EnableAutoConfiguration,Spring Boot看到这个注解,会根据已经加入的jar dependency执行相关的配置。例如在我们的工程中有Spring MVC和Tomcat的依赖,Spring Boot就会猜到这是一个WEB工程,它就会对项目执行相应的配置(如Spring MVC和Servlet的配置)。

应用启动

Spring Boot自带了一个Tomcat容器,省去我们自己安装和配置容器的工作。为了了解Spring Boot的启动过程,我们将build好的jar解压得到的目录结构如下图所示:

其中最主要的配置文件是MANIFEST.MF,在执行java -jar *.jar启动命令时,JVM参考的就是这个文件的配置。其文件内容如下:

Manifest-Version: 1.0
Implementation-Title: spring-boot-hello
Implementation-Version: 1.0-SNAPSHOT
Built-By: poype
Implementation-Vendor-Id: com.poype
Spring-Boot-Version: 2.1.4.RELEASE
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.poype.springboot.web.HelloController
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Created-By: Apache Maven 3.6.1
Build-Jdk: 1.8.0_211
Implementation-URL: https://projects.spring.io/spring-boot/#/spring-bo
 ot-starter-parent/spring-boot-hello

Main-Class是jar包中的启动类,可以看到是一个叫org.springframework.boot.loader.JarLauncher类,是Spring Boot提供的Launcher类。Start-Class是我们自己编写的含有main方法的类。Spring-Boot-Classes是应用自己类的路径,Spring-Boot-Lib是应用依赖的第三方包的路径。

看到这里我们可以大概总结一下(仅仅是YY,目前理解还不够深入),Spring Boot实现了一套自己的部署路径规范(应用自己的类放在哪里,应用依赖的第三方jar放在哪里等等),就像J2EE规范一样。然后利用tomcat的jar实现servlet容器的功能,对WEB请求进行处理。

可以说Spring Boot利用tomcat打造了一个全新的平台,这个平台也仅仅只在servlet容器部分利用到了tomcat的功能,至于部署规范和加载机制,都是Spring Boot自己全新实现的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • IntelliJ IDEA 创建spring boot 的Hello World 项目(图解)

    1.Open IDEA,choose "New-->Project" 2.Choose "Spring Initializr" 3. Choose java 1.7 version,then next 4. Choose "Web" 5. Fill out the project name,and choose the project location 6. 将" .mvn mvnw mvnw.cmd"文件删掉 7. s

  • Spring Boot实战之逐行释义Hello World程序

    一.前言 研究Spring boot也有一小段时间了,最近会将研究东西整理一下给大家分享,大概会有10~20篇左右的博客,整个系列会以一个简单的博客系统作为基础,因为光讲理论很多东西不是特别容易理解,并且如果每次通过一个简单的小程序也无法系统的把握好一些知识点,所以就以一个简单的系统作为基础来讲,看看通过spring boot如何实现一个完整系统.本系列除了Spring boot基本的知识点之外,还会涉及到Spring boot与数据库.缓存(redis).消息队列等的结合以及多实例部署等方面的

  • Spring Boot 之HelloWorld开发案例

    1.开发工具安装 在Eclipse上安装插件:spring Tool Suite(简称STS) 2.开发实例 1).创建项目 File > New > Spring Starter Project 项目创建完成: 2).生成的源码解读 SpringBootSimpleApplication类: package com.example; import org.springframework.boot.SpringApplication; import org.springframework.bo

  • spring boot application properties配置实例代码详解

    废话不多说了,直接给大家贴代码了,具体代码如下所示: # =================================================================== # COMMON SPRING BOOT PROPERTIES # # This sample file is provided as a guideline. Do NOT copy it in its # entirety to your own application. ^^^ # ========

  • Spring Boot定时任务的使用实例代码

    Spring Boot中配置定时任务极其简单......下面看下实例代码: import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import java.text.SimpleD

  • Angular+Bootstrap+Spring Boot实现分页功能实例代码

    需要用到的js angular.js(用angular.min.js会导致分页控件不显示) ui-bootstrap-tpls.min.js angular-animate.js 需要用到的css bootstrap.min.css 由于本项目使用了路由,所以讲js以及css文件的应用都放在一个主html,请同学们在html页面中添加以上文件 在开始之前,我先简单介绍下分页的原理. 分页的实质其实就是一条sql语句, 比如查找第二页,即第16到第30条数据 在MySQL中是select * fr

  • Spring Boot整合mybatis(一)实例代码

    sprig-boot是一个微服务架构,加快了spring工程快速开发,以及简便了配置.接下来开始spring-boot与mybatis的整合. 1.创建一个maven工程命名为spring-boot-entity,pom.xml文件配置如下: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:s

  • spring boot整合Swagger2的示例代码

    Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化RESTful风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步.Swagger 让部署管理和使用功能强大的API从未如此简单. 1.代码示例 1).在pom.xml文件中引入Swagger2 <dependency> <groupId>io.springfox</groupId> <artifa

  • spring boot aop 记录方法执行时间代码示例

    本文研究的主要是spring boot aop 记录方法执行时间的实现代码,具体如下. 为了性能调优,需要先统计出来每个方法的执行时间,直接在方法前后log输出太麻烦,可以用AOP来加入时间统计 添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency&

  • Spring Boot集成Mybatis的实例代码(简洁版)

    概述 现在互联网应用中,大部分还是使用Mybatis来操作数据库的,本文介绍一下Spring Boot中如何集成Mybatis. 上篇介绍了Spring Boot 直接用jar运行项目的方法,需要的朋友点击查看. 创建Spring Boot工程 在 Spring Boot 开篇-创建和运行 一文中有一个小节介绍了如何使用Spring Boot的组件来创建工程.如果要集成Mybatis,只需要把Mysql和Mybatis这两个组件勾选一下即可. 当然也可以不通过这种方式,直接在POM.xml文件中

  • Spring Boot集成Kafka的示例代码

    本文介绍了Spring Boot集成Kafka的示例代码,分享给大家,也给自己留个笔记 系统环境 使用远程服务器上搭建的kafka服务 Ubuntu 16.04 LTS kafka_2.12-0.11.0.0.tgz zookeeper-3.5.2-alpha.tar.gz 集成过程 1.创建spring boot工程,添加相关依赖: <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&qu

  • spring boot多数据源动态切换代码实例

    这篇文章主要介绍了spring boot多数据源动态切换代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 当项目中存在多数据源时,就涉及到数据源的动态切换,通过研究,特此记录一下. 1.maven依赖 <!--数据库连接--> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> &

  • spring boot项目导入依赖后代码报错问题的解决方法

    代码截图如图所示(由于本人问题已经解决,没来得及截图,所以在网上找了一张图片) ​ 针对图中所示的情况,可参考一下解决方案: 方案一: 在 Idea 导入 Spring Boot 项目代码报红,试过更改maven配置,maven clean操作,执行-U idea:idea等命令还是提示:cannot resolve symbol 'SpringBootApplication' .我最终解决方法是导入要导入项目的pom.xml文件,而不是导入现有项目解决.选择pom.xml后会弹出提示框,选择a

随机推荐