天天看點

【架構】Spring Boot 2.0 介紹 + 問題彙總(包括:異步非阻塞)(未完結)

  • 提問:什麼是 Spring Boot?

    Spring Boot 是 Spring 開源組織下的子項目,是【Spring 元件一站式解決方案】,主要是簡化了使用 Spring 的難度,簡省了繁重的配置,提供了各種啟動器,開發者能快速上手。

    更多 Spring Boot 詳細介紹請看這篇文章《什麼是Spring Boot?》。

——————————————————————————————

  • 提問:Spring Boot優點?

    獨立運作

    簡化配置

    自動配置

    無代碼生成和XML配置

    應用監控

    上手容易

——————————————————————————————

  • 提問:Spring Boot 的核心配置檔案有哪幾個?它們的差別是什麼?

Spring Boot 的核心配置檔案是

application

bootstrap

配置檔案。

Spring Boot 中有兩種【上下文】一種是

bootstrap

, 另外一種是

application

bootstrap

是【應用程式】的父上下文,也就是說

bootstrap

加載優先于

applicaton

bootstrap

主要用于從額外的資源來加載配置資訊,還可以在本地外部配置檔案中解密屬性。

是以,對比 application 配置檔案,bootstrap 配置檔案具有以下幾個特性。

  • boostrap 由

    父 ApplicationContext

    加載,比

    applicaton

    優先加載;
  • boostrap 裡面的屬性不能被覆寫;

bootstrap/ application 的應用場景:

application

配置檔案這個容易了解,主要用于 Spring Boot 項目的自動化配置。

bootstrap

配置檔案有以下幾個應用場景:

使用

Spring Cloud Config

配置中心時,這時需要在

bootstrap

配置檔案中添加連接配接到配置中心的配置屬性來加載外部配置中心的配置資訊;

  • 一些固定的不能被覆寫的屬性
  • 一些加密/解密的場景;

——————————————————————————————

  • 提問:Spring Boot 的配置檔案有哪幾種格式?它們有什麼差別?

    .properties 和 .yml,它們的差別主要是書寫格式不同。

1).properties
app.user.name = javastack

2).yml
app:
  user:
    name: javastack
           

另外,.yml 格式不支援 @PropertySource 注解導入配置。

——————————————————————————————

  • 提問:Spring Boot 的核心注解是哪個?它主要由哪幾個注解組成的?

    啟動類上面的注解是

    @SpringBootApplication

    ,它也是 Spring Boot 的核心注解,主要組合包含了以下 3 個注解:

    @SpringBootConfiguration

    :組合了 @Configuration 注解,實作配置檔案的功能。

    @EnableAutoConfiguration

    :打開自動配置的功能,也可以關閉某個自動配置的選項,如關閉資料源自動配置功能: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。

    @ComponentScan

    :Spring元件掃描。

——————————————————————————————

  • 提問:開啟 Spring Boot 特性有哪幾種方式?

    1)繼承spring-boot-starter-parent項目

    2)導入spring-boot-dependencies項目依賴

    具體請參考這篇文章《Spring Boot開啟的2種方式》。

——————————————————————————————

  • 提問:Spring Boot 需要獨立的容器運作嗎?

    可以不需要,内置了 Tomcat/ Jetty 等容器。

——————————————————————————————

  • 提問:運作 Spring Boot 有哪幾種方式?

    1)打包用指令或者放到容器中運作

    2)用 Maven/ Gradle 插件運作

    3)直接執行 main 方法運作

——————————————————————————————

  • 提問:Spring Boot 自動配置原理是什麼?

    注解 @EnableAutoConfiguration, @Configuration, @ConditionalOnClass 就是自動配置的核心,首先它得是一個配置檔案,其次根據類路徑下是否有這個類去自動配置。

    具體看這篇文章《Spring Boot自動配置原理、實戰》。

——————————————————————————————

  • 提問:Spring Boot 的目錄結構是怎樣的?
cn
 +- javastack
     +- MyApplication.java
     |
     +- customer
     |   +- Customer.java
     |   +- CustomerController.java
     |   +- CustomerService.java
     |   +- CustomerRepository.java
     |
     +- order
         +- Order.java
         +- OrderController.java
         +- OrderService.java
         +- OrderRepository.java
           

這個目錄結構是主流及推薦的做法,而在主入口類上加上

@SpringBootApplication

注解來開啟 Spring Boot 的各項能力,如自動配置、元件掃描等。具體看這篇文章《Spring Boot 主類及目錄結構介紹》。

——————————————————————————————

  • 提問:你如何了解 Spring Boot 中的 Starters?

    Starters可以了解為啟動器,它包含了一系列可以內建到應用裡面的依賴包,你可以一站式內建 Spring 及其他技術,而不需要到處找示例代碼和依賴包。如你想使用 Spring JPA 通路資料庫,隻要加入 spring-boot-starter-data-jpa 啟動器依賴就能使用了。

    Starters包含了許多項目中需要用到的依賴,它們能快速持續的運作,都是一系列得到支援的管理傳遞性依賴。

——————————————————————————————

  • 提問:如何在 Spring Boot 啟動的時候運作一些特定的代碼?

    可以實作接口 ApplicationRunner 或者 CommandLineRunner,這兩個接口實作方式一樣,它們都隻提供了一個 run 方法,具體請看這篇文章《Spring Boot Runner啟動器》。

——————————————————————————————

  • 提問:Spring Boot 有哪幾種讀取配置的方式?

    Spring Boot 可以通過 @PropertySource,@Value,@Environment, @ConfigurationProperties 來綁定變量,具體請看這篇文章《Spring Boot讀取配置的幾種方式》。

——————————————————————————————

  • 提問:Spring Boot 支援哪些日志架構?推薦和預設的日志架構是哪個?

    Spring Boot 支援 Java Util Logging, Log4j2, Lockback 作為日志架構,如果你使用 Starters 啟動器,Spring Boot 将使用 Logback 作為預設日志架構,具體請看這篇文章《Spring Boot日志內建》。

——————————————————————————————

  • 提問:SpringBoot 實作熱部署有哪幾種方式?

    主要有兩種方式:

Spring Loaded

Spring-boot-devtools

Spring-boot-devtools 使用方式可以參考這篇文章《Spring Boot實作熱部署》。

——————————————————————————————

  • 提問:你如何了解 Spring Boot 配置加載順序?

    在 Spring Boot 裡面,可以使用以下幾種方式來加載配置。

    1)properties檔案;

    2)YAML檔案;

    3)系統環境變量;

    4)指令行參數;

    等等……

    具體請看這篇文章《Spring Boot 配置加載順序詳解》。

——————————————————————————————

  • 提問:Spring Boot 如何定義多套不同環境配置?

    提供多套配置檔案,如:

    applcation.properties

    application-dev.properties

    application-test.properties

    application-prod.properties

運作時指定具體的配置檔案,具體請看這篇文章《Spring Boot Profile 不同環境配置》。

——————————————————————————————

  • 提問:Spring Boot 可以相容老 Spring 項目嗎,如何做?

    可以相容,使用 @ImportResource 注解導入老 Spring 項目配置檔案。

——————————————————————————————

  • 提問:保護 Spring Boot 應用有哪些方法?

在生産中使用HTTPS

使用Snyk檢查你的依賴關系

更新到最新版本

啟用CSRF保護

使用内容安全政策防止XSS攻擊

更多請看這篇文章《10 種保護 Spring Boot 應用的絕佳方法》。

——————————————————————————————

  • 提問:Spring Boot 2.X 有什麼新特性?與 1.X 有什麼差別?

配置變更

JDK 版本更新

第三方類庫更新

響應式 Spring 程式設計支援

HTTP/2 支援

配置屬性綁定

更多改進與加強…

——————————————————————————————

  • 提問:Spring和Spring Boot有什麼差別?

Spring Framework提供了多種功能,使Web應用程式的開發更加容易。這些功能包括依賴注入,資料綁定,面向方面的程式設計,資料通路等等。

多年來,Spring一直在變得越來越複雜,這樣的應用程式所需的配置量可能會令人生畏。這就是Spring Boot派上用場的地方 - 它使配置Spring應用程式變得輕而易舉。

從本質上講,盡管Spring是不受歡迎的, Spring Boot 會對 平台和庫有一個看法,讓我們快速入門。

以下是Spring Boot帶來的兩個最重要的好處:

根據在類路徑中找到的工件自動配置應用程式

提供生産中應用程式通用的非功能性功能,例如安全性或健康檢查

請檢視我們的其他教程之一,了解vanilla Spring和Spring Boot之間的詳細比較。

——————————————————————————————

  • 提問:我們如何使用Maven設定Spring Boot應用程式?

我們可以像在任何其他庫中一樣在Maven項目中包含Spring Boot。但是,最好的方法是從 spring-boot-starter-parent 項目繼承并聲明依賴于Spring Boot啟動器。這樣做可以讓我們的項目重用Spring Boot的預設設定。

繼承 spring-boot-starter-parent 項目非常簡單 - 我們隻需要在 pom.xml中 指定一個 父元素:

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

我們可以在Maven Central找到最新版本的

spring-boot-starter-parent

使用啟動父項目很友善,但并不總是可行。 例如,如果我們公司要求所有項目都從标準POM繼承,我們就不能依賴Spring Boot的啟動父級。

在這種情況下,我們仍然可以通過此

POM

元素獲得依賴關系管理的好處:

<dependencyManagement> 
  <dependencies>
     <dependency> 
       <groupId>org.springframework.boot</groupId> 
       <artifactId>spring-boot-dependencies</artifactId> 
       <version>2.1.1.RELEASE</version> 
       <type>pom</type>
       <scope>import</scope> 
   </dependency> 
  </dependencies>
</dependencyManagement>
           

最後,我們可以為Spring Boot啟動器添加一些依賴項,然後我們就可以了。

——————————————————————————————

  • 提問:有什麼Spring Boot啟動器可供選擇嗎?

依賴管理是任何項目的關鍵方面。當一個項目足夠複雜時,管理依賴項可能會變成一場噩夢,因為涉及太多的工件。

這就是Spring Boot入門者派上用場的地方。每個入門者都可以作為我們所需的所有Spring技術的一站式服務。然後,以一緻的方式傳遞和管理其他所需的依賴關系。

所有啟動器都在

org.springframework.boot

組下,其名稱以

spring-boot-starter-

開頭 。 這種命名模式使得查找啟動器變得很容易,尤其是在使用支援按名稱搜尋依賴關系的IDE時。

在撰寫本文時,我們有超過50名初學者。最常用的是:

spring-boot-starter

: 核心啟動器,包括自動配置支援,日志記錄和YAML

spring-boot-starter-aop

: 使用Spring AOP和AspectJ進行面向方面程式設計的初學者

spring-boot-starter-data-jpa

: 使用Spring Data JPA和Hibernate的啟動器

spring-boot-starter-jdbc

: 用于将JDBC與HikariCP連接配接池一起使用的啟動器

spring-boot-starter-security

: 使用Spring Security的啟動器

spring-boot-starter-test

: 用于測試Spring Boot應用程式的啟動器

spring-boot-starter-web

: 使用Spring MVC建構Web的啟動器,包括RESTful應用程式

有關啟動器的完整清單,請參閱此存儲庫。

要查找有關Spring Boot啟動器的更多資訊,請檢視Spring啟動器簡介。

——————————————————————————————

  • 提問:如何禁用特定的自動配置?

如果我們要禁用特定的自動配置,我們可以使用

@EnableAutoConfiguration

批注的

exclude

屬性來訓示它。例如,此代碼段中和了

DataSourceAutoConfiguration

// other annotations @EnableAutoConfiguration (exclude = DataSourceAutoConfiguration. class ) 
public class MyConfiguration { }
           

如果我們使用

@SpringBootApplication

注釋啟用自動配置- 它具有

@EnableAutoConfiguration

作為元注釋 - 我們可以使用相同名稱的屬性禁用自動配置:

// other annotations @SpringBootApplication (exclude = DataSourceAutoConfiguration. class ) 
public class MyConfiguration { }
           

我們還可以使用

spring.autoconfigure.exclude

環境屬性禁用自動配置。

application.properties

檔案中的此設定與以前相同:

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
           

——————————————————————————————

  • 提問:如何注冊自定義自動配置?

要注冊自動配置類,我們必須在

META-INF/spring.factories

檔案的

_EnableAutoConfiguration

_key

下列出其完全限定名稱:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.baeldung.autoconfigure.CustomAutoConfiguration
           

如果我們使用Maven建構一個項目,那麼該檔案應放在

resources/META-INF

目錄中。

——————————————————————————————

  • 提問:如何告訴自動配置在bean存在時退回?

要訓示自動配置類在bean已經存在時退出,我們可以使用

@ConditionalOnMissingBean

注解。

此注解的最顯着屬性是:

value

: 要檢查的bean類型

name

: 要檢查的bean的名稱

放置在使用

@Bean

裝飾的方法上時 ,目标類型預設為方法的傳回類型:

@Configuration 
public class CustomConfiguration { 
    @Bean 
    @ConditionalOnMissingBean 
    public CustomService service() { 
    ... 
    } 
}
           

——————————————————————————————

  • 提問:如何将Spring Boot Web應用程式部署為JAR和WAR檔案?

傳統上,我們将Web應用程式打包為WAR檔案,然後将其部署到外部伺服器中。這樣做可以讓我們在同一台伺服器上安排多個應用程式。在CPU和記憶體稀缺的時候,這是節省資源的好方法。

但事情發生了變化。現在計算機硬體相當便宜,并且注意力轉向伺服器配置。在部署期間配置伺服器的一個小錯誤可能會導緻災難性後果。

Spring通過提供一個插件即

spring-boot-maven-plugin

來解決這個問題,将Web應用程式打包為可執行的JAR 。要包含此插件,隻需向

pom.xml

添加一個plugin元素:

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

有了這個插件,我們将在執行 package 階段後得到一個fat JAR 。此JAR包含所有必需的依賴項,包括嵌入式伺服器。是以,我們不再需要擔心配置外部伺服器。

然後我們可以像運作普通的可執行JAR一樣運作應用程式。

請注意,必須将

pom.xml

檔案中的

packaging

元素設定為

jar

才能建構JAR檔案:

<packaging>jar</packaging>

如果我們不包含這個元素,它也預設為 jar 。

如果我們想要建構WAR檔案,請将packing元素更改為

ar

<packaging>war</packaging>

并将容器依賴關系從打封包件中删除:

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

執行Maven package階段後,我們将擁有一個可部署的WAR檔案。

——————————————————————————————

  • 提問:如何将Spring Boot用于指令行應用程式?

與任何其他Java程式一樣,Spring Boot指令行應用程式必須具有 main 方法。此方法用作入口點,它調用

SpringApplication#run

方法來引導應用程式:

@SpringBootApplication 
public class MyApplication { 
    public static void main(String[] args) { 
        SpringApplication.run(MyApplication. class ); 
        // other statements 
        } 
}
           

然後 SpringApplication 類啟動一個Spring容器并自動配置bean。

請注意,我們必須将配置類傳遞給

run

方法才能作為主要配置源。按照慣例,這個參數就是入門類本身。

在調用

run

方法之後,我們可以像在正常程式中那樣執行其他語句。

——————————————————————————————

  • 提問:有哪些可能的外部配置來源?

Spring Boot支援外部配置,允許我們在各種環境中運作相同的應用程式。我們可以使用屬性檔案,YAML檔案,環境變量,系統屬性和指令行選項參數來指定配置屬性。

然後,我們可以通路使用這些屬性

@Value

注釋,經由綁定對象

@ConfigurationProperties

注解,或 環境 抽象。

以下是最常見的外部配置來源:

指令行屬性:指令行選項參數是以雙連字元開頭的程式參數,例如

-server.port = 8080

。Spring Boot将所有參數轉換為屬性,并将它們添加到環境屬性集中。

應用程式屬性:應用程式屬性是從

application.properties

檔案或其YAML對應檔案加載的屬性。預設情況下,Spring Boot會在目前目錄,類路徑根或其 config 子目錄中搜尋此檔案。

特定于配置檔案的屬性:特定的配置檔案的屬性從

application- {profile} .properties

檔案或其YAML對應檔案加載。這些檔案與非特定屬性檔案位于相同位置,并且優先于非特定屬性檔案。

——————————————————————————————

  • 提問:Spring Boot支援relaxed binding是什麼意思?

Spring Boot中的relaxed binding适用于配置屬性的類型安全綁定。

使用relaxed binding時,環境屬性的鍵不需要與屬性名稱完全比對。這樣的環境屬性可以用

camelCase

kebab-case

snake_case

或大寫字母寫成,單詞用下劃線分隔。

例如,如果帶有

@ConfigurationProperties

批注的bean類中的屬性名為 myProp ,則可以将其綁定到以下任何環境屬性:

myProp

my-prop

my_prop

MY_PROP

——————————————————————————————

  • 提問:什麼是Spring Boot DevTools?

Spring Boot Developer Tools或DevTools是一組工具,使開發過程更容易。要包含這些開發時功能,我們隻需要在 pom.xml 檔案中添加依賴項:

<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-devtools</artifactId> 
</dependency>
           

Spring Boot DevTools在生産運作子產品将自動禁用。

預設情況下,重新打包存檔也會排除此子產品。是以,它不會給生産環境帶來任何開銷。

預設情況下,DevTools應用适合開發環境的屬性。

這些屬性禁用模闆緩存,為Web組啟用調試日志記錄,等等。

是以,我們擁有這種合理的開發時配置,而無需設定任何屬性。

隻要類路徑上的檔案發生更改,使用DevTools的應用程式就會重新啟動。

這是開發中非常有用的功能,因為它可以快速回報修改。

預設情況下,靜态資源(包括視圖模闆)不會啟動重新啟動。

相反,資源更改會觸發浏覽器重新整理。請注意,隻有在浏覽器中安裝

LiveReload

擴充以與

DevTools

包含的嵌入式

LiveReload

伺服器進行互動時,才會發生這種情況。

有關此主題的更多資訊,請參閱

Spring Boot DevTools

概述。

——————————————————————————————

  • 提問:如何編寫內建測試?

在為Spring應用程式運作內建測試時,我們必須有一個

ApplicationContext

為了讓我們的生活更輕松,Spring Boot為測試提供了一個特殊的注釋

@SpringBootTest

。此注解從其 classes 屬性訓示的配置類建立

ApplicationContext

如果未設定 classes 屬性,Spring Boot将搜尋主配置類。 搜尋從包含測試的包開始,直到找到使用

@SpringBootApplication

@SpringBootConfiguration

注釋的類。

請注意,如果我們使用

JUnit 4

,我們必須使用

@RunWith(SpringRunner.class)

裝飾測試類。

有關詳細說明,請檢視我們的Spring Boot測試教程。

——————————————————————————————

  • 提問:什麼是Spring Boot Actuator?

從本質上講,Actuator通過支援生産就緒功能讓Spring Boot應用跑起來。這些功能使我們能夠在生産環境運作時監控和管理應用程式。

将Spring Boot Actuator內建到一個項目中非常簡單。我們需要做的就是在

pom.xml

檔案中包含

spring-boot-starter-actuator

啟動器:

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

Spring Boot Actuator可以使用HTTP或JMX公開操作。但是大多數應用程式都使用HTTP,其中端點的辨別為 /執行器字首形成的URL路徑。

——————————————————————————————

——————————————————————————————

——————————————————————————————

——————————————————————————————

——————————————————————————————

——————————————————————————————

——————————————————————————————

——————————————————————————————

——————————————————————————————

——————————————————————————————

——————————————————————————————

——————————————————————————————

——————————————————————————————

——————————————————————————————

——————————————————————————————

附:

Spring問題彙總 (on IDEA MAC)

https://blog.csdn.net/weixin_42915286/article/details/85017091

課程内容:

  • 1.核心特性
  • 2.Web應用
  • 3.資料相關
  • 4.功能擴充
  • 5.運維管理

分成兩篇:核心技術+生态整合

核心技術關注:SpringBoot和Spring Framework/SpringEE規範之間的聯系;

生态整合關注:JavaEE;其中運維整合較難了解,此部分和以往JavaEE不太相關;

技術儲備要求:

1.語言:JAVA8

2.架構:Spring Framework 基礎熟練

3.運用:SpringBoot基礎

【架構】Spring Boot 2.0 介紹 + 問題彙總(包括:異步非阻塞)(未完結)

這裡有幾個問題:

1.SpringBoot是如何基于Spring Framework逐漸走向自動裝配?

2.SpringApplication是如何掌控Spring應用生命周期?

3.SpringBoot外部化配置與SpringEnvironment抽象之間是什麼關系?

4.SpringWebMVC向Spring Reactive WebFlux過渡地真實價值和意義?

建議:

想學好SpringBoot或JAVA,多寫API,少用自動化的工具。終身受益。

——————————————————————————————-——

Web應用

Spring Web Flux 應用 (Spring5開始支援,對Servlet補充)

我們知道傳統的Web架構,比如說:

struts2

springmvc

等 都是基于

Servlet API

Servlet容器

基礎之上運作的,在Servlet3.1之後才有了異步非阻塞的支援。

而WebFlux是一個典型非阻塞異步的架構,它的核心是基于

Reactor

相關API

實作的。

相對于傳統的web架構來說,它可以運作在諸如Netty,Undertow及支援Servlet3.1的容器上,是以它的運作環境的可選擇行要比傳統web架構多的多。

根據官方的說法,webflux主要在如下兩方面展現出獨有的優勢:

1)非阻塞式

其實在servlet3.1提供了非阻塞的API,WebFlux提供了一種比其更完美的解決方案。使用非阻塞的方式可以利用較小的線程或硬體資源來處理并發進而提高其可伸縮性;

  1. 函數式程式設計端點

    老生常談的程式設計方式了,Spring5必須讓你使用java8,那麼函數式程式設計就是java8重要的特點之一,而WebFlux支援函數式程式設計來定義路由端點處理請求。

  • Reactor基礎:Java Lambda、Mono、Flux
  • Web Flux核心:Web MVC注解(

    @Controller @RequestMapping ...

    )、函數式聲明(

    RouterFunction

    )、異步非阻塞(

    Servlet 3.1+``Netty Reactor

  • 使用場景:頁面渲染、REST應用;Web Flux優勢和限制

blog.ippon.tech 了解下

Web Server 應用

  • 切換Web Server,比如Tomcat與Jetty的切換,或不用Server;
  • 自定義Servlet Web Server
  • 自定義Reactive Web Server

SpringBoot易學:

  • 組建自動裝配:規約大于配置,專注核心業務
  • 外部化配置:一次建構、按需配置、到處運作
  • 嵌入式容器:内置容器、無需部署、獨立運作
  • Spring Boot Starter:簡化依賴、按需裝配、自我包含
  • Production-Ready:一站式運維、生态無縫整合

SpringBoot難靜:

  • 組建自動裝配:模式注解、@Enable子產品、條件裝配、加載機制
  • 外部化配置:Environment抽象、生命周期、破壞性變更
  • 嵌入式容器:Servlet Web容器、Reactive Web容器
  • Spring Boot Starter:依賴管理、裝配條件、裝配順序
  • Production-Ready:健康檢查、資料名額、@Endpoint管控

1.核心特性

SpringBoot三大特性:

組建自動裝配:WebMVC、WebFlux、JDBC等

嵌入式Web容器:Tomcat、Jetty、Undertow

生産準備特性:名額、健康檢查、外部化配置等

組建自動裝配

  • 1.激活:

    @EnableAutoConfiguration

  • 2.配置:

    /META-INF/spring.factories

  • 3.實作:

    XXXAutoConfiguration

start.spring.io

【架構】Spring Boot 2.0 介紹 + 問題彙總(包括:異步非阻塞)(未完結)

下好後,導入IDE中:

注意!導入時的路徑不要随便放在桌面或其他地方,放在正式倉庫檔案夾為好;

————————————————

1.激活

官網檢視SampleController可知

SpringBootController中比SpringMVC中多了一句

@EnableAutoConfiguration

一旦加上就啟動了SpringBoot

但實際上項目中的注解是

@SpringBootApplication

它包括了

@EnableAutoConfiguration

2.配置:

/META-INF/spring.factories

項目中其實有很多同名檔案,如:

【架構】Spring Boot 2.0 介紹 + 問題彙總(包括:異步非阻塞)(未完結)

3.實作:

XXXAutoConfiguration

【架構】Spring Boot 2.0 介紹 + 問題彙總(包括:異步非阻塞)(未完結)

從這裡看得出來,enableConfiguration可以作為一個鍵,實作很多value裝配

是以SB啟動時,可以啟動很多BEAN。

————————————————————————————————

Web應用

傳統Servlet應用

Spring自定義操作方式,結合Servlet規範;

目錄:

  • *.依賴;
  • 1.Servlet元件:Servlet、Filter、Listener
  • 2.Servlet注冊:Servlet注解、Spring Bean、RegistrationBean
  • 3.異步非阻塞(重要):異步Servlet、非阻塞Servlet

    —————————————————————

    ** *.依賴 **

傳統的Servlet應用使用依賴如下:

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

而項目中的子產品長這樣:

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

其實就是spring-boot-starter分成了多個子產品,如-web、-test;

綜上所見,可以發現

<groupId>

都是固定的:org.springframework.boot

<artifactId>

字首都是固定的:spring-boot-starter。。。

把 artifactid: spring-boot-starter-web加入POM後,發現MavenProjects發生了變化:

BEFORE:

【架構】Spring Boot 2.0 介紹 + 問題彙總(包括:異步非阻塞)(未完結)

AFTER:新增了一條

【架構】Spring Boot 2.0 介紹 + 問題彙總(包括:異步非阻塞)(未完結)

運作後:

【架構】Spring Boot 2.0 介紹 + 問題彙總(包括:異步非阻塞)(未完結)

明顯,此時的容器就為Tomcat。

此時通路下

Localhost:8080

:出現白頁錯誤404警告,因為無映射;

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Wed Feb 06 21:28:52 CST 2019
There was an unexpected error (type=Not Found, status=404).
No message available
           

—————————————————————

1.Servlet元件: Servlet、Filter、Listener

建立

web/servlet/MyServlet.java

Servlet

1).實作

  • @WebServlet

  • extends

    HttpServlet

  • 注冊

    2).URL 映射(這樣寫适用于浏覽器,無法讓程式識别)
  • @WebServlet(urlPatterns = "/my/servlet")

    3).注冊 (在此包名下搜尋所有元件)
  • @ServletComponentScan(basePackages = "com.example.springboot.web.servlet")

    Filter

    Listener

MyServlet.java

@WebServlet(urlPatterns = "/my/servlet")   //這裡實作映射(到浏覽器通路)

public class MyServlet extends HttpServlet {    //實作此接口(因他是Servlet3.0的規範)

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().println("OKKKKKKKK");
    }

}

           

—————————————————————

2. Servlet注冊:(3.0) : 1).Servlet注解、2).Spring Bean、3).RegistrationBean

1).Servlet 注解

@ServletComponentScan +(使用他,掃描上面servlet中所有的元件)

  • @WebServlet
  • @WebFilter
  • @WebListener

2).Spring Bean

@Bean +

  • Servlet
  • Filter
  • Listener

3).RegistrationBean

  • ServletRegistrationBean
  • FilterRegistrationBean
  • ServletListenerRegistrationBean

這裡先使用1).1).Servlet 注解 @ServletComponentScan +

Application.java

@SpringBootApplication
@ServletComponentScan(basePackages = "com.example.springboot.web.servlet")
public class Application {

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

}
           

此時通路localhost.com/8080/my/sevlet,即可看到輸出語句

OKKKKKKKK

———————————————————

異步非阻塞(重要):兩個方面,異步Servlet 和 非阻塞Servlet

注:同步,異步 (asynchronous),阻塞,非阻塞:

同步異步是資料通信的方式,阻塞和非阻塞是一種狀态。

比如同步這種資料通訊方式裡面可以有阻塞狀态也可以有非阻塞狀态。從另外一個角度了解同步和異步,就是如果一個線程幹完的事情都是同步,有線程切換才能幹完的事情就是異步。

異步 Servlet (3.0)

  • javax.servlet.ServletRequest#startAsync()

  • javax.servlet.AsyncContext

    非阻塞 Servlet (3.1)
  • javax.servlet.ServletInputStream#setReadListener

  • javax.servlet.ReadListener

  • javax.servlet.ServletOutputStream#setWriteListener

  • javax.servlet.WriteListener

在MyServlet.java中

doGet()

内 添加異步上下文條件語句:

AsyncContext asyncContext = request.startAsync();

和添加操作語句:

asyncContext.start(()->{ });

把已寫代碼

response.getWriter().println("OKKKKKKKK");

挪入操作語句中;

.getWriter

還報錯,把他try catch,暫不加日志說明;

(不可用)
@WebServlet(urlPatterns = "/my/servlet")
public class MyServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        AsyncContext asyncContext = request.startAsync();
        asyncContext.start(()->{
            try {
                response.getWriter().println("OKKKKKKKK");
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }
}
           

重新開機通路

Localhost.com/8080/my/servlet

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Thu Feb 07 00:43:56 CST 2019
There was an unexpected error (type=Internal Server Error, status=500).
A filter or servlet of the current chain does not support asynchronous operations.
           

A filter or servlet of the current chain does not support asynchronous operations.

檢視

WebServlet.class

源碼可知:

boolean asyncSupported() default false;

于是需要在

@WebServlet

後注明

true

(非最終版)
@WebServlet(urlPatterns = "/my/servlet",asyncSupported=true)
public class MyServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        AsyncContext asyncContext = request.startAsync();
        asyncContext.start(()->{
            try {
                response.getWriter().println("OKKKKKKKK");
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }
}
           

此時浏覽器通路連結,速度慢到難以忍受,報錯逾時:

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Thu Feb 07 01:17:29 CST 2019
There was an unexpected error (type=Internal Server Error, status=500).
No message available
           

原因是異步與同步處理有差別,(方法内)結尾必須告訴IDE已經完結;

需要添加觸發完成,加上

asyncContext.complete();

;(重要!!!)

(非最終版)
@WebServlet(urlPatterns = "/my/servlet",asyncSupported=true)

public class MyServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        AsyncContext asyncContext = request.startAsync();
        asyncContext.start(()->{
            try {
                response.getWriter().println("OKKKKKKKK");
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        asyncContext.complete();
    }

}
           

浏覽器不報錯了,顯示空白;

如果把觸發完成移步到列印的"OKKKKKKKK"後,浏覽器即可顯示輸出這句話。

@WebServlet(urlPatterns = "/my/servlet",asyncSupported=true)

public class MyServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        AsyncContext asyncContext = request.startAsync();
        asyncContext.start(()->{
            try {
                response.getWriter().println("OKKKKKKKK");
                asyncContext.complete();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }
}
           

異步非阻塞比同步操作麻煩很多,極容易遇坑,需要注意的問題之後再讨論;

此部分完結。

————————————————————————————————

Spring Web MVC 應用

目錄:

  • 1. Web MVC 視圖:模版引擎、内容協商、異常處理等;
  • 2. Web MVC REST:(JSON、XML為例)資源服務、資源跨域、服務發現等;
  • 3. Web MVC 核心:核心架構、處理流程、核心元件。

1. Web MVC 視圖

  • ViewResolver
  • View

1).模闆引擎:渲染

  • Thymeleaf
  • Freemarker
  • JSP

2).内容協商: 多種模版引擎時,内容協商幫助選擇最佳比對的模版引擎

  • ContentNegotiationConfigurer
  • ContentNegotiationStrategy
  • ContentNegotiatingViewResolver

3).異常處理

  • @ExceptionHandler
  • HandlerExceptionResolver
    • ExceptionHandlerExceptionResolver
  • BasicErrorController (Spring Boot) :生成白頁

————————————————————————————————

2. Web MVC REST

資源服務

  • @RequestMapping :請求映射
    • @GetMapping
  • @ResponseBody
  • @RequestBody (少用)

資源跨域

  • CrossOrigin
  • WebMvcConfigurer#addCorsMappings
  • 傳統解決方案(浏覽器中不推薦)
    • IFrame
    • JSONP

服務發現

  • HATEOS

————————————————————————————————

3. Web MVC 核心

  • 核心架構
  • 處理流程
  • 核心元件
    • DispatcherServlet (主要)
    • HandlerMapping
    • HandlerAdapter
    • ViewResolver

————————————————————————————————

Spring Web Flux 應用

————————————————

Reactor 基礎

  • Java Lambda (Reactor的基礎)
  • Mono(核心接口之一)
  • Flux(核心接口之一)

    ————————————————

    Web Flux 核心 (可與SpringMVC相容)

1).Web MVC 注解相容

  • @Controller
  • @RequestMapping
  • @ResponseBody
  • @RequestBody

2).函數式聲明

  • RouterFunction (路由器函數)

3).異步非阻塞

  • Servlet 3.1 +
  • Netty Reactor

    ————————————————

    使用場景(與SpringMVC沒什麼差別)

  • 頁面渲染 (視圖應用)
  • REST 應用
  • 性能測試

    http://blog.ippon.tech/spring-5-webflux-performance-tests/

    ————————————————————————————————

Web Server 應用

切換 Web Server

1).切換其他 Servlet 容器

  • Tomcat -> Jetty
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- Exclude the Tomcat dependency -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Use Jetty instead -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
           

2).替換 Servlet 容器

  • WebFlux
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- Exclude the Tomcat dependency -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Use Jetty instead -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-web</artifactId>-->
<!--<exclusions>-->
<!--&lt;!&ndash; Exclude the Tomcat dependency &ndash;&gt;-->
<!--<exclusion>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-tomcat</artifactId>-->
<!--</exclusion>-->
<!--</exclusions>-->
<!--</dependency>-->
<!--&lt;!&ndash; Use Jetty instead &ndash;&gt;-->
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-jetty</artifactId>-->
<!--</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
           

3).自定義 Servlet Web Server

  • WebServerFactoryCustomizer

4).自定義 Reactive Web Server

  • ReactiveWebServerFactoryCustomizer

————————————————————————————————

資料相關

1.關系型資料

JDBC

1).依賴

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

2).資料源

  • javax.sql.DataSource
  • JdbcTemplate

    3).自動裝配

  • DataSourceAutoConfiguration

繼續閱讀