非常熱門的 20 個Spring Boot 技術面試中經常被問到的問題。
1. Spring Boot 有哪些特點?
Spring Boot 是 Spring 的擴展,它消除了設置 Spring 應用程序所需的樣板配置。
- 自動配置
這是 Spring Boot 最重要的特性。這極大地消除了手動配置?;A框架附帶了一個名為 auto-configure 的內置庫,它為我們完成了這項工作。它檢測某些類的存在以及類路徑上的存在,并為我們自動配置它們。
例如:— 當我們在項目中添加spring-boot-starter-web依賴項時,Spring Boot 自動配置會查找 Spring MVC 是否在類路徑中。它自動配置dispatcherServlet、默認錯誤頁面和web jars?!?同樣,當我們添加
spring-boot-starter-data-jpa依賴項時,我們會看到 Spring Boot 自動配置,自動配置一個數(shù)據源和一個實體管理器。
- 嵌入式 Tomcat Web 服務器
Spring Boot 默認隨 Tomcat 服務器一起提供。因此,我們不需要配置服務器來運行應用程序(如果我們的首選服務器是 Tomcat)。
- 入門 POM
Spring Boot 本身提供了許多啟動 POM 來完成開發(fā)生活中最常見的任務。我們可以依賴它們和框架本身,而不需要去第三方庫。我在這里列出了其中的一些。
- spring-boot-starter-web:創(chuàng)建 REST API
- spring-boot-starter-data-jpa:連接 SQL 數(shù)據庫
- spring-boot-starter-data-mongodb:連接 MongoDB
- spring-boot-starter -aop:應用面向方面的編程概念
- spring-boot-starter-security:實現(xiàn)安全性,如基于角色的身份驗證
- spring-boot-starter-test:實現(xiàn)單元測試
- Actuator執(zhí)行器 API
Spring Boot Actuator 是 Spring Boot 框架的一個子項目。它使我們能夠通過一組 API 端點查看見解和指標并監(jiān)控正在運行的應用程序。我們不需要手動創(chuàng)建它們。
- 數(shù)據庫統(tǒng)計信息:數(shù)據源使用情況
- CPU內存使用情況
- GC 周期
- 跟蹤 HTTP 請求
- SpringBoot初始化器
這是一個基于 Web 的 UI,主要提供了使用可用依賴項創(chuàng)建新 Spring Boot 項目并下載創(chuàng)建為 zip 的項目的能力。所以我們不必從頭開始創(chuàng)建它。該項目的所有基本結構都已在此下載的 zip 中。Spring Initializer 作為 IDE 插件提供,也具有不同的名稱。
例如:對于 IntelliJ - 插件是 Spring Assistant 或 Spring Initializer。
2、你知道“@SpringBootApplication”注解在內部是如何工作的嗎?
Spring Boot 應用程序使用此注解執(zhí)行。實際上它是其他 3 個注釋的組合:
ComponentScan、EnableAutoConfiguration和Configuration。
@SpringBootApplication = @ComponentScan + @EnableAutoConfiguration + @Configuration
- “@Configuration” ——所有帶注釋的類都被視為 Spring Boot 的廣告配置,它們有資格創(chuàng)建 bean 并返回到 IOC 容器。
- “@ComponentScan” ——所有帶注釋的類都將通過包(在哪里尋找)進行掃描,并幫助創(chuàng)建這些類的實例。
- “@EnableAutoConfiguration” ——這是神奇的注解。這會尋找類路徑。基礎框架附帶了一個名為auto-configure的內置庫,它為我們完成了這項工作。它檢測某些類的存在以及類路徑上的存在,并為我們自動配置它們。我在下面放了圖書館的快照。如果您前往 spring.factories 文件,您將看到可用的類配置。
?
上圖是自動配置依賴 JAR
假設我們添加了 JPA 依賴項:Spring Boot 檢查 class-path 以查看可用的內容以及
application.properties/yml 文件中定義的屬性。這里將是數(shù)據庫 URL 和憑據。
JPA Repository 類也使用一些條件注釋進行注釋,例如“@ConditionalOnBean”、“@ConditionalOnClass”,根據這些規(guī)則,生成配置。
3. 什么是 Bean?
Bean 只是普通的 Java 對象。在 Spring Boot 上下文中,它們被視為 Java 對象 + 在應用程序啟動時自動初始化并由 Spring IOC 容器管理的對象。我們有“@Bean”注解來實現(xiàn)這一點。
4、什么是Spring中的控制反轉(IOC)?
控制反轉:
將對象或程序部分的控制權轉移到容器或框架的原理。我們最常在?面向對象?編程的上下文中使用它。簡單地說,控制是由框架來處理的,而不是由我們來處理——程序控制流的逆向。反者道之動。
Spring IOC 容器:
創(chuàng)建對象、配置和組裝它們的依賴關系、管理它們的整個生命周期的容器。它使用依賴注入 (DI)來管理構成應用程序的組件。
5、我們如何在Spring Boot中實現(xiàn)依賴注入?
DI — 將對象作為依賴項傳遞給另一個對象
在 Spring Boot 中,我們可以使用“@Autowired”注解來實現(xiàn)這一點。然后 Spring IOC 容器將代表我們創(chuàng)建對象。通常,在控制器層我們注入服務,在服務層我們注入存儲庫來使用這個注解。
6、Spring Boot微服務有哪些層?
- 控制器層:所有具有 API 端點定義方法的控制器。類使用“@RestController”注解進行注解。
- Repository/DAO層:所有repository接口都包含在這一層中,用于查詢已選擇的數(shù)據庫(SQL/no SQL)。接口使用“@Repository”注解進行注解。
- 服務層:所有業(yè)務邏輯都包含在這里。通常在該層訪問DAO層以執(zhí)行一些操作。類使用“@Service”注解進行注解。
- 實體層:映射到現(xiàn)實世界的所有類都包含在該層中。通常所有與 ORM 相關的注釋都放在這些類中?!?如果它與 MySQL 連接,我們用“@Entity”注釋表名?!?如果它連接到 MongoDB,我們用“@Document”注釋集合名稱。
此外,我們可以使用 Lombok 之類的庫在此處定義 getter 和 setter。
9. 如何使用 Spring Boot 連接數(shù)據庫?
通常我們不需要創(chuàng)建單例數(shù)據庫類、連接池方法和任何其他實現(xiàn)。Spring Boot Auto Configuration 將為我們完成所有這些類和配置設置。只需要設置。
- 將數(shù)據庫(MySQL/MongoDB/Redis)的啟動器依賴項添加到 POM。
- 在 application.properties/yml 文件中定義配置 - 例如:數(shù)據庫 URL 和憑據
10.如何在DAO層編寫自定義查詢?
通常在 Repository 層,我們使用 JPARepository 或 MongoRepository 接口擴展接口。之后,我們的 Repository(DAO) 將擁有 Spring Boot Repository 接口中可用的所有方法。Es:save()、saveAll()、findById()、find() 等。
但是根據我們的業(yè)務需求,我們可能還需要一些其他的方法。
例如:findByEmail()、findUsersByRegion() 等等……單例
因此,我們必須在這種情況下提供自定義查詢。我們有“@Query”注釋來實現(xiàn)這一點。只需在每個方法定義之前定義查詢即可。就這樣!
如果我們使用 JPA,我們必須使用JPQL (Java Persistence Query Language)創(chuàng)建查詢。它在 JPA 規(guī)范中定義,是一種面向對象的查詢語言,用于對持久實體執(zhí)行數(shù)據庫操作。
例如:僅查找給定區(qū)域中的用戶
@Query(<font>"select u from users u where u.region =: region"</font><font>)
Optional<List<User>> findUsersByRegion(String region);
</font>
11. Spring Boot 中如何處理事務?使用的任何注釋?
Spring Boot 提供了一個名為“@Transactional”的注解來管理事務。
讓我們假設一個產品訂購場景。我們需要在 Order Service 中處理訂單,并通過 REST 調用將付款詳情發(fā)送到 Payment Service。想象一下,支付服務突然停止了。如果在向支付服務發(fā)送 API 調用之前將訂單詳細信息保存在自己的數(shù)據庫中,那么將來會出現(xiàn)差異,因為支付服務數(shù)據正在丟失該記錄!
為了避免這種情況,我們可以將“@Transactional”注解放入訂單服務的方法中。然后從那里開始,如果調用支付服務時出現(xiàn)故障,正在進行的流程中的所有數(shù)據都將回滾!
@Transactional
<b>public</b> Order orderProduct(Product product, Double payment) {
<font><i>// 處理訂單</i></font><font>
</font><font><i>// 向支付服務發(fā)送 REST 調用</i></font><font>
}
</font>
12.我們需要在哪里使用“@Qualifier”注解?
此注解用于專門告訴 Spring Boot 從其所有可用實現(xiàn) bean 中獲取特定類。@Qualifier注解與“ @Autowired”注解一起用于依賴注入。
假設我們有1 個接口和 2 個不同的實現(xiàn)類。
例如:UserService 接口 => AdminUserService、StaffUserService 類
AdminUserService、StaffUserService 都在實現(xiàn) UserService 接口。我們必須在服務啟動時選擇StaffUserService 。否則 Spring Boot 將拋出異常并抱怨候選人太多。
請參閱下面的錯誤...
Description:
Field userService in com.example.demo.UserExecutor required a single bean, but 2 were found:
- adminUserService: defined in file [/home/salitha/Downloads/demo/target/<b>class</b>es/com/example/demo/AdminUserService.<b>class</b>]
- staffUserService: defined in file [/home/salitha/Downloads/demo/target/<b>class</b>es/com/example/demo/StaffUserService.<b>class</b>]
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
所以我們應該在 Autowired 之后放置 Qualifier 注釋來解決這個問題:
@Autowired
@Qualifier(<font>"staffUserService"</font><font>)
<b>private</b> UserService userService;
</font>
示例 Java 類設置來測試這一點:
<b>import</b> org.springframework.beans.factory.annotation.Autowired;
<b>import</b> org.springframework.beans.factory.annotation.Qualifier;
<b>import</b> org.springframework.boot.SpringApplication;
<b>import</b> org.springframework.boot.autoconfigure.SpringBootApplication;
<b>import</b> org.springframework.context.annotation.AnnotationConfigApplicationContext;
<b>import</b> org.springframework.context.annotation.ComponentScan;
<b>import</b> org.springframework.context.annotation.Configuration;
<b>import</b> org.springframework.stereotype.Component;
<b>import</b> org.springframework.stereotype.Service;
<b>import</b> javax.annotation.PostConstruct;
@SpringBootApplication
<b>public</b> <b>class</b> DemoApplication {
<b>public</b> <b>static</b> <b>void</b> main(String args) {
SpringApplication.run(DemoApplication.<b>class</b>, args);
}
}
<b>interface</b> UserService {
<b>void</b> login();
}
@Service
<b>class</b> AdminUserService implements UserService {
@Override
<b>public</b> <b>void</b> login() {
System.out.println(<font>"Admin Login"</font><font>);
}
}
@Service
<b>class</b> StaffUserService implements UserService {
@Override
<b>public</b> <b>void</b> login() {
System.out.println(</font><font>"Staff Login"</font><font>);
}
}
@Configuration
@ComponentScan(</font><font>"com.example.demo"</font><font>)
<b>class</b> AppConfig {
@Autowired
UserExecutor userExecutor;
@PostConstruct
<b>void</b> testBeans() {
userExecutor.getLogin();
}
}
@Component
<b>class</b> UserExecutor {
@Autowired
@Qualifier(</font><font>"staffUserService"</font><font>)
<b>private</b> UserService userService;
<b>public</b> <b>void</b> getLogin() {
userService.login();
}
}
</font>
13. Spring Boot項目中可以替換Tomcat服務器嗎?
是的。如果需要,我們可以通過在 POM 中添加 maven 排除來刪除 Tomcat 服務器。實際上,Web 服務器捆綁在started-web Spring Boot starter 依賴項中。應該添加排除。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId> spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
然后我們必須將任何其他服務器(如 Jetty)添加到 POM。無論如何,我們必須在刪除 tomcat 后添加一個 Web 服務器。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId> </dependency><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
您現(xiàn)在將看到 Jetty 服務器日志,而不是 Tomcat。
2022-08-03 13:22:12.551 INFO 57495 --- [main] osbweb.embedded.jetty.JettyWebServer:Jetty 在端口 8080 (http/1.1) 上啟動,上下文路徑為“/”
14.“@PathVariable”和“@RequestParam”有什么區(qū)別?
PathVariable - 當我們設置 API 端點時使用以“/”分隔的參數(shù)。
@GetMapping(path = <font>"/profile/{username}"</font><font>)
<b>public</b> ResponseEntity<?> getUser( @PathVariable(</font><font>"username"</font><font>) String username) {
<b>return</b> ResponseEntity.ok().body(authService.findUserByUsername(username));
}
</font>
API 端點:
http://localhost/api/profile/salitha
RequestParam - 當我們設置 API 端點時使用,查詢參數(shù)以“&”分隔并以“?”開頭。
@GetMapping(path = <font>"/confirm"</font><font>)
<b>public</b> ResponseEntity<?> confirmUser( @RequestParam(</font><font>"token"</font><font>) String token) {
<b>return</b> ResponseEntity. ok ().body(authService.confirmUser(token));
}
</font>
API 端點:
http://localhost/api/profile?token=12345678
15、“@Primary”注解有什么用?
@Primary表示當多個候選者有資格自動連接單值依賴項時,應優(yōu)先考慮 bean。
17. 如何驗證傳入的請求并將錯誤通知給用戶?
為此需要執(zhí)行幾個主要步驟。如果我們遵循這些,只需驗證請求即可。
- 我們已將啟動器驗證依賴項添加到 POM 中。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2. 在“RequestBody”注解前添加“@Valid”注解。
3. 為要顯示驗證約束消息的請求創(chuàng)建單獨的 DTO。
4. 使用“@RestControllerAdvice”創(chuàng)建全局異常處理程序,并在單獨的方法中處理
MethodArgumentNotValidException 。
5. 創(chuàng)建邏輯以根據需要將錯誤返回給最終用戶。我們可以在這個 logic.es 中提取異常消息
18、什么是Spring Boot Actuator?
簡單地說,Spring Boot 框架的一個子項目,它使用 HTTP 端點來公開有關任何正在運行的應用程序的操作信息。
這些信息包括應用程序指標、連接的數(shù)據庫狀態(tài)、應用程序狀態(tài)、bean 信息、請求跟蹤等。
它可作為啟動器依賴項使用。我們可以通過安裝以下依賴項來使用該庫。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
19、Spring Boot微服務中的異常如何處理?
我們可以以集中的方式做到這一點。我們需要一個全局配置類,為每個異常類預定義異常處理方法。我們也可以使用處理程序本身定義返回的 HTTP 狀態(tài)代碼。
- 使用“@RestControllerAdvice”創(chuàng)建一個全局異常處理程序,并在單獨的方法中處理每個異常。
- 創(chuàng)建邏輯以根據需要將錯誤返回給最終用戶。我們可以在這個邏輯中提取異常消息
@RestControllerAdvice
<b>public</b> <b>class</b> GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.<b>class</b>)
<b>public</b> ResponseEntity<Map<String, List<String>>> handleValidationErrors(MethodArgumentNotValidException ex) {
List<String> errors = ex.getBindingResult().getFieldErrors()
.stream().map(FieldError::getDefaultMessage).collect(Collectors.toList());
<b>return</b> <b>new</b> ResponseEntity<>(getErrorsMap(errors), <b>new</b> HttpHeaders(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(UserNotFoundException.<b>class</b>)
<b>public</b> ResponseEntity<Map<String, List<String>>> handleNotFoundException(UserNotFoundException ex) {
List<String> errors = Collections.singletonList(ex.getMessage());
<b>return</b> <b>new</b> ResponseEntity<>(getErrorsMap(errors), <b>new</b> HttpHeaders(), HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.<b>class</b>)
<b>public</b> <b>final</b> ResponseEntity<Map<String, List<String>>> handleGeneralExceptions(Exception ex) {
List<String> errors = Collections.singletonList(ex.getMessage());
<b>return</b> <b>new</b> ResponseEntity<>(getErrorsMap(errors), <b>new</b> HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler(RuntimeException.<b>class</b>)
<b>public</b> <b>final</b> ResponseEntity<Map<String, List<String>>> handleRuntimeExceptions(RuntimeException ex) {
List<String> errors = Collections.singletonList(ex.getMessage());
<b>return</b> <b>new</b> ResponseEntity<>(getErrorsMap(errors), <b>new</b> HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
}
<b>private</b> Map<String, List<String>> getErrorsMap(List<String> errors) {
Map<String, List<String>> errorResponse = <b>new</b> HashMap<>();
errorResponse.put(<font>"errors"</font><font>, errors);
<b>return</b> errorResponse;
}
}
</font>
20、“@Entity”和“@Table”注解有什么區(qū)別?
實體表示您將在程序中使用的類,表表示您將通過程序訪問的實際數(shù)據庫表。文章來源:http://www.zghlxwxcb.cn/news/detail-481580.html
以上就是為大家整理出來的最全面、在面試中百分之九十以上會被問到的問題,有需要完整版的PDF檔可【戳一戳】文章來源地址http://www.zghlxwxcb.cn/news/detail-481580.html
到了這里,關于最經典的20個Spring Boot面試題,95%以上會被問到,不服來戰(zhàn)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!