Spring Boot快速开始及核心功能入门篇

318 阅读8分钟

一、Spring Boot微服务开发利器


1、什么是微服务,微服务和微服务架构的区别

目前而已,对于微服务,业界没有一个统一的标准定义,但是通常而言提倡把一个单一的应用程序划分为一组小的服务,每个小的服务都会运行在自己的进程中,服务之间通过轻量级的通信机制(http的rest api)进行通信,这些一个个的小服务就是微服务。

单体架构与微服务架构图示:

传统的单一电商应用,订单、支付、用户、商品、库存等模块都在一个项目中,若某一个模块出现线上bug,会导致整个版本发布回退

若把单一应用拆分为一个个微服务,比如订单微服务、用户微服务、商品微服务、积分微服务等,若某一个微服务出错不会导致整个版本的回退

2、什么是微服务架构

微服务架构是一种架构模式(用于服务管理微服务的),它把一组小的服务互相协调、互相配合,并且 完成功能。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相协作(通常是基 于HTTP协议的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外,应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。

3、微服务的优缺点

1)优点:

  • 每个服务足够内聚,足够小,代码容易理解,这样能聚焦一个指定的业务功能或业务需求(职责单一)
  • 开发简单、开发效率提高,一个服务可能就是专一的只干一件事,微服务能够被小团队单独开发,这个小团队是2到5人的开发人员组成
  • 微服务能使用不同的语言开发
  • 易于和第三方集成,微服务允许容易且灵活的方式集成自动部署,通过持续集成工具,如Jenkins,Hudson,bamboo
  • 微服务只是业务逻辑的代码,不会和HTML,CSS或其他界面组件混合
  • 每个微服务都有自己的存储能力,可以有自己的数据库。也可以有统一的数据库
  • ......

2)缺点:

  • 开发人员要处理分布式系统的复杂性(分布式事物)
  • 多服务运维难度,随着服务的增加,运维的压力也在增大
  • 系统部署依赖增加
  • 服务间通信成本
  • 数据一致性
  • ......

二、Spring Boot快速开始


1、基于maven版本构建

1)先把maven的配置文件(setting.xml)设置为如下格式:

<profile> 
    <id>jdk‐1.8</id>
    <activation>
        <activeByDefault>true</activeByDefault>
        <jdk>1.8</jdk>
    </activation>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
    </properties>
</profile>

2)配置IDE的环境(maven环境)

3)创建一个空的maven工程,然后导入Spring Boot相关的jar包

<!-- 父工程依赖 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.0.RELEASE</version>
    <relativePath/>
</parent>

<!-- springmvc web依赖 -->
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

<!-- 引入一个spring boot插件,可以将web应用程序打成可运行jar包 -->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

4)编写主入口程序

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

5)其它业务组件,比如controller、service、repository、component注解标注的组件以及自己写的组件==必须放在主启动类所在包及其子包下==,否则扫描不到

@Controller
public class HelloController {
    @RequestMapping(value = "hello")
    @ResponseBody
    public String hello(){
        return "hello springboot";
    }
}

6)运行main函数启动程序,访问http://localhost:8080/hello,或者执行mvn package将项目打成jar包,用java -jar xxx.jar直接运行

2、通过sts或idea创建一个Spring Boot项目

编写自己的业务代码,之后的操作与maven构建springboot工厂类似

3、helloworld探究

1)pom文件分析

为什么引入了spring-boot-starter-parent和spring-boot-starter-web就可以快速开发mvc的项目?

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

<!-- 真正管理版本的是spring-boot-starter-parent的父工程,俗称版本仲裁中心,来决定应用的版本 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.2.0.RELEASE</version>
    <relativePath>../../spring-boot-dependencies</relativePath>
</parent>

以后我们导入依赖默认是不需要写版本;(没有在dependencies里面管理的依赖自然需要声明版本号)

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

spring-boot-starter-web:Spring Boot场景启动器;帮我们导入了web开发需要的jar包依赖

Spring Boot将所有的功能场景都抽取出来,做成一个个的starter,我们只需要在项目里面引入这些starter,相关场景的所有依赖都会导入进来

2)主程序类,主入口类

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

==@SpringBootApplication==:标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用

@SpringBootApplication是一个组合注解,其里面主要包含三个注解:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {}

==@SpringBootConfiguration==:Spring Boot的配置类,标注在某个类上,表示这是一个Spring Boot的配置类

@SpringBootConfiguration注解本质是一个@Configuration注解

@Configuration(
    proxyBeanMethods = false
)
public @interface SpringBootConfiguration {}

==@Configuration==:用来标注配置类(配置文件),配置类也是容器中的一个组件(@Component)

@Component
public @interface Configuration {}

==@Component==:将这个类标注为组件,纳入spring ioc容器管理

==@EnableAutoConfiguration==:开启自动配置功能

@EnableAutoConfiguration是一个组合注解,其里面主要包含两个注解:

@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {}

==@AutoConfigurationPackage==:自动配置包

@Import({Registrar.class})
public @interface AutoConfigurationPackage {}

==@Import({Registrar.class})==:Spring的底层注解,给容器导入一个组件,导入的组件为AutoConfigurationPackages.Registrar.class,==其作用是将主配置类所在包及下面所有子包里面的所有组件扫描到Spring容器==

==@Import({AutoConfigurationImportSelector.class})==:将所有需要导入的组件添加到容器中并配置好这些组件(后面自动装配原理会细说)

==Spring Boot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,根据项目导入的场景启动器过滤这些自动配置类,满足条件的配置类就生效,帮我们进行自动配置工作==

4、多profile切换

在开发应用时,通常一个项目会被部署到不同的环境中,比如:开发、测试、生产等。其中每个环境的数据库地址、服务器端口等等配置都会不同,对于多环境的配置,大部分构建工具或是框架解决的基本思路是一致的,通过配置多份不同环境的配置文件,再通过打包命令指定需要打包的内容之后进行区分打包

1)yml支持多模块文档块

server:
  servlet:
    context-path: /springbootMultiProfiles

spring:
  profiles:
    active: test

---
# 开发环境配置
spring:
  profiles: dev

server:
  port: 8081
---
# 生产环境配置
spring:
  profiles: prod

server:
  port: 8082
---
# 测试环境配置
spring:
  profiles: test

server:
  port: 8083

2)多yml|properties文件的环境切换

application.yml

# 用于激活不同环境的配置文件
spring:
  profiles:
    active: test

application-dev.yml

# 开发环境配置
server:
  port: 8081

application-prod.yml

# 生产环境配置
server:
  port: 8082

application-test.yml

# 测试环境配置
server:
  port: 8083

3)激活指定环境配置的方法

  • 直接在application.yml的配置文件中使用==spring.profiles.active=dev|prod|test==
  • 设置虚拟机参数:==-Dspring.profiles.active=dev|prod|test==
  • 命令行参数启动(打成Jar包时候):==java -jar xxx.jar --spring.profiles.active=prod==

4)设置jvm参数,然后检查是否设置成功

java -Xms128m -Xmx128m -jar xxx.jar -- server.port=8888

第一步:在cmd窗口中使用jps来看我们的主进程,查找对应的主启动类进程号

第二部:使用jinfo命令 + 进程号来查看具体信息

5、Spring Boot关于打包问题总结

1)打成指定名称的jar包

<build>
    <!-- 指定打包的文件名称 -->
    <finalName>cyanboot4MultiProfiles</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

2)若工程中出现多个mainclass的时候需要指定主启动类

<build>
    <!-- 指定打包的文件名称 -->
    <finalName>cyanboot4MultiProfiles</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <!-- 指定主启动类 -->
            <configuration>
                <mainClass>com.cyan.CyanSpringbootMultiProfilesApplication</mainClass>
            </configuration>
        </plugin>
    </plugins>
</build>

3)如何打出一个war包

第一步:指定Spring Boot项目中pom文件中的打包方式为war

<packaging>war</packaging>

第二步:把内嵌的tomcat作用域改为provided(只在编译和测试的时候使用)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>

第三步:主启动类上实现SpringBootServletInitializer接口,重写confiure方法

@SpringBootApplication
public class CyanSpringbootWarApplication extends SpringBootServletInitializer {

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

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(CyanSpringbootWarApplication.class);
    }
}

第四步:打成war包 放在tomcat上运行

6、Spring Boot的web开发