今天看啥  ›  专栏  ›  since1986

Spring Cloud与微服务学习笔记-关于Spring Boot

since1986  · 掘金  · Java  · 2018-03-24 11:47

背景

虽然「Spring Cloud与微服务学习笔记」系列文章是针对Spring Cloud这一主题的,但是,由于Spring Cloud是依赖于Spring Boot的,而且,Spring Boot也为构建基于Spring Cloud的微服务程序提供了很多基础性的支持,因此,可以说,Spring Boot是Spring Cloud必不可少的基石,同时也是Spring Cloud背后的英雄。所以,在开始介绍Spring Cloud之前,我们专门拿出一篇文章的篇幅来简要介绍一下Spring Boot。

理论知识

“那么,我以前已经用Spring + Spring MVC用的很6了,这个Spring Boot又是什么鬼,我为什么要花时间来了解它、学习它呢?”

其一,正如前文所讲,Spring Cloud依赖于Spring Boot,所以要想开发基于Spring Cloud的程序,不得不用Spring Boot;其二,即便你说:“我用不着开发Spring Cloud程序”,那我也还是建议你了解一下Spring Boot,因为,它能彻底改变你开发与部署web应用的思路。闲言少叙,Spring Boot是什么呢,他又能提供给我什么好处呢?关于这一点,我们来看官方的介绍吧:

Spring Boot makes it easy to create Spring-powered, production-grade applications and services with absolute minimum fuss. It takes an opinionated view of the Spring platform so that new and existing users can quickly get to the bits they need.

You can use Spring Boot to create stand-alone Java applications that can be started using java -jar or more traditional WAR deployments. We also provide a command line tool that runs spring scripts.

Our primary goals are:

  • Provide a radically faster and widely accessible getting started experience for all Spring development

  • Be opinionated out of the box, but get out of the way quickly as requirements start to diverge from the defaults

  • Provide a range of non-functional features that are common to large classes of projects (e.g. embedded servers, security, metrics, health checks, externalized configuration)

  • Absolutely no code generation and no requirement for XML configuration

我在这里大致翻译一下(意译),请对应原文查看:

用Spring Boot,你能够轻松创建基于Spring的、约定大于配置的、独立运行的,生产级应用。

你可以用Spring Boot来写基于jar部署启动的应用或者是传统的war应用。 同时我们还提供给你一个运行“spring scripts”的命令行工具。

我们的主要愿景是:

  • 提供给所有的Spring开发者更爽的”getting started”体验。

  • 开箱即用,精简配置过程。

  • 内置好了一些在很多项目中都会需要的通用特性,如嵌入式服务器,安全,指标,健康检查,外部化配置。

  • 绝对不用代码生成和XML配置。

其实归根结底,用一张图就可以说明了:

我自己从去年11月份开始接触Spring Boot,到现在大约5个月的时间,我自己直观的感受就是:”我再也不想用回到原来的Spring + Spring MVC了”,这5个月时间我大概也体会到了Spring Boot的一些特点:

  • 配置的确简化了相当多,无论是代码中的配置还是构建工具的配置,都简化了
  • 彻底打破了开发与部署时的思维定式,原来搞得都是war,需要繁琐的,配置服务器与部署的过程,现在咱开发的产品都是jar了,或者说是一个独立的进程的命令行程序了,再不依赖于应用服务器了,这一点可以说是web开发的一个飞跃
  • 自己掌控main()方法,基于这一点我们可以玩出很多花样来,main()大法好啊 (关于这一点,可以参考我的另一篇文章)

实际操作

“夸归夸,卖归卖,你说了这莫多Spring Boot的好处,倒是写一个看看啊。”

作为程序员,我们最关心的就是怎样上手了,那么我们就通过简单的例子来演示一下Spring Boot的基本使用吧。就拿一个最普通的CRUD来做演示吧,在开始Spring Boot之前,我们先来温习一下Spring + Spring MVC,温故而知新,同时也是拿它来做一个对比的基准。

“CRUD” 之 Spring + Spring MVC版

限于篇幅,过多的代码我就不贴出来了,我将这个demo工程放到了github上,到那里去看吧。
我在这里简要介绍一下我习惯的普通的Spring + Spring MVC工程开发的一般路数吧:

我一般会用的全Java配置的方式,并且使用Gradle构建。所以我会首先集齐所有依赖项放入Gradle的dependencies(集齐七个依赖可以召唤神龙 😀)

group 'com.githu.since1986.learn.boot'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'war'

sourceCompatibility = 1.8

repositories {
    maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
    mavenCentral()
}

dependencies {
    compile group: 'org.springframework', name: 'spring-webmvc', version: '4.3.14.RELEASE'
    compile group: 'org.springframework', name: 'spring-tx', version: '4.3.14.RELEASE'
    compile group: 'org.springframework', name: 'spring-jdbc', version: '4.3.14.RELEASE'

    compile group: 'org.mybatis', name: 'mybatis-spring', version: '1.3.2'
    compile group: 'org.mybatis', name: 'mybatis', version: '3.4.6'

    compile group: 'org.apache.tomcat', name: 'tomcat-servlet-api', version: '8.5.29'

    compile group: 'org.apache.commons', name: 'commons-dbcp2', version: '2.2.0'

    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.4'

    compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.46'
}

然后,配置好所有配置项,我一般按照这样的路数配置:

.
├── java
│   └── com
│       └── github
│           └── since1986
│               └── learn
│                   └── boot
│                       └── step1
│                           ├── AppConfig.java 根配置
│                           ├── AppConstants.java 全局常量
│                           ├── AppInitializer.java Mvc初始化器
│                           ├── MyBatisConfig.java MyBatis根配置
│                           ├── controller 控制器包
│                           │   ├── AppExceptionHandler.java Mvc全局异常处理
│                           │   ├── ServletConfig.java Mvc配置
│                           │   └── TestController.java
│                           ├── mapper Mapper接口包
│                           │   ├── MapperConfig.java Mapper配置
│                           │   └── TestMapper.java Mapper接口
│                           ├── model Model类包
│                           │   └── TestModel.java
│                           └── service Service包
│                               ├── ServiceConfig.java Service配置
│                               ├── TestService.java
│                               └── TestServiceImpl.java
└── resources
    ├── com
    │   └── github
    │       └── since1986
    │           └── learn
    │               └── boot
    │                   └── step1
    │                       └── mapper
    │                           └── TestMapper.xml Mapper接口对应的配置文件
    └── import.sql #数据库初始化脚本

再然后,调试、打包、部署tomcat,这几个步骤可由各类开发、调试、部署、构建工具来进行,在此不仔细展开了。到此基本上就完成了传统的基于Spring + Spring MVC的项目的初始化工作

“CRUD” 之 Spring Boot版

我们再来看Spring Boot版的CRUD,同样,代码在github上

基于Spring Boot开发与传统的Spring —— Spring MVC开发的一个不同点是在构建工具中提供了组合型依赖项,也就是所谓”starter”,一个”starter”就能替代原来许多个独立的依赖项,这样我们就不用刻意去凑这些依赖了:

group 'com.github.since1986.learn.boot'
version '1.0-SNAPSHOT'

apply plugin: 'application'
apply plugin: 'org.springframework.boot'
apply plugin: 'propdeps'
apply plugin: 'propdeps-maven'
apply plugin: 'propdeps-idea'

sourceCompatibility = 1.8

buildscript {
    repositories {
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
        maven { url 'http://repo.spring.io/plugins-release' }
        mavenCentral()
    }
    dependencies {
        classpath "org.springframework.boot:spring-boot-gradle-plugin:1.5.9.RELEASE"
        classpath "io.spring.gradle:propdeps-plugin:0.0.9.RELEASE"
    }
}

repositories {
    maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
    mavenCentral()
}

dependencies {
    optional group: 'org.springframework.boot', name: 'spring-boot-configuration-processor'

    compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.5.9.RELEASE' #注意这里的starter,可以和上边的传统MVC工程对比一下

    compile group: 'org.mybatis.spring.boot', name: 'mybatis-spring-boot-starter', version: '1.3.1'

    compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.46'
}
compileJava.dependsOn(processResources)

jar {
    manifest {
        attributes(
                "Manifest-Version": "1.0",
                "Class-Path": '. ' + configurations.compile.collect { it.getName() }.join(' ')
        )
    }
}

我们再来看Spring Boot的配置项,可以看到,有一个名为”application.yml”的配置文件,这个是Spring Boot”约定优先于配置”的一个很好体现,在这个约定好的配置文件中,使用约定好的配置项进行配置,能省去原来很多需要自己定义的Java配置类,比如dbcp的DataSource,这一点是Spring Boot与传统Spring + Spring MVC程序在配置上的最大不同,其他的配置类的模式你仍然可以保持原样

.
├── java
│   └── com
│       └── github
│           └── since1986
│               └── learn
│                   └── boot
│                       └── step1
│                           ├── App.java Boot主启动类
│                           ├── AppConfig.java 主配置
│                           ├── AppProperties.java 自定义属性配置类
│                           ├── MvcConfig.java Mvc配置
│                           ├── controller 控制器包
│                           │   ├── AppExceptionHandler.java Mvc全局异常处理
│                           │   └── TestController.java
│                           ├── mapper Mapper包
│                           │   ├── MapperConfig.java Mapper配置
│                           │   └── TestMapper.java Mapper接口
│                           ├── model Model包
│                           │   └── TestModel.java
│                           └── service Service包
│                               ├── ServiceConfig.java Service配置
│                               ├── TestService.java
│                               └── TestServiceImpl.java
└── resources
    ├── application.yml Boot主配置文件
    ├── com
    │   └── github
    │       └── since1986
    │           └── learn
    │               └── boot
    │                   └── step1
    │                       └── mapper
    │                           └── TestMapper.xml Mapper接口对应的配置文件
    └── import.sql 数据库初始化文件

然后再来看部署方面,注意我在构建脚本里的apply plugin: 'application'这个Gradle plugin,这是一个用来将普通的带有main()方法的Java应用打成带有操作系统适应的启动脚本的命令行程序的插件,也就是我们的应用是能以独立进程的方式跑的,这一点是个很大的进步,无需关心宿主应用服务器的配置是怎样的了,因为压根就没有宿主环境了。
同时,请注意App.java

package com.github.since1986.learn.boot.step1;

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

@SpringBootApplication
public class App {

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

这么多年的web开发,我们几乎都忘记了那曾经拥有main()方法的纯真快乐时光了,只记住了一直霸气的老黄猫😆,现在main()又回到了我们的身边,善待它吧,因为有了它,我们能做出很多了不起的事。

总结

在这篇文章中,我们简要的介绍了一下Spring Cloud的基石Spring Boot的概念与使用,为以后了解Spring Cloud打好了基础,在下一篇文章「Spring Cloud与微服务学习笔记-基本概念」中,我们将真正开始Spring Cloud之旅。

参考资料

用Spring Boot颠覆Java应用开发

Spring Boot 官方文档




原文地址:访问原文地址
快照地址: 访问文章快照