首頁  >  文章  >  資料庫  >  收藏! Spring必須掌握的內容

收藏! Spring必須掌握的內容

coldplay.xixi
coldplay.xixi轉載
2020-09-29 18:05:122066瀏覽

mysql教學欄位為大家介紹Spring必須掌握的內容。

大家好!我是熱心的朝陽群眾。

Spring框架在面試中是一個必問點,裡面究竟有哪些內容呢?讓我們一起來看看。這也是我在面試中常問到的問題,也是展現程式設計師對框架理解的能力。

介紹Spring框架

#Spring是一種輕量級框架,旨在提高開發人員的開發效率以及系統的可維護性。

我們一般說的Spring框架就是Spring Framework,它是許多模組的集合,使用這些模組可以很方便地協助我們進行開發。這些模組是核心容器、資料存取/整合、Web、AOP(面向切面程式設計)、工具、訊息和測試模組。例如Core Container中的Core元件是Spring所有元件的核心,Beans元件和Context元件是實作IOC和DI的基礎,AOP元件用來實現面向切面程式設計。

Spring的6個特徵:

  • 核心技術:依賴注入(DI),AOP,事件(Events),資源,i18n,驗證,資料綁定,類型轉換,SpEL;
  • 測試:模擬對象,TestContext框架,Spring MVC測試,WebTestClient;
  • #資料存取:事務,DAO支持,JDBC,ORM,編組XML;
  • #Web支援:Spring MVC和Spring WebFlux Web框架;
  • #整合:遠端處理,JMS,JCA,JMX,電子郵件,任務,調度,快取;
  • 語言:Kotlin,Groovy,動態語言;

#列舉一些重要的Spring模組

下圖對應的是Spring 4.x的版本,目前最新的5.x版本中Web模組的Portlet元件已經被廢棄掉,同時增加了用於非同步響應式處理的WebFlux元件。

  • Spring Core:基礎,可以說Spring其他所有的功能都依賴於該類別庫。主要提供IOC和DI功能。
  • Spring Aspects:此模組為與AspectJ的整合提供支援。
  • Spring AOP:提供面向方面的程式實作。
  • Spring JDBC:Java資料庫連線。
  • Spring JMS:Java訊息服務。
  • Spring ORM:用於支援Hibernate等ORM工具。
  • Spring Web:為建立網路應用程式提供支援。
  • Spring Test:提供了對JUnit和TestNG測試的支援。

談談自己對Spring IOC和AOP的理解

IOC

IOC(Inversion Of Controll,控制反轉)是一種設計思想,就是將原本在程式中手動建立物件的控制權,交由給Spring框架來管理。 IOC在其他語言中也有應用,並非Spring特有。 IOC容器是Spring用來實現IOC的載體,IOC容器其實就是一個Map(key, value),Map中存放的是各種物件。

將物件之間的相互依賴關係交給IOC容器來管理,並由IOC容器完成物件的注入。這樣可以很大程度上簡化應用的開發,把應用從複雜的依賴關係中解放出來。 IOC容器就像是工廠一樣,當我們需要建立一個物件的時候,只需要配置好設定檔/註解即可,完全不用考慮物件是如何被建立出來的。在實際專案中一個Service類別可能由幾百甚至上千個類別作為它的底層,假如我們需要實例化這個Service,可能要每次都搞清楚這個Service所有底層類別的建構函數,這可能會把人逼瘋。如果利用IOC的話,你只需要配置好,然後在需要的地方引用就行了,大大增加了專案的可維護性且降低了開發難度。

Spring時代我們通常透過XML檔案來設定Bean,後來開發人員覺得用XML檔案來設定不太好,於是Sprng Boot註解配置就慢慢開始流行起來。

AOP

#AOP(Aspect-Oriented Programming,針對切面程式設計)能夠將那些與業務無關,卻為業務模組所共同調用的邏輯或責任(例如事務處理、日誌管理、權限控制等)封裝起來,便於減少系統的重複代碼,降低模組間的耦合度,並有利於未來的可擴展性和可維護性。

Spring AOP是基於動態代理的,如果要代理的對象實現了某個接口,那麼Spring AOP就會使用JDK動態代理去創建代理對象;而對於沒有實現接口的對象,就無法使用JDK動態代理,轉而使用CGlib動態代理產生一個被代理物件的子類別來作為代理。

當然也可以使用AspectJ,Spring AOP中已經整合了AspectJ,AspectJ應該算是Java生態系中最完整的AOP框架了。使用AOP之後我們可以把一些通用功能抽像出來,在需要用到的地方直接使用即可,這樣可以大幅簡化程式碼量。我們需要增加新功能也方便,提高了系統的擴充性。日誌功能、事務管理和權限管理等場景都用到了AOP。

Spring AOP和AspectJ AOP的差別

Spring AOP是屬於執行時間增強,而AspectJ是編譯時增強。 Spring AOP是基於代理(Proxying),而AspectJ則是基於字節碼操作(Bytecode Manipulation)。

Spring AOP已經整合了AspectJ,AspectJ應該算是Java生態系中最完整的AOP框架了。 AspectJ比起Spring AOP功能更強大,但是Spring AOP相對來說更簡單。

如果我們的切面比較少,那麼兩者性能差異不大。但是,當切面太多的話,最好選擇AspectJ,它比SpringAOP快很多。

Spring中的bean的作用域有哪些?

  1. singleton:唯一bean實例,Spring中的bean預設都是單例的。
  2. prototype:每次請求都會建立一個新的bean實例。
  3. request:每個HTTP請求都會產生一個新的bean,該bean只在目前HTTP request內有效。
  4. session:每一個HTTP請求都會產生一個新的bean,該bean只在目前HTTP session內有效。
  5. global-session:全域session作用域,僅在基於Portlet的Web應用中才有意義,Spring5中已經沒有了。 Portlet是能夠產生語意程式碼(例如HTML)片段的小型Java Web外掛程式。它們是基於Portlet容器,可以像Servlet一樣處理HTTP請求。但是與Servlet不同,每個Portlet都有不同的會話。

Spring中的單例bean的執行緒安全性問題了解嗎?

大部分時候我們並沒有在系統中使用多線程,所以很少人會關注這個問題。單例bean存在線程問題,主要是因為當多個線程操作同一個物件的時候,對這個物件的非靜態成員變數的寫入操作會存在線程安全問題。

有兩種常見的解決方案:

  1. #在bean物件中盡量避免定義可變的成員變數(不太現實)。
  2. 在類別中定義一個ThreadLocal成員變量,將所需的可變成員變數保存在ThreadLocal中(建議的一種方式)。

Spring中的bean生命週期?

  1. Bean容器找到設定檔中Spring Bean的定義。
  2. Bean容器利用Java Reflection API建立一個Bean的實例。
  3. 如果涉及一些屬性值,就利用set()方法來設定一些屬性值。
  4. 如果Bean實作了BeanNameAware接口,呼叫setBeanName()方法,傳入Bean的名字。
  5. 如果Bean實作了BeanClassLoaderAware接口,呼叫setBeanClassLoader()方法,傳入ClassLoader物件的實例。
  6. 如果Bean實作了BeanFactoryAware接口,呼叫setBeanClassFacotory()方法,傳入ClassLoader物件的實例。
  7. 與上面的類似,如果實作了其他*Aware接口,就呼叫對應的方法。
  8. 如果有和載入這個Bean的Spring容器相關的BeanPostProcessor對象,執行postProcessBeforeInitialization()方法。
  9. 如果Bean實作了InitializingBean接口,執行afeterPropertiesSet()方法。
  10. 如果Bean在設定檔中的定義包含init-method屬性,執行指定的方法。
  11. 如果有和載入這個Bean的Spring容器相關的BeanPostProcess對象,執行postProcessAfterInitialization()方法。
  12. 當要銷毀Bean的時候,如果Bean實作了DisposableBean接口,執行destroy()方法。
  13. 當要銷毀Bean的時候,如果Bean在設定檔中的定義包含destroy-method屬性,執行指定的方法。

#說自己對於Spring MVC的了解?

談到這個問題,我們不得不提列之前Model1和Model2這兩個沒有Spring MVC的時代。

**Model1時代:**很多學Java比較晚的後端程式設計師可能沒有接觸過Model1模式下的JavaWeb應用開發。在Model1模式下,整個Web應用程式幾乎全部用JSP頁面組成,只用少量的JavaBean來處理資料庫連接,存取等操作。這個模式下JSP即是控制層又是表現層。顯而易見,這種模式存在著許多問題。例如將控制邏輯和表現邏輯混雜在一起,導致程式碼重用率極低;又例如前端和後端相互依賴,難以進行測試且開發效率極低。

Model2時代:學過Servlet並做過相關Demo的朋友應該了解Java Bean(Model) JSP(View) Servlet(Controller)這種開發模式,這就是早期的Java Web MVC開發模式。 Model是系統中涉及的數據,也就是dao和bean;View是用來展示模型中的數據,只是用來展示;Controller是將用戶請求都發送給Servlet做處理,返回數據給JSP並展示給用戶。

Model2模式下還存在很多問題,Model2的抽象和封裝程度還遠遠不夠,使用Model2進行開發時不可避免地會重複造輪子,這就大大降低了程式的可維護性和可復用性。於是許多Java Web開發相關的MVC框架應運而生,例如Struts2,但由於Struts2比較笨重,隨著Spring輕量級開發框架的流行,Spring生態圈出現了Spring MVC框架。 Spring MVC是目前最優秀的MVC框架,相較於Struts2,Spring MVC使用更加簡單和方便,開發效率更高,並且Spring MVC運行速度更快。

MVC是一種設計模式,Spring MVC是一款很優秀的MVC框架。 Spring MVC可以幫助我們進行更簡潔的Web層的開發,並且它天生與Spring框架整合。 Spring MVC下我們一般把後端專案分成Service層(處理業務)、Dao層(資料庫操作)、Entity層(實體類別)、Controller層(控制層,回傳資料給前台頁面)。

Spring MVC的簡單原理圖如下:

談談Spring MVC的工作原理

流程說明:

1.客戶端(瀏覽器)傳送請求,直接請求到DispatcherServlet。

2.DispatcherServlet根據請求資訊呼叫HandlerMapping,解析請求對應的Handler。

3.解析到對應的Handler(也就是我們平常說的Controller控制器)。

4.HandlerAdapter會根據Handler來呼叫真正的處理器來處理請求和執行相對應的業務邏輯。

5.處理器處理完業務後,會傳回一個ModelAndView對象,Model是傳回的資料對象,View是邏輯上的View。

6.ViewResolver會根據邏輯View去找實際的View。

7.DispatcherServlet把回傳的Model傳給View(視圖渲染)。

8.把View回傳給請求者(瀏覽器)。

##Spring框架中用到了哪些設計模式?

  1. 工廠設計模式:Spring使用工廠模式透過BeanFactory和ApplicationContext建立bean物件。
  2. 代理程式設計模式:Spring AOP功能的實作。
  3. 單例設計模式:Spring中的bean預設都是單例的。
  4. 模板方法模式:Spring中的jdbcTemplate、hibernateTemplate等以Template結尾的對資料庫操作的類,它們就使用到了模板模式。
  5. 包裝器設計模式:我們的專案需要連接多個資料庫,不同的客戶在每次存取中會根據需要會去存取不同的資料庫。這種模式讓我們可以根據客戶的需求能夠動態切換不同的資料來源。
  6. 觀察者模式:Spring事件驅動模型就是觀察者模式很經典的一個應用。
  7. 適配器模式:Spring AOP的增強或通知(Advice)使用到了適配器模式、Spring MVC中也是用到了適配器模式適配器Controller。

@Component和@Bean的差別是什麼?

  1. 作用物件不同。 @Component註解作用於類,而@Bean註解作用於方法。
  2. @Component註解通常是透過類別路徑掃描來自動偵測以及自動組裝到Spring容器中(我們可以使用@ComponentScan註解定義要掃描的路徑)。 @Bean註解通常是在標有該註解的方法中定義產生這個bean,告訴Spring這是某個類別的實例,當我需要用它的時候還給我。
  3. @Bean註解比@Component註解的自訂性更強,而且很多地方只能透過@Bean註解來註冊bean。例如引用第三方函式庫的類別需要組裝到Spring容器的時候,就只能透過@Bean註解來實現。

@Bean註解的使用範例:

@Configurationpublic class AppConfig {    @Bean    public TransferService transferService() {        return new TransferServiceImpl();    }}复制代码

上面的程式碼相當於下面的XML設定:

<beans>    <bean id="transferService" class="com.common.TransferServiceImpl"/></beans>复制代码

下面這個範例是無法通過@ Component註解實現的:

@Beanpublic OneService getService(status) {    case (status)  {        when 1:                return new serviceImpl1();        when 2:                return new serviceImpl2();        when 3:                return new serviceImpl3();    }}复制代码

将一个类声明为Spring的bean的注解有哪些?

我们一般使用@Autowired注解去自动装配bean。而想要把一个类标识为可以用@Autowired注解自动装配的bean,可以采用以下的注解实现:

  1. @Component注解。通用的注解,可标注任意类为Spring组件。如果一个Bean不知道属于哪一个层,可以使用@Component注解标注。
  2. @Repository注解。对应持久层,即Dao层,主要用于数据库相关操作。
  3. @Service注解。对应服务层,即Service层,主要涉及一些复杂的逻辑,需要用到Dao层(注入)。
  4. @Controller注解。对应Spring MVC的控制层,即Controller层,主要用于接受用户请求并调用Service层的方法返回数据给前端页面。

Spring事务管理的方式有几种?

  1. 编程式事务:在代码中硬编码(不推荐使用)。
  2. 声明式事务:在配置文件中配置(推荐使用),分为基于XML的声明式事务和基于注解的声明式事务。

Spring事务中的隔离级别有哪几种?

在TransactionDefinition接口中定义了五个表示隔离级别的常量:

**ISOLATION_DEFAULT:**使用后端数据库默认的隔离级别,Mysql默认采用的REPEATABLE_READ隔离级别;Oracle默认采用的READ_COMMITTED隔离级别。

**ISOLATION_READ_UNCOMMITTED:**最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。

**ISOLATION_READ_COMMITTED:**允許讀取並發事務已經提交的數據,可以阻止臟讀,但是幻讀或不可重複讀仍有可能發生

**ISOLATION_REPEATABLE_READ:**對同一字段的多次讀取結果都是一致的,除非資料是被本身事務自己所修改,可以阻止髒讀和不可重複讀,但幻讀仍有可能發生。

**ISOLATION_SERIALIZABLE:**最高的隔離級別,完全服從ACID的隔離級別。所有的事務依序逐一執行,這樣事務之間就完全不可能產生幹擾,也就是說,該層級可以防止髒讀、不可重複讀以及幻讀。但是這將嚴重影響程式的效能。通常情況下也不會用到該等級。

Spring事務中有哪幾種事務傳播行為?

在TransactionDefinition介面中定義了八個表示交易傳播行為的常數。

支援目前交易的情況:

#**PROPAGATION_REQUIRED:**如果目前存在事務,則加入該事務;如果目前沒有事務,則建立一個新的事務。

PROPAGATION_SUPPORTS: 如果目前存在事務,則加入該事務;如果目前沒有事務,則以非事務的方式繼續運作。

PROPAGATION_MANDATORY: 如果目前存在事務,則加入該交易;如果目前沒有事務,則拋出例外。 (mandatory:強制性)。

不支援目前交易的狀況:

PROPAGATION_REQUIRES_NEW: 建立一個新的交易,如果目前存在事務,則把當前事務掛起。

PROPAGATION_NOT_SUPPORTED: 以非交易方式運行,如果目前存在事務,則把目前交易掛起。

PROPAGATION_NEVER: 以非交易方式運行,如果目前存在事務,則拋出例外。

其他情況:

PROPAGATION_NESTED:

如果目前存在事務,則建立一個交易作為目前事務的巢狀事務來運作;如果目前沒有事務,則該取值等價於PROPAGATION_REQUIRED。 ###

結束

#希望大家能掌握這些內容,也能繼續支持我,感謝。

更多相關免費學習推薦:##mysql教學(影片)

#

以上是收藏! Spring必須掌握的內容的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.im。如有侵權,請聯絡admin@php.cn刪除