這裡是參考B站上的大佬做的面試題筆記。大家也可以去看視訊講解!!!
文章目錄
- 31、線程池複用的原理
- 32、spring是什麼?
- 33、對Aop的了解
- 34、對IOC的了解
- 35、BeanFactory和ApplicationContext有什麼什麼差別?
- 36、簡述spring bean的生命周期
- 37、spring支援的幾種bean作用域
- 38、Spring架構中的單例Bean是線程安全的嗎
- 39、spring架構中使用了哪些設計模式及應用場景
- 40、spring事務的實作方式原理以及隔離級别
31、線程池複用的原理
- 線程池将線程和任務進行解耦,線程是線程,任務是任務,擺脫了之前通過Thread建立線程時的一個線程必須對應一個任務的限制。
- 線上程池中,同一個線程可以從阻塞隊列中不斷擷取新任務來執行,其核心原理在于線程池對Thread進行了封裝,并不是每次執行任務都會調用Thread.start()來建立線程,而是讓每個線程去執行一個“循環任務”,在這個“循環任務”中不停檢查是否有任務需要被執行,也就是調用任務中的run方法,将run方法當成一個普通的方法執行,通過這種方式隻使用固定的線程就将所有任務的run方法串聯起來
32、spring是什麼?
輕量級的開源的J2EE架構,它是一個容器架構,用來裝javabean(java對象),中間層架構(萬能膠)可以起一個連接配接作用,比如說把Structs和hibernate粘合在一起運用,可以讓我們的企業開發更快,更簡潔
Spring是一個輕量級的控制反轉(IOC)和面向切面(AOP)的容器架構
- 從大小與開銷兩方面而言Spring都是輕量級的。
- 通過控制反轉(IOC)的技術達到松耦合的目的。
- 提供了面向切面程式設計的豐富支援,允許通過分離應用的業務邏輯與系統級服務進行内聚性的開發。
- 包含并管理應用對象(Bean)的配置和生命周期,這個意義上是一個容器
- 将簡單的元件配置,組合成為複雜的應用,這個意思上是一個架構。
33、對Aop的了解
- 系統是由許多不同的元件所組成的每一個元件各負責一塊特定功能。除了實作自身核心功能之外,這些元件還經常承擔着額外的職責。例如日志,事務管理和安全這樣的核心服務經常融入到自身具有核心業務邏輯的元件中去。這些系統服務經常被稱為橫切關注點,因為它們會跨越系統的多個元件。
- 當我們需要為分散的對象引入公共行為的時候,O0P則顯得無能為力。也就是說,OOP允許你定義從上到下的關系,但并不适合定義從左到右的關系,例如日志功能。
- 日志代碼往往水準地散布在所有對象層次中,而與它所散布到的對象的核心功能毫無關系
- 在OOP設計中,它導緻了大量代碼的重複,而不利于各個子產品的複用
- AOP:将程式中的交叉業務邏輯(比如安全、日志、事務等),封裝成了一個切面,然後注入到目标對象(具體業務邏輯)中去,AOP可以對某個對象或某些對象的功能進行增強,比如對象中的方法進行增強,可以在執行某個方法之前額外的做一些事情,在某個方法執行之後額外的做一些事情
34、對IOC的了解
容器概念、控制反轉、依賴注入
IOC容器:
- 實際上就是個map(key,value),裡面存的是各種對象(在xml裡配置的bean節點,@repository、@service、@controller、@component),在項目啟動時的時候會讀取配置檔案裡面的bean節點,根據全限定類名使用反射建立對象放到map裡,掃描到打上上述注解的類還是通過反射建立對象放到map裡。
- 這個時候map裡就有各種對象了,接下來我們在代碼裡需要用到裡面的對象時,再通過DI注入(autowired、resource等注解,xml裡面bean節點内的ref屬性,項目啟動時候會讀取xml節點ref屬性更具DI注入,也會掃描這些注解,根據類型或DI注入,id就是對象名)
控制反轉
- 沒有引入IOC容器之前,對象A依賴與對象B,那麼對象A在初始化或者在運作到某一點的時候,自己必須主動去建立對象B或者使用已經建立的對象B。無論是建立還是使對象B,控制權都在自己手上。
- 引入IOC容器之後,對象A與對象B之間失去了直接關系,當對象A運作到需要對象B的時候,IOC容器會主動去建立一個對象B注入到對象A需要的地方
- 通過前後的對比,不難看出:對象A獲得依賴對象B的過程由主動行為變為了被動行文,控制權颠倒過來了,這就是“控制反轉”這個名稱的由來
全部對象的控制權全部上繳給“第三方“IOC容器、是以,IOC容器成了整個系統的關鍵核心,它起到了一種類似“粘合劑” 的作用,把系統中的所有對象粘合在一起發揮作用,如果沒有這個“粘合劑”,對象與對象之間會彼此失去聯系,這就是有人把IOC容器比喻成“粘合劑”的由來
依賴注入
- 獲得依賴對象的過程被反轉了。控制被反轉之後,獲得對象依賴對象的過程由自身管理變為了由IOC容器主動注入。依賴注入是實作IOC的方法,就是由IOC容器在運作期間,動态地将某種依賴關系注入到對象中。
35、BeanFactory和ApplicationContext有什麼什麼差別?
ApplicationContext是BeanFactory的子接口
ApplicationContext提供了更完整的功能:
- 繼承了MessageSource,是以支援國際化
- 統一的資源檔案通路方式
- 提供在監聽器中注冊bean的事件
- 同時加載多個配置檔案
- 載入多個(有繼承關系)上下文,使得每一個上下文都專注與一個特定的層次,比如應用的web層
BeanFactory
采用的是延遲加載形式來注入Bean的,即隻有在使用到某個Bean時(調用getBean()),才對該Bean進行加載執行個體化。這樣、我們就不能發現一些存在的Spring配置問題。如果Bean的某一個屬性沒有注入,BeanFactory加載後,直至第一次使用調用getBean()方法才會抛出異常
ApplicationContext
,它是在容器啟動時,一次性建立了所有的Bean。這樣,在容器啟動時,我們就可以發現Spring中存在的配置錯誤,這樣有利于檢查所依賴屬性是否注入。
ApplicationContext
啟動後預載入所有的單執行個體Bean,確定當你需要的時候,你就不用在等待,因為他們已經建立好了。
相對于基本的
BeanFactory
,
ApplicationContext
唯一的不足是占用記憶體空間。當應用程式配置Bean較多時,程式啟動較慢。
BeanFactory
通常以程式設計的方式被建立,
ApplicationContext
還能以聲明的方式建立,如使用
ContextLoader
BeanFactory
和
ApplicationContext
都支援
BeanPostProcessor
、
BeanFactoryPostProcessor
的使用,但兩者之間的差別是:
BeanFactory
需要手動注冊,而
ApplicationContext
則是自動注冊
36、簡述spring bean的生命周期
- 1、解析類得到的
BeanDefinition
- 2、如果有多個構造方法後,則要推斷構造方法
- 3、确定好構造方法後,進行執行個體化得到一個對象
- 4、對對象中的家裡
注解的屬性進行屬性填充@Autowired
- 5、回調Aware方法,比如
,BeanNameAware
BeanFactoryAware
- 6、調用
的初始化前的方法BeanPostProcessor
- 7、調用初始化方法
- 8、調用
的初始化後的方法,在這裡進行AOPBeanPostProcessor
- 9、如果目前建立的bean是單例的則會把bean放入單例池
- 10、使用bean
- 11、Spring容器關閉時調用
中destory()方法DisposableBean
37、spring支援的幾種bean作用域
- singleton:預設,每個容器中隻有一個bean的執行個體,單例的模式由BeanFactory自身來維護。該對象的生命周期是與Spring IOC容器一緻的(但是第一次被注入時才會建立)
- prototype:為每一個bean請求提供一個執行個體。在每次注入時都會建立一個新的對象
- request:bean被定義為在每個HTTP請求中建立一個單例對象,也就是說在單個請求中都會複用這一個單例對象
- session:與request範圍類似,確定每個session中有一個bean的執行個體,在sesssion過期後,bean會随之失效
- application:bean被定義為在servletContext的生命周期中複用一個單例對象。
- websocket:bean被定義為在websocket的生命周期中複用一個單例對象。
global-session:全局作用域,global-session和Portlet應用相關。當你的應用部署在Portlet容器中工作時,它包含很多portlet。如果你想要聲明讓所有的portlet共用全局的存儲變量的話,那麼這全局變量需要存在
global-session
中。全局作用域與servlet中的session作用域效果相同。
38、Spring架構中的單例Bean是線程安全的嗎
Spring中的Bean預設是單例模式的,架構并沒有對bean進行多線程的封裝處理。
如果Bean是有狀态的 那就需要開發人員自己來進行線程安全的保證,最簡單的方法就是改變bean的作用域 把”singleton"改為“protopyte"這樣每次請求Bean就相當于是 new Bean()這樣就可以保證線程安全了。
- 有效狀态就是有資料存儲功能
- 無效狀态就是不會儲存資料 controller、service和dao層本身并不是線程安全的,隻是如果隻是調用裡面的方法,而且多線程調用一個執行個體的方法,會在記憶體中複制變量,這是自己的線程的工作記憶體,是安全的。
Dao會操作資料庫Connection、Connection是帶有狀态的,比如說資料庫事務、spring的事務管理器使用
Threadlocal為不同線程維護了一套獨立的connection副本,保證線程之間不會互相影響(spring是如何保證事務擷取同一個Connection的)
不要在bean中聲明任何有狀态的執行個體變量或類變量,如果必須如此,那麼就使用Threadlocal把變量變為私有線程有的,如果bean的執行個體變量或類變量需要在多個線程之間共享,那麼就隻能使用synchronized、lock、CAS等這些實作線程同步的方法了。
39、spring架構中使用了哪些設計模式及應用場景
簡單工廠:由一個工廠類根據傳入的參數,動态決定應該建立哪一個産品類
- Spring中的BeaFactory就是簡單工廠模式的展現,根據傳入一個唯一的辨別符來獲得Bean對象,但是否是在傳入參數後建立還是傳入參數前建立這個要根據具體情況來定
工廠方法:
- 實作了FactoryBean接口的bean是一類叫做factory的bean,其特點是,spring會再使用getBean()調用獲得該bean時,會自動調用該bean的getObject()方法,是以傳回的不是factory這個bean,而是這個bean.getObject()方法的傳回值。
單例模式:保證一個類僅有一個執行個體,并提供了一個通路它的全局通路點
- spring對單例的實作:spring中的單例模式完成了後半句話,即提供了全局的通路點BeanFactory,但沒有從構造器級别去控制單例,這是因為spring管理的時任意的java對象
擴充卡模式
- spring定義了一個适配接口,使得每一個Controller有一種對應的擴充卡實作類,讓擴充卡代替controller執行相應的方法,這樣在擴充controller時,隻需要增加一個擴充卡類就完成了spirngmvc的擴充了
裝飾模式:動态地給一個對象添加一些額外的職責。就是增加功能來說,Decorator模式相比生成子類更為靈活。
- spring中用到的包裝器模式在類名上有兩種表現,一種是類名中含有
,另一種是類名中含有wrapper
。Decorator
動态代理:
- 切面在應用運作時的時刻被織入,在織入切面時,AOP容器會為目标對象建立動态的建立一個代理對象。SpringAOP就是以這種方式織入切面的。
- 織入:把切面應用到目标對象并建立新的代理對象的過程
觀察者模式:
- spring的事件驅動模型使用的是:觀察者模式,Spring中obserber模式常用的地方是listener的實作
政策模式:
- spring架構的資源通路Resource接口,該接口提供了更強的資源通路能力,Spring架構本身大量使用了Resource接口來通路底層資源
40、spring事務的實作方式原理以及隔離級别
在使用Spring架構時,可以有兩種使用事務的方式,一種是=程式設計式的,一種是申明式的,@Transactiona注解就是申明式的。
首先,事務這個概念是資料庫層面的,Spring隻是基于資料庫中的事務進行了擴充,以及提供一些能讓程式員更加友善操作事務的方式。
比如我們可以提通過在某個方法上增加了
@Transactionanl
注解,就可以開啟事務,這個方法中所有的的sql都會在一個事務中執行,統一超過或失敗。
在一個方法上加了
@Transactional
注解後,Spring會基于這個類生成一個代理對象,會将這個代理對象作為bean,當在使用這個代理對象的方法時,如果這個方法存在
@Transactional
注解,那麼代理邏輯就會先把事務的自動送出設定為false,然後再去執行原本的業務邏輯方法,如果執行業務邏輯方法沒有出現異常,那麼代理邏輯中就會将事務進行送出,如果執行業務邏輯方法出現了異常,那麼會将事務進行復原。
當然,針對哪些異常復原事務是可以配置的,可以利用
@Transactional
注解中的rollbackFor屬性進行配置,預設情況下會對
RuntimeException
進行復原。
spring事務隔離級别就是資料庫的隔離級别:外加一個預設級别
- read uncommitted(未送出讀)
- read committed (送出讀、不可重複讀)
- repeatable read (可重複讀)
- serializable (可串行化)