隨着 Spring Boot 使用愈來愈普遍,Spring Boot 已經成爲 Java 程序員面試的知識點,不少同窗對 Spring Boot 理解不是那麼深入,常常就會被幾個連環跑給幹趴下了!前端
好比下面這一段的 Spring Boot 問答:程序員
問:你以爲 Spring Boot 最大的優點是什麼呢?web
答:Spring Boot 的最大的優點是「約定優於配置「。「約定優於配置「是一種軟件設計範式,開發人員按照約定的方式來進行編程,能夠減小軟件開發人員需作決定的數量,得到簡單的好處,而又不失靈活性。面試
問:Spring Boot 中 「約定優於配置「的具體產品體如今哪裏。redis
答:Spring Boot Starter、Spring Boot Jpa 都是「約定優於配置「的一種體現。都是經過「約定優於配置「的設計思路來設計的,Spring Boot Starter 在啓動的過程當中會根據約定的信息對資源進行初始化;Spring Boot Jpa 經過約定的方式來自動生成 Sql ,避免大量無效代碼編寫。具體詳細能夠參考:Spring Boot 爲何這麼火?spring
問:Spring Boot Starter 的工做原理是什麼?sql
答:Spring Boot 在啓動的時候會幹這幾件事情:編程
① Spring Boot 在啓動時會去依賴的 Starter 包中尋找 resources/META-INF/spring.factories 文件,而後根據文件中配置的 Jar 包去掃描項目所依賴的 Jar 包。後端
② 根據 spring.factories 配置加載 AutoConfigure 類跨域
③ 根據 @Conditional 註解的條件,進行自動配置並將 Bean 注入 Spring Context
總結一下,其實就是 Spring Boot 在啓動的時候,按照約定去讀取 Spring Boot Starter 的配置信息,再根據配置信息對資源進行初始化,並注入到 Spring 容器中。這樣 Spring Boot 啓動完畢後,就已經準備好了一切資源,使用過程當中直接注入對應 Bean 資源便可。
這只是簡單的三連環問答,不知道有多少同窗可以完整的回答出來。
其實 Spring Boot 中有不少的技術點能夠挖掘,今天給你們整理了十個高頻 Spring Boot 面試題,但願能夠在後期的面試中幫助到你們。
Spring Boot 項目的啓動註解是:@SpringBootApplication,其實它就是由下面三個註解組成的:
@Configuration
@ComponentScan
@EnableAutoConfiguration
其中 @EnableAutoConfiguration 是實現自動配置的入口,該註解又經過 @Import 註解導入了AutoConfigurationImportSelector,在該類中加載 META-INF/spring.factories 的配置信息。而後篩選出以 EnableAutoConfiguration 爲 key 的數據,加載到 IOC 容器中,實現自動配置功能!
思考一下在你的虛擬機上部署應用程序須要些什麼。
第一步:安裝 Java
第二部:安裝 Web 或者是應用程序的服務器(Tomat/Wbesphere/Weblogic 等等)
第三部:部署應用程序 war 包
若是咱們想簡化這些步驟,應該如何作呢?
讓咱們來思考如何使服務器成爲應用程序的一部分?
你只須要一個安裝了 Java 的虛擬機,就能夠直接在上面部署應用程序了,
是否是很爽?
這個想法是嵌入式服務器的起源。
當咱們建立一個能夠部署的應用程序的時候,咱們將會把服務器(例如,tomcat)嵌入到可部署的服務器中。
例如,對於一個 Spring Boot 應用程序來講,你能夠生成一個包含 Embedded Tomcat 的應用程序 jar。你就能夠像運行正常 Java 應用程序同樣來運行 web 應用程序了。
嵌入式服務器就是咱們的可執行單元包含服務器的二進制文件(例如,tomcat.jar)。
支持分佈式事務,可使用Spring Boot集成 Aatomikos來解決,可是我通常不建議這樣使用,由於使用分佈式事務會增長請求的響應時間,影響系統的TPS。通常在實際工做中,會利用消息的補償機制來處理分佈式的事務。
cas和oauth是一個解決單點登陸的組件,shiro主要是負責權限安全方面的工做,因此功能點不一致。但每每須要單點登錄和權限控制一塊兒來使用,因此就有 cas+shiro或者oauth+shiro這樣的組合。
token通常是客戶端登陸後服務端生成的令牌,每次訪問服務端會進行校驗,通常保存到內存便可,也能夠放到其餘介質;redis能夠作Session共享,若是前端web服務器有幾臺負載,可是須要保持用戶登陸的狀態,這場景使用比較常見。
咱們公司使用oauth+shiro這樣的方式來作後臺權限的管理,oauth負責多後臺統一登陸認證,shiro負責給登陸用戶賦予不一樣的訪問權限。
在傳統的SOA治理中,使用rpc的居多;Spring Cloud默認使用restful進行服務之間的通信。rpc通信效率會比restful要高一些,可是對於大多數公司來說,這點效率影響甚微。我建議使用restful這種方式,易於在不一樣語言實現的服務之間通信。
對於無狀態服務,首先說一下什麼是狀態:若是一個數據須要被多個服務共享,才能完成一筆交易,那麼這個數據被稱爲狀態。進而依賴這個「狀態」數據的服務被稱爲有狀態服務,反之稱爲無狀態服務。
那麼這個無狀態服務原則並非說在微服務架構裏就不容許存在狀態,表達的真實意思是要把有狀態的業務服務改變爲無狀態的計算類服務,那麼狀態數據也就相應的遷移到對應的「有狀態數據服務」中。
場景說明:例如咱們之前在本地內存中創建的數據緩存、Session緩存,到如今的微服務架構中就應該把這些數據遷移到分佈式緩存中存儲,讓業務服務變成一個無狀態的計算節點。遷移後,就能夠作到按需動態伸縮,微服務應用在運行時動態增刪節點,就再也不須要考慮緩存數據如何同步的問題。
@Cacheable ,用來聲明方法是可緩存,將結果存儲到緩存中以便後續使用相同參數調用時不需執行實際的方法,直接從緩存中取值。
@CachePut,使用 @CachePut 標註的方法在執行前,不會去檢查緩存中是否存在以前執行過的結果,而是每次都會執行該方法,並將執行結果以鍵值對的形式存入指定的緩存中。
@CacheEvict,是用來標註在須要清除緩存元素的方法或類上的,當標記在一個類上時表示其中全部的方法的執行都會觸發緩存的清除操做。
現代瀏覽器出於安全的考慮, HTTP 請求時必須遵照同源策略,不然就是跨域的 HTTP 請求,默認狀況下是被禁止的,IP(域名)不一樣、或者端口不一樣、協議不一樣(好比 HTTP、HTTPS)都會形成跨域問題。
通常前端的解決方案有:
① 使用 JSONP 來支持跨域的請求,JSONP 實現跨域請求的原理簡單的說,就是動態建立<script>
標籤,而後利用<script>
的 SRC 不受同源策略約束來跨域獲取數據。缺點是須要後端配合輸出特定的返回信息。
② 利用反應代理的機制來解決跨域的問題,前端請求的時候先將請求發送到同源地址的後端,經過後端請求轉發來避免跨域的訪問。
後來 HTML5 支持了 CORS 協議。CORS 是一個 W3C 標準,全稱是」跨域資源共享」(Cross-origin resource sharing),容許瀏覽器向跨源服務器,發出 XMLHttpRequest 請求,從而克服了 AJAX 只能同源使用的限制。它經過服務器增長一個特殊的 Header[Access-Control-Allow-Origin]來告訴客戶端跨域的限制,若是瀏覽器支持 CORS、而且判斷 Origin 經過的話,就會容許 XMLHttpRequest 發起跨域請求。
前端使用了 CORS 協議,就須要後端設置支持非同源的請求,Spring Boot 設置支持非同源的請求有兩種方式。
第一,配置 CorsFilter。
@Configuration public class GlobalCorsConfig { @Bean public CorsFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); config.addAllowedOrigin("*"); config.setAllowCredentials(true); config.addAllowedMethod("*"); config.addAllowedHeader("*"); config.addExposedHeader("*"); UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource(); configSource.registerCorsConfiguration("/**", config); return new CorsFilter(configSource); } }
須要配置上述的一段代碼。第二種方式稍微簡單一些。
第二,在啓動類上添加:
public class Application extends WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowCredentials(true) .allowedHeaders("*") .allowedOrigins("*") .allowedMethods("*"); } }
JPA自己是一種規範,它的本質是一種ORM規範(不是ORM框架,由於JPA並未提供ORM實現,只是制定了規範)由於JPA是一種規範,因此,只是提供了一些相關的接口,可是接口並不能直接使用,JPA底層須要某種JPA實現,Hibernate 是 JPA 的一個實現集。
JPA 是根據實體類的註解來建立對應的表和字段,若是須要動態建立表或者字段,須要動態構建對應的實體類,再從新調用Jpa刷新整個Entity。動態SQL,mybatis支持的最好,jpa也能夠支持,可是沒有Mybatis那麼靈活。
Spring 最初最核心的兩大核心功能 Spring Ioc 和 Spring Aop 成就了 Spring,Spring 在這兩大核心的功能上不斷的發展,纔有了 Spring 事務、Spring Mvc 等一系列偉大的產品,最終成就了 Spring 帝國,到了後期 Spring 幾乎能夠解決企業開發中的全部問題。
Spring Boot 是在強大的 Spring 帝國生態基礎上面發展而來,發明 Spring Boot 不是爲了取代 Spring ,是爲了讓人們更容易的使用 Spring 。
Spring Cloud 是一系列框架的有序集合。它利用 Spring Boot 的開發便利性巧妙地簡化了分佈式系統基礎設施的開發,如服務發現註冊、配置中心、消息總線、負載均衡、斷路器、數據監控等,均可以用 Spring Boot 的開發風格作到一鍵啓動和部署。
Spring Cloud 是爲了解決微服務架構中服務治理而提供的一系列功能的開發框架,而且 Spring Cloud 是徹底基於 Spring Boot 而開發,Spring Cloud 利用 Spring Boot 特性整合了開源行業中優秀的組件,總體對外提供了一套在微服務架構中服務治理的解決方案。
用一組不太合理的包含關係來表達它們之間的關係。
Spring ioc/aop > Spring > Spring Boot > Spring Cloud