原文自工程師baeldung部落格,傳送門
最近到了春招的時間,各位同學們都開始努力準備面試相關的事項,這邊 Eugen 老師在 baeldung 中發表了一篇和 SpringBoot 相關的面試題目以及解答,希望對大家有幫助。
概述
從誕生那天開始,SpringBoot 就在 Spring 生態中扮演一個重要的地位。這個專案的自動化部署功能使我們的程式設計工作變得更方便。
在這篇文章當中,我們將介紹一些在工程師面試中可能會出現的 Spring Boot 相關的常見問題。
問題
Q1. Spring 和 SpringBoot 有什麼不同?
Spring 框架提供多種特性使得 web 應用開發變得更簡便,包括依賴注入、資料繫結、切面程式設計、資料存取等等。
隨著時間推移,Spring 生態變得越來越複雜了,並且應用程式所必須的配置檔案也令人覺得可怕。這就是 Spirng Boot 派上用場的地方了 – 它使得 Spring 的配置變得更輕而易舉。
實際上,Spring 是 unopinionated(予以配置項多,傾向性弱) 的,Spring Boot 在平臺和庫的做法中更 opinionated ,使得我們更容易上手。
這裡有兩條 SpringBoot 帶來的好處:
- 根據 classpath 中的 artifacts 的自動化配置應用程式
- 提供非功能性特性例如安全和健康檢查給到生產環境中的應用程式
Q2. 怎麼使用 Maven 來構建一個 SpringBoot 程式?
就像引入其他庫一樣,我們可以在 Maven 工程中加入 SpringBoot 依賴。然而,最好是從 spring-boot-starter-parent 專案中繼承以及宣告依賴到 Spring Boot starters。這樣做可以使我們的專案可以重用 SpringBoot 的預設配置。
繼承 spring-boot-starter-parent 專案依賴很簡單 – 我們只需要在 pom.xml 中定義一個 parent 節點:
<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 的最新版本。
使用 starter 父專案依賴很方便,但並非總是可行。例如,如果我們公司都要求專案繼承標準 POM,我們就不能依賴 SpringBoot starter 了。
這種情況,我們可以通過對 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>
複製程式碼
最後,我們可以新增 SpringBoot starter 中一些依賴,然後我們就可以開始了。
Q3. SpringBoot starter 作用在什麼地方?
依賴管理是所有專案中至關重要的一部分。當一個專案變得相當複雜,管理依賴會成為一個噩夢,因為當中涉及太多 artifacts 了。
這時候 SpringBoot starter 就派上用處了。每一個 stater 都在扮演著提供我們所需的 Spring 特性的一站式商店角色。其他所需的依賴以一致的方式注入並且被管理。
所有的 starter 都歸於 org.springframework.boot 組中,並且它們都以由 spring-boot-starter- 開頭取名。這種命名方式使得我們更容易找到 starter 依賴,特別是當我們使用那些支援通過名字查詢依賴的 IDE 當中。
在寫這篇文章的時候,已經有超過50個 starter了,其中最常用的是:
- spring-boot-starter:核心 starter,包括自動化配置支援,日誌以及 YAML
- spring-boot-starter-aop:Spring AOP 和 AspectJ 相關的切面程式設計 starter
- spring-boot-starter-data-jpa:使用 Hibernate Spring Data JPA 的 starter
- spring-boot-starter-jdbc:使用 HikariCP 連線池 JDBC 的 starter
- spring-boot-starter-security:使用 Spring Security 的 starter
- spring-boot-starter-test:SpringBoot 測試相關的 starter
- spring-boot-starter-web:構建 restful、springMVC 的 web應用程式的 starter
Q4. 怎麼禁用某些自動配置特性?
如果我們想禁用某些自動配置特性,可以使用 @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
複製程式碼
Q5. 怎麼註冊一個定製的自動化配置?
為了註冊一個自動化配置類,我們必須在 META-INF/spring.factories 檔案中的 EnableAutoConfiguration 鍵下列出它的全限定名:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.baeldung.autoconfigure.CustomAutoConfiguration
複製程式碼
如果我們使用 Maven 構建專案,這個檔案需要放置在在 package 階段被寫入完成的 resources/META-INF 目錄中。
Q6. 當 bean 存在的時候怎麼置後執行自動配置?
為了當 bean 已存在的時候通知自動配置類置後執行,我們可以使用 @ConditionalOnMissingBean 註解。這個註解中最值得注意的屬性是:
- value:被檢查的 beans 的型別
- name:被檢查的 beans 的名字
當將 @Bean 修飾到方法時,目標型別預設為方法的返回型別:
@Configuration
public class CustomConfiguration {
@Bean
@ConditionalOnMissingBean
public CustomService service() { ... }
}
複製程式碼
Q7. 怎麼將 SpringBoot 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 步驟後得到一個 JAR 包。這個 JAR 包包含所需的所有依賴以及一個嵌入的伺服器。因此,我們不再需要擔心去配置一個額外的伺服器了。
我們能夠通過執行一個普通的 JAR 包來啟動應用程式。
注意一點,為了打包成 JAR 檔案,pom.xml 中的 packgaing 屬性必須定義為 jar:
<packaging>jar</packaging>
複製程式碼
如果我們不定義這個元素,它的預設值也為 jar。
如果我們想構建一個 WAR 檔案,將 packaging 元素修改為 war:
<packaging>war</packaging>
複製程式碼
並且將容器依賴從打包檔案中移除:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
複製程式碼
執行 Maven 的 package 步驟之後,我們得到一個可部署的 WAR 檔案。
Q8. 怎麼使用 SpringBoot 去執行命令列程式?
像其他 Java 程式一樣,一個 SpringBoot 命令列程式必須要有一個 main 方法。這個方法作為一個入口點,通過呼叫 SpringApplication#run 方法來驅動程式執行:
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class);
// other statements
}
}
複製程式碼
SpringApplication 類會啟動一個 Spirng 容器以及自動化配置 beans。
要注意的是我們必須把一個配置類傳遞到 run 方法中作為首要配置資源。按照慣例,這個引數一般是入口類本身。
在呼叫 run 方法之後,我們可以像平常的程式一樣執行其他語句。
Q9. 有什麼外部配置的可能來源?
SpringBoot 對外部配置提供了支援,允許我們在不同環境中執行相同的應用。我們可以使用 properties 檔案、YAML 檔案、環境變數、系統引數和命令列選項引數來宣告配置屬性。
然後我們可以通過 @Value 這個通過 @ConfigurationProperties 繫結的物件的註解或者實現 Enviroment 來訪問這些屬性。
以下是最常用的外部配置來源:
- 命令列屬性:命令列選項引數是以雙連字元(例如,=)開頭的程式引數,例如 –server.port=8080。SpringBoot將所有引數轉換為屬性並且新增到環境屬性當中。
- 應用屬性:應用屬性是指那些從 application.properties 檔案或者其 YAML 副本中獲得的屬性。預設情況下,SpringBoot會從當前目錄、classpath 根目錄或者它們自身的 config 子目錄下搜尋該檔案。
- 特定 profile 配置:特殊概要配置是從 application-{profile}.properties 檔案或者自身的 YAML 副本。{profile} 佔位符引用一個在用的 profile。這些檔案與非特定配置檔案位於相同的位置,並且優先於它們。
Q10. SpringBoot 支援鬆繫結代表什麼?
SpringBoot中的鬆繫結適用於配置屬性的型別安全繫結。使用鬆繫結,環境屬性的鍵不需要與屬性名完全匹配。這樣就可以用駝峰式、短橫線式、蛇形式或者下劃線分割來命名。
例如,在一個有 @ConfigurationProperties 宣告的 bean 類中帶有一個名為 myProp 的屬性,它可以繫結到以下任何一個引數中,myProp、 my-prop、my_prop 或者 MY_PROP。
Q11. SpringBoot DevTools 的用途是什麼?
SpringBoot 開發者工具,或者說 DevTools,是一系列可以讓開發過程變得簡便的工具。為了引入這些工具,我們只需要在 POM.xml 中新增如下依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
複製程式碼
spring-boot-devtools 模組在生產環境中是預設禁用的,archives 的 repackage 在這個模組中預設也被排除。因此,它不會給我們的生產環境帶來任何開銷。
通常來說,DevTools 應用屬性適合於開發環境。這些屬性禁用模板快取,啟用 web 組的除錯日誌記錄等等。最後,我們可以在不設定任何屬性的情況下進行合理的開發環境配置。
每當 classpath 上的檔案發生更改時,使用 DevTools 的應用程式都會重新啟動。這在開發中非常有用,因為它可以為修改提供快速的反饋。
預設情況下,像檢視模板這樣的靜態資源修改後是不會被重啟的。相反,資源的更改會觸發瀏覽器重新整理。注意,只有在瀏覽器中安裝了 LiveReload 擴充套件並以與 DevTools 所包含的嵌入式 LiveReload 伺服器互動時,才會發生。
Q12. 怎麼編寫一個整合測試?
當我們使用 Spring 應用去跑一個整合測試時,我們需要一個 ApplicationContext。
為了使我們開發更簡單,SpringBoot 為測試提供一個註解 – @SpringBootTest。這個註釋由其 classes 屬性指示的配置類建立一個 ApplicationContext。
如果沒有配置 classes 屬性,SpringBoot 將會搜尋主配置類。搜尋會從包含測試類的包開始直到找到一個使用 @SpringBootApplication 或者 @SpringBootConfiguration 的類為止。
注意如果使用 JUnit4,我們必須使用 @RunWith(SpringRunner.class) 來修飾這個測試類。
Q13. SpringBoot的 Actuator 是做什麼的?
本質上,Actuator 通過啟用 production-ready 功能使得 SpringBoot 應用程式變得更有生命力。這些功能允許我們對生產環境中的應用程式進行監視和管理。
整合 SpringBoot Actuator 到專案中非常簡單。我們需要做的只是將 spring-boot-starter-actuator starter 引入到 POM.xml 檔案當中:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
複製程式碼
SpringBoot Actuaor 可以使用 HTTP 或者 JMX endpoints來瀏覽操作資訊。大多數應用程式都是用 HTTP,作為 endpoint 的標識以及使用 /actuator 字首作為 URL路徑。
這裡有一些常用的內建 endpoints Actuator:
- auditevents:檢視 audit 事件資訊
- env:檢視 環境變數
- health:檢視應用程式健康資訊
- httptrace:展示 HTTP 路徑資訊
- info:展示 arbitrary 應用資訊
- metrics:展示 metrics 資訊
- loggers:顯示並修改應用程式中日誌器的配置
- mappings:展示所有 @RequestMapping 路徑資訊
- scheduledtasks:展示應用程式中的定時任務資訊
- threaddump:執行 Thread Dump
3. 總結
這篇文章我們討論了一些關於 SpringBoot 的關鍵問題,這些問題可能會在你們的技術面試中遇到。我們希望這篇文章能夠幫你找到理想的工作。
4. 譯者總結
原文囊括了一些 SpringBoot 中提供的特性以及特點,譯者在翻譯的時候也重溫了其中的一些注意點,希望可以幫到讀者們,更好地認識 SpringBoot,能夠從容不迫地面對面試官的問題。
在這裡也提一句,如果想和我們一起工作,可以將簡歷投放到我們的郵箱,我們等待你們的加入!
小喇叭
廣州蘆葦科技Java開發團隊
蘆葦科技-廣州專業網際網路軟體服務公司
抓住每一處細節 ,創造每一個美好
關注我們的公眾號,瞭解更多
想和我們一起奮鬥嗎?lagou搜尋“ 蘆葦科技 ”或者投放簡歷到 server@talkmoney.cn 加入我們吧
關注我們,你的評論和點贊對我們最大的支援