SpringBoot 面試問答總結(jié)(VIP典藏版)

1.什么是 Spring Boot?
Spring Boot 是 Spring 開源組織下的子項(xiàng)目,是 Spring 組件一站式解決方案,主要是簡化了使用Spring 的難度, ? ?省了繁重的配置,提供了各種啟動器,使開發(fā)者能快速上手。
2. 為什么要用SpringBoot?
快速開發(fā),快速整合,配置簡化、內(nèi)嵌服務(wù)容器
3. SpringBoot與SpringCloud 區(qū)別?
SpringBoot是快速開發(fā)的Spring框架,SpringCloud是完整的微服務(wù)框架,SpringCloud依賴于SpringBoot。
4. Spring Boot 有哪些優(yōu)點(diǎn)?
Spring Boot 主要有如下優(yōu)點(diǎn):
容易上手,提升開發(fā)效率,為 Spring 開發(fā)提供一個更快、更簡單的開發(fā)框架。
開箱即用,遠(yuǎn)離繁瑣的配置。
提供了一系列大型項(xiàng)目通用的非業(yè)務(wù)性功能,例如:內(nèi)嵌服務(wù)器、安全管理、運(yùn)行數(shù)據(jù)監(jiān)控、運(yùn)行狀況檢查和外部化配置等。
SpringBoot總結(jié)就是使編碼變簡單、配置變簡單、部署變簡單、監(jiān)控變簡單等等
【文末有驚喜】
【文末有驚喜】
【文末有驚喜】
5. Spring Boot 的核心注解是哪個?它主要由哪幾個注解組成的?
啟動類上面的注解是@SpringBootApplication
,它也是 Spring Boot 的核心注解,主要組合包含了以下 3 個注解:
@SpringBootConfiguration:組合了
@Configuration
注解,實(shí)現(xiàn)配置文件的功能。@EnableAutoConfiguration:打開自動配置的功能,也可以關(guān)閉某個自動配置的選項(xiàng)
例如:
java 如關(guān)閉數(shù)據(jù)源自動配置功能:
@SpringBootApplication(exclude =?{DataSourceAutoConfiguration.class })。
@ComponentScan:Spring組件掃描。
6. Spring Boot 支持哪些日志框架?推薦和默認(rèn)的日志框架是哪個?
Spring Boot 支持Java Util Logging
, Log4j2, Lockback 作為日志框架,如果你使用 Starters 啟動器, ? ?Spring Boot 將使用 Logback 作為默認(rèn)日志框架,但是不管是那種日志框架他都支持將配置文件輸出到控制臺或者文件中。
7. SpringBoot Starter的工作原理?
我個人理解SpringBoot就是由各種Starter組合起來的,我們自己也可以開發(fā)Starter
在sprinBoot啟動時(shí)由@SpringBootApplication
注解會自動去maven中讀取每個starter中的spring.factories
文件,文件里配置了所有需要被創(chuàng)建spring容器中的bean,并且進(jìn)行自動配置把bean注入SpringContext中
SpringContext是Spring的配置文件
8. Spring Boot 2.X 有什么新特性?與 1.X 有什么區(qū)別?
配置變更
JDK 版本升級
第三方類庫升級
響應(yīng)式 Spring 編程支持
HTTP/2 支持
配置屬性綁定
更多改進(jìn)與加強(qiáng)
9. SpringBoot支持什么前端模板?
thymeleaf,freemarker,jsp,官方不推薦JSP會有限制
10. SpringBoot的缺點(diǎn)?
我覺得是為難人,SpringBoot在目前我覺得沒有什么缺點(diǎn),非要找一個出來我覺得就是由于不用自己做的配置,報(bào)錯時(shí)很難定位。
11. 運(yùn)行 Spring Boot 有哪幾種方式?
打包用命令或者放到容器中運(yùn)行
用 Maven/ Gradle 插件運(yùn)行
直接執(zhí)行 main 方法運(yùn)行
12. Spring Boot 需要獨(dú)立的容器運(yùn)行嗎?
可以不需要,內(nèi)置了 Tomcat/ Jetty 等容器。
13. 開啟 Spring Boot 特性有哪幾種方式?
繼承
spring-boot-starter-parent
項(xiàng)目導(dǎo)入
spring-boot-dependencies
項(xiàng)目依賴
【文末有驚喜】
【文末有驚喜】
【文末有驚喜】
14. SpringBoot 實(shí)現(xiàn)熱部署有哪幾種方式?
熱部署就是可以不用重新運(yùn)行SpringBoot項(xiàng)目可以實(shí)現(xiàn)操作后臺代碼自動更新到以運(yùn)行的項(xiàng)目中
主要有兩種方式:
模板熱部署
spring-boot-devtools
Spring Loaded
JRebel(插件)
<dependency>
??<groupId>org.springframework.boot</groupId>
??<artifactId>spring-boot-devtools</artifactId>
</dependency>
15. SpringBoot事務(wù)的使用?
1、啟動類加上@EnableTransactionManagement
注解,開啟事務(wù)支持(其實(shí)默認(rèn)是開啟的)。
2、在使用事務(wù)的public(只有public支持事務(wù))方法(或者類-相當(dāng)于該類的所有public方法都使用)加上@Transactional
注解。
16. Async異步調(diào)用方法?
在SpringBoot中使用異步調(diào)用是很簡單的,只需要在方法上使用@Async注解即可實(shí)現(xiàn)方法的異步
調(diào)用。注意:需要在啟動類加入@EnableAsync
使異步調(diào)用@Async注解生效。
@Configuration
//主要是為了掃描范圍包下的所有?@Async注解
@EnableAsync
public?class?AsyncConfiguration?{
?
}
17. 如何在 Spring Boot 啟動的時(shí)候運(yùn)行一些特定的代碼?
可以實(shí)現(xiàn)接口ApplicationRunner
或者CommandLineRunner
,這兩個接口實(shí)現(xiàn)方式一樣,它們都只提供了一個 run 方法
18. Spring Boot 有哪幾種讀取配置的方式?
Spring Boot 可以通過@PropertySource
、@Value
、@Environment
、@ConfigurationProperties
注解來綁定變量
19. 什么是 JavaConfig?
Spring JavaConfig 是 Spring 社區(qū)的產(chǎn)品,Spring 3.0 引入了他,它提供了配置 Spring IOC 容器的純Java 方法。因此它有助于避免使用 XML 配置。使用 JavaConfig 的優(yōu)點(diǎn)在于:
面向?qū)ο蟮呐渲谩S捎谂渲帽欢x為 JavaConfig 中的類,因此用戶可以充分利用 Java 中的面向?qū)ο蠊δ堋?/p>
一個配置類可以繼承另一個,重寫它的@Bean 方法等。
減少或消除 XML 配置
。基于依賴注入原則的外化配置的好處已被證明。但是,許多開發(fā)人員不希望在 XML 和 Java 之間來回切換。
JavaConfig 為開發(fā)人員提供了一種純 Java 方法來配置與 XML 配置概念相似的 Spring 容器。
從技術(shù)角度來講,只使用 JavaConfig 配置類來配置容器是可行的,但實(shí)際上很多人認(rèn)為將JavaConfifig 與 XML 混合匹配是理想的。
類型安全和重構(gòu)友好。JavaConfig 提供了一種類型安全的方法來配置 Spring容器。
由于 Java5.0 對泛型的支持,
現(xiàn)在可以按類型而不是按名稱檢索 bean,不需要任何強(qiáng)制轉(zhuǎn)換或基于字符串的查找。
常用的Java config:
@Configuration:在類上寫下此注解,表示這個類是配置類
@ComponentScan:在配置類上添加
@ComponentScan
注解。該注解默認(rèn)會掃描該類所在的包下所有的配置類,相當(dāng)于之前的<context:component-scan >
。@Bean:bean的注入:相當(dāng)于以前的
< bean id=“objectMapper” class=“org.codehaus.jackson.map.ObjectMapper” />
@EnableWebMvc:相當(dāng)于xml的
<mvc:annotation-driven >
@ImportResource:相當(dāng)于xml的
< import resource="applicationContextcache.xml">

20. SpringBoot的自動配置原理是什么?
主要是Spring Boot的啟動類上的核心注解SpringBootApplication
注解主配置類,有了這個主配置類啟動時(shí)就會為SpringBoot開啟一個@EnableAutoConfiguration
注解自動配置功能。
有了這個EnableAutoConfiguration
的話就會:
從配置文件
META_INF/Spring.factories
加載可能用到的自動配置類去重,并將exclude和excludeName屬性攜帶的類排除
過濾,將滿足條件(
@Conditional
)的自動配置類返回
21. 你如何理解 Spring Boot 配置加載順序?
在 Spring Boot 里面,可以使用以下幾種方式來加載配置。
properties文件;
YAML文件;
系統(tǒng)環(huán)境變量;
命令行參數(shù);
22. 什么是 YAML?
YAML 是一種人類可讀的數(shù)據(jù)序列化語言。它通常用于配置文件。與屬性文件相比,如果我們想要在配置文件中添加復(fù)雜的屬性,YAML 文件就更加結(jié)構(gòu)化,而且更少混淆??梢钥闯?YAML 具有分層配置數(shù)據(jù)。
23. YAML 配置的優(yōu)勢在哪里 ?
YAML 現(xiàn)在可以算是非常流行的一種配置文件格式了,無論是前端還是后端,都可以見到 YAML 配置。那么 YAML 配置和傳統(tǒng)的 properties 配置相比到底有哪些優(yōu)勢呢?
配置有序,在一些特殊的場景下,配置有序很關(guān)鍵
簡潔明了,他還支持?jǐn)?shù)組,數(shù)組中的元素可以是基本數(shù)據(jù)類型也可以是對象
相比 properties 配置文件,YAML 還有一個缺點(diǎn),就是不支持@PropertySource
注解導(dǎo)入自定義的 YAML 配置。
24. Spring Boot 是否可以使用 XML 配置 ?
Spring Boot 推薦使用 Java 配置而非 XML 配置,但是 Spring Boot 中也可以使用 XML 配置,通過@ImportResource
注解可以引入一個 XML 配置。
25. spring boot 核心配置文件是什么?bootstrap.properties 和application.properties 有何區(qū)別 ?
單純做 Spring Boot 開發(fā),可能不太容易遇到bootstrap.properties
配置文件,但是在結(jié)合Spring Cloud 時(shí),這個配置就會經(jīng)常遇到了,特別是在需要加載一些遠(yuǎn)程配置文件的時(shí)侯。
spring boot 核心的兩個配置文件:bootstrap (. yml 或者 . properties):boostrap 由父 ApplicationContext 加載的,比applicaton 優(yōu)先加載,配置在應(yīng)用程序上下文的引導(dǎo)階段生效。
一般來說我們在 Spring Cloud 配置就會使用這個文件。且 boostrap 里面的屬性不能被覆蓋;application (. yml 或者 . properties):由ApplicatonContext 加載,用于 spring boot 項(xiàng)目的自動化配置。
26. 什么是 Spring Profiles?
在項(xiàng)目的開發(fā)中,有些配置文件在開發(fā)、測試或者生產(chǎn)等不同環(huán)境中可能是不同的,例如數(shù)據(jù)庫連接、redis的配置等等。那我們?nèi)绾卧诓煌h(huán)境中自動實(shí)現(xiàn)配置的切換呢?Spring給我們提供了profiles機(jī)制給我們提供的就是來回切換配置文件的功能
Spring Profiles 允許用戶根據(jù)配置文件(dev,test,prod 等)來注冊 bean。因此,當(dāng)應(yīng)用程序在開發(fā)中運(yùn)行時(shí),只有某些 bean 可以加載,而在 PRODUCTION中,某些其他 bean 可以加載。
假設(shè)我們的要求是 Swagger 文檔僅適用于 QA 環(huán)境,并且禁用所有其他文檔。這可以使用配置文件來完成。Spring Boot 使得使用配置文件非常簡單。
spring.profiles.active
spring:
?profiles:
??active:?dev
指定激活哪個文件,值是application-{profileName}.yml
中的 profileName。用于區(qū)分不同的運(yùn)行環(huán)境。
【文末有驚喜】
【文末有驚喜】
【文末有驚喜】
27. SpringBoot多數(shù)據(jù)源拆分的思路?
先在properties配置文件中配置兩個數(shù)據(jù)源,創(chuàng)建分包mapper,使用@ConfigurationProperties
讀取properties中的配置,使用@MapperScan
注冊到對應(yīng)的mapper包中
28. SpringBoot多數(shù)據(jù)源事務(wù)如何管理?
第一種方式是在service層的@TransactionManager
中使用transactionManager
指定
DataSourceConfig
中配置的事務(wù)
第二種是使用jta-atomikos
實(shí)現(xiàn)分布式事務(wù)管理
29. 保護(hù) Spring Boot 應(yīng)用有哪些方法?
在生產(chǎn)中使用HTTPS
使用Snyk檢查你的依賴關(guān)系
升級到最新版本
啟用CSRF保護(hù)
使用內(nèi)容安全策略防止XSS攻擊

30. 如何實(shí)現(xiàn) Spring Boot 應(yīng)用程序的安全性?
為了實(shí)現(xiàn) Spring Boot 的安全性,我們使用spring-boot-starter-security
依賴項(xiàng),并且必須添加安全配置。它只需要很少的代碼。配置類將必須擴(kuò)展WebSecurityConfigurerAdapter
并覆蓋其方法。
31. 比較一下 Spring Security 和 Shiro 各自的優(yōu)缺點(diǎn) ?
由于 Spring Boot 官方提供了大量的非常方便的開箱即用的 Starter ,包括 Spring Security 的Starter ,使得在 Spring Boot 中使用 Spring Security 變得更加容易,甚至只需要添加一個依賴就可以保護(hù)所有的接口,所以,如果是 Spring Boot 項(xiàng)目,一般選擇 Spring Security 。
當(dāng)然這只是一個建議的組合,單純從技術(shù)上來說,無論怎么組合,都是沒有問題的。Shiro 和 Spring Security相比,主要有如下一些特點(diǎn):
Spring Security 是一個重量級的安全管理框架;Shiro 則是一個輕量級的安全管理框架
Spring Security 概念復(fù)雜,配置繁瑣;Shiro 概念簡單、配置簡單
Spring Security 功能強(qiáng)大;Shiro 功能簡單
32. Spring Boot 中如何解決跨域問題 ?
跨域可以在前端通過 JSONP 來解決,但是 JSONP 只可以發(fā)送 GET 請求,無法發(fā)送其他類型的請求,在 RESTful 風(fēng)格的應(yīng)用中,就顯得非常雞肋,因此我們推薦在后端通過 (CORS,Cross origin resource sharing
)來解決跨域問題。這種解決方案并非 Spring Boot 特有的,在傳統(tǒng)的SSM 框架中,就可以通過 CORS 來解決跨域問題,只不過之前我們是在 XML 文件中配置 CORS ,
現(xiàn)在可以通過實(shí)現(xiàn)WebMvcConfigurer
接口然后重寫addCorsMappings
方法解決跨域問題。
@Configuration
public?class?MyWebMvcConfig?implements?WebMvcConfigurer?{
?
????@Override
????public?void?addCorsMappings(CorsRegistry?registry)?{
????????registry.addMapping("/**")
????????????????.allowedHeaders("*")
????????????????.allowedMethods("*")
????????????????.maxAge(1800)
????????????????.allowedOrigins("*");
????}
}
33. Spring Boot 中的監(jiān)視器是什么?
Spring boot actuator 是 spring 啟動框架中的重要功能之一。Spring boot 監(jiān)視器可幫助您訪問生產(chǎn)環(huán)境中正在運(yùn)行的應(yīng)用程序的當(dāng)前狀態(tài)。有幾個指標(biāo)必須在生產(chǎn)環(huán)境中進(jìn)行檢查和監(jiān)控。即使一些外部應(yīng)用程序可能正在使用這些服務(wù)來向相關(guān)人員觸發(fā)警報(bào)消息。監(jiān)視器模塊公開了一組可直接作為 HTTP URL 訪問的REST 端點(diǎn)來檢查狀態(tài)。
34. 如何使用 Spring Boot 實(shí)現(xiàn)全局異常處理?
全局異常處理可以用兩個注解來實(shí)現(xiàn):@ControllerAdvice+@ExceptionHandler
。
這樣可以捕獲 Controller中拋出的指定類型異常,可對不同類型的異常單獨(dú)進(jìn)行處理。
@Slf4j
@ControllerAdvice
public?class?GlobalExceptionAdvice?{
????@ExceptionHandler({Exception.class})
????@ResponseBody
????public?Object?handleException(HttpServletRequest?request,?Exception?e)?throws?Exception?{
????????log.error(e.getMessage(),?e);
????????//?如果某個自定義異常有@ResponseStatus注解,就繼續(xù)拋出
????????if?(AnnotationUtils.findAnnotation(e.getClass(),?ResponseStatus.class)?!=?null)?{
????????????throw?e;
????????}
????????HashMap<String,?Object>?map?=?new?HashMap<>();
????????map.put("message",?"全局異常處理"?+?e.getMessage());
????????return?map;
????}
}
35. 我們?nèi)绾伪O(jiān)視所有 Spring Boot 微服務(wù)?
Spring Boot 提供監(jiān)視器端點(diǎn)以監(jiān)控各個微服務(wù)的度量。這些端點(diǎn)對于獲取有關(guān)應(yīng)用程序的信息(如它們是否已啟動)以及它們的組件(如數(shù)據(jù)庫等)是否正常運(yùn)行很有幫助。但是,使用監(jiān)視器的一個主要缺點(diǎn)或困難是,我們必須單獨(dú)打開應(yīng)用程序的知識點(diǎn)以了解其狀態(tài)或健康狀況。
想象一下涉及 50 個應(yīng)用程序的微服務(wù),管理員將不得不擊中所有 50 個應(yīng)用程序的執(zhí)行終端。為了幫助我們處理這種情況,我們將使用位于https://github.com/codecentric/spring-boot-admin
的開源項(xiàng)目。它建立在Spring Boot Actuator
之上,它提供了一個 Web UI,使我們能夠可視化多個應(yīng)用程序的度量。
36. SpringBoot性能如何優(yōu)化?
一、優(yōu)化注解@SpringBootApplication
@SpringBootApplication
是Springboot 整合的一個復(fù)合注解,作用相當(dāng)于@Configuration + @EnableAutoConfiguration + @ComponentScan
由于其中包括有包掃描的注解@ComponentScan
,這會導(dǎo)致項(xiàng)目啟動時(shí)間變長(啟動一個大的應(yīng)用程序或做大量的集成測試啟動應(yīng)用程序時(shí),影響會特別明顯),會加載一些多余的實(shí)例(Beans),也會增加 CPU 消耗。所以可以將@SpringBootApplication
注解改為@EnableAutoConfiguration + @Configuration + 在我們需要的 bean 上進(jìn)行顯式配置注解
。
二、將 Servlet 容器由 Tomcat 變成 Undertow
三、JVM 調(diào)優(yōu)
【文末有驚喜】
【文末有驚喜】
【文末有驚喜】
37. 如何重新加載 Spring Boot 上的更改,而無需重新啟動服務(wù)器?Spring Boot項(xiàng)目如何熱部署?
這可以使用 DEV 工具來實(shí)現(xiàn)。通過這種依賴關(guān)系,您可以節(jié)省任何更改,嵌入式tomcat 將重新啟動。Spring Boot 有一個開發(fā)工具(DevTools)模塊,它有助于提高開發(fā)人員的生產(chǎn)力。
Java 開發(fā)人員面臨的一個主要挑戰(zhàn)是將文件更改自動部署到服務(wù)器并自動重啟服務(wù)器。開發(fā)人員可以重新加載 Spring Boot 上的更改,而無需重新啟動服務(wù)器。這將消除每次手動部署更改的需要。SpringBoot 在發(fā)布它的第一個版本時(shí)沒有這個功能。
這是開發(fā)人員最需要的功能。DevTools 模塊完全滿足開發(fā)人員的需求。該模塊將在生產(chǎn)環(huán)境中被禁用。它還提供 H2 數(shù)據(jù)庫控制臺以更好地測試應(yīng)用程序。
38. SpringBoot微服務(wù)中如何實(shí)現(xiàn) session 共享 ?
在微服務(wù)中,一個完整的項(xiàng)目被拆分成多個不相同的獨(dú)立的服務(wù),各個服務(wù)獨(dú)立部署在不同的服務(wù)器上,各自的 session 被從物理空間上隔離開了,但是經(jīng)常,我們需要在不同微服務(wù)之間共享session ,常見的方案就是 Spring Session + Redis 來實(shí)現(xiàn) session 共享。
將所有微服務(wù)的session 統(tǒng)一保存在 Redis 上,當(dāng)各個微服務(wù)對 session 有相關(guān)的讀寫操作時(shí),都去操作 Redis 上的 session 。這樣就實(shí)現(xiàn)了 session 共享,Spring Session 基于 Spring 中的代理過濾器實(shí)現(xiàn),使得 session 的同步操作對開發(fā)人員而言是透明的,非常簡便。
<dependency>
?<groupId>org.springframework.boot</groupId>
?<artifactId>spring-boot-devtools</artifactId>
</dependency>
39. 您使用了哪些 starter maven 依賴項(xiàng)?
使用了下面的一些依賴項(xiàng)
spring-boot-starter-web
嵌入tomcat和web開發(fā)需要servlet與jsp支持spring-boot-starter-data-jpa
數(shù)據(jù)庫支持spring-boot-starter-data-redis
redis數(shù)據(jù)庫支持spring-boot-starter-data-solr
solr支持mybatis-spring-boot-starter
第三方的mybatis集成starter
40. Spring Boot 中的 starter 到底是什么 ?
這個 Starter 并非什么新的技術(shù)點(diǎn),基本上還是基于 Spring 已有功能來實(shí)現(xiàn)的。
首先它提供了一個自動化配置類,一般命名為XXXAutoConfiguration
,在這個配置類中通過條件注解來決定一個配置是否生效(條件注解就是 Spring 中原本就有的),然后它還會提供一系列的默認(rèn)配置,也允許開發(fā)者根據(jù)實(shí)際情況自定義相關(guān)配置,然后通過類型安全的屬性注入將這些配置屬性注入進(jìn)來,新注入的屬性會代替掉默認(rèn)屬性。
正因?yàn)槿绱?,很多第三方框架,我們只需要引入依賴就可以直接使用了。?dāng)然,開發(fā)者也可以自定義 Starter
41. Spring Boot 中如何實(shí)現(xiàn)定時(shí)任務(wù) ?
在 Spring Boot 中使用定時(shí)任務(wù)主要有兩種不同的方式,一個就是使用 Spring 中的@Scheduled
注解,另一-個則是使用第三方框架 Quartz。
使用 Spring 中的@Scheduled
的方式主要通過@Scheduled
注解來實(shí)現(xiàn)。
42. spring-boot-starter-parent 有什么用 ?
我們都知道,新創(chuàng)建一個 Spring Boot 項(xiàng)目,默認(rèn)都是有 parent 的,這個 parent 就是spring-boot-starter-parent
,spring-boot-starter-parent
主要有如下作用:
定義了 Java 編譯版本為 1.8 。
使用 UTF-8 格式編碼。
繼承自
spring-boot-dependencies
,這個里邊定義了依賴的版本,也正是因?yàn)槔^承了這個依賴,所以我們在寫依賴時(shí)才不需要寫版本號。執(zhí)行打包操作的配置。
自動化的資源過濾。
自動化的插件配置。
針對
application.properties
和application.yml
的資源過濾,包括通過 profile 定義的不同環(huán)境的配置文件,例如application-dev.properties
和application-dev.yml
。
總結(jié)就是打包用的
43. SpringBoot如何實(shí)現(xiàn)打包?
進(jìn)入項(xiàng)目目錄在控制臺輸入mvn clean package
,clean是清空已存在的項(xiàng)目包,package進(jìn)行打包;或者點(diǎn)擊左邊選項(xiàng)欄中的Maven,先點(diǎn)擊clean在點(diǎn)擊package
44. Spring Boot 打成的 jar 和普通的 jar 有什么區(qū)別 ?
Spring Boot 項(xiàng)目最終打包成的 jar 是可執(zhí)行 jar ,這種 jar 可以直接通過java -jar xxx.jar
命令來運(yùn)行,這種 jar 不可以作為普通的 jar 被其他項(xiàng)目依賴,即使依賴了也無法使用其中的類。
Spring Boot 的 jar 無法被其他項(xiàng)目依賴,主要還是他和普通 jar 的結(jié)構(gòu)不同。普通的 jar 包,解壓后直接就是包名,包里就是我們的代碼,而 Spring Boot 打包成的可執(zhí)行 jar 解壓后,在\BOOT-INF\classes
目錄下才是我們的代碼,因此無法被直接引用。如果非要引用,可以在 pom.xml文件中增加配置,將 Spring Boot 項(xiàng)目打包成兩個 jar ,一個可執(zhí)行,一個可引用。
相關(guān)電子書籍


有需要的小伙伴一鍵三連后臺主動打招呼即可獲取哦~~~~