只有光頭才能變強html
回顧前面:java
在刷Spring書籍的時候花了點時間去學習了單例模式和工廠模式,總的來講仍是很是值得的!web
原本想的是刷完《Spring 實戰 (第4版)》和《精通Spring4.x 企業應用開發實戰》的IOC章節後來從新編寫一篇IOC的文章的,看了一下以前已經寫過的入門系列Spring入門這一篇就夠了和Spring【依賴注入】就是這麼簡單。最主要的知識點都已經講過了,因此感受就不必從新來編寫這些知識點了...面試
我我的又不喜歡將寫過的東西複製到新的文章中,因此建議你們能夠先去閱讀上面兩篇文章再來看這篇(工廠模式那篇若是沒有看過的同窗也有必要去看看)~~spring
這篇文章主要是補充和強化一些比較重要的知識點,並會把上面的兩本書關於IOC的知識點整理出來並畫成一個思惟導圖來全面瞭解Spring IOC的知識點!數據庫
那麼接下來就開始吧,若是有錯的地方但願能多多包涵,並不吝在評論區指正!編程
結合《Spring 實戰 (第4版)》和《精通Spring4.x 企業應用開發實戰》兩本書的IOC章節將其知識點整理起來~設計模式
在《精通Spring4.x 企業應用開發實戰》中對IOC的定義是這樣的:緩存
IoC(Inversion of Control)控制反轉,包含了兩個方面:1、控制。2、反轉安全
咱們能夠簡單認爲:
IOC不夠開門見山,因而Martin Fowler提出了DI(dependency injection)來替代IoC,即讓調用類對某一接口實現類的依賴關係由第三方(容器或協做類)注入,以移除調用類對某一接口實現類的依賴。
在《Spring 實戰 (第4版)》中並無說起到IOC,而是直接來講DI的:
經過DI,對象的依賴關係將由系統中負責協調各對象的第三方組件在建立對象的時候進行設定,對象無需自行建立或管理它們的依賴關係,依賴關係將被自動注入到須要它們的對象當中去
從書上咱們也能夠發現:IoC和DI的定義(區別)並非如此容易就能夠說得清楚的了。這裏我就簡單摘抄一下:
對咱們而言,其實也不必分得那麼清,混合一談也不影響咱們的理解...
再經過昨天寫過的工廠模式理解了沒有?,咱們如今就能夠很清楚的發現,其實所謂的IOC容器就是一個大工廠【第三方容器】(Spring實現的功能很強大!比咱們本身手寫的工廠要好不少)。
使用IOC的好處(知乎@Intopass的回答):
參考資料:
從上面就已經說了:IOC容器其實就是一個大工廠,它用來管理咱們全部的對象以及依賴關係。
上面描述的技術只要學過點Java的都能說出來,這一會兒可能就會被面試官問倒了,咱們簡單來看看實際Spring IOC容器是怎麼實現對象的建立和依賴的:
Spring容器(Bean工廠)可簡單分紅兩種:
幾乎全部的應用場合都是使用ApplicationContext!
BeanFactory的繼承體系:
ApplicationContext的繼承體系:
其中在ApplicationContext子類中又有一個比較重要的:WebApplicationContext
Web應用與Spring融合:
咱們看看BeanFactory的生命週期:
接下來咱們再看看ApplicationContext的生命週期:
初始化的過程都是比較長,咱們能夠分類來對其進行解析:
ApplicationContext和BeanFactory不一樣之處在於:
addBeanPostProcessor()
方法進行註冊有了上面的知識點了,咱們再來詳細地看看Bean的初始化過程:
簡要總結:
<bean>
解析成一個BeanDefinition對象,並保存到BeanDefinitionRegistry中;Spring4.x開始IOC容器裝配Bean有4種方式:
總的來講:咱們以XML配置+註解來裝配Bean得多,其中註解這種方式佔大部分!
依賴注入的方式有3種方式:
setter()
方法注入總的來講使用屬性注入是比較靈活和方便的,這是大多數人的選擇!
<bean>
對象之間有三種關係:
Bean的做用域:
使用到了Web應用環境相關的Bean做用域的話,是須要咱們手動配置代理的~
緣由也很簡單:由於咱們默認的Bean是單例的,爲了適配Web應用環境相關的Bean做用域--->每一個request都須要一個對象,此時咱們返回一個代理對象出去就能夠完成咱們的需求了!
將Bean配置單例的時候還有一個問題:
此時咱們須要用到了lookup
方法注入,使用也很簡單,看看例子就明白了:
昨天在刷書的時候恰好看到了有人在知乎邀請我回答這個問題:
結合兩本書的知識點,能夠概括成兩種解決方案:
@Primary
註解設置爲首選的注入Bean@Qualifier
註解設置特定名稱的Bean來限定注入!
以前在寫配置文件的時候都是直接將咱們的數據庫配置信息在裏面寫死的了:
其實咱們有更優雅的作法:將這些配置信息寫到配置文件上(由於這些配置信息極可能是會變的,並且有可能被多個配置文件引用).
引用配置文件的數據使用的是${}
除了引用配置文件上的數據,咱們還能夠引用Bean的屬性:
引用Bean的屬性使用的是#{}
在這種技術在《Spring 實戰 第四版》稱之爲Spring EL,跟咱們以前學過的EL表達式是相似的。主要的功能就是上面的那種,想要更深刻了解可參考下面的連接:
xml文件之間組合:
xml和javaconfig互相組合的方式:
public static void main(String[] args) { //1.經過構造函數加載配置類 ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConf.class); //2.經過編碼方式註冊配置類 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(DaoConfig.class); ctx.register(ServiceConfig.class); ctx.refresh(); //3.經過XML組裝@Configuration配置類所提供的配置信息 ApplicationContext ctx = new ClassPathXmlApplicationContext("com/smart/conf/beans2.xml"); //4.經過@Configuration組裝XML配置所提供的配置信息 ApplicationContext ctx = new AnnotationConfigApplicationContext(LogonAppConfig.class); //5.@Configuration的配置類相互引用 ApplicationContext ctx = new AnnotationConfigApplicationContext(DaoConfig.class,ServiceConfig.class); LogonService logonService = ctx.getBean(LogonService.class); System.out.println((logonService.getLogDao() !=null)); logonService.printHelllo(); }
第一種的例子:
第二種的例子:
第三種的例子:
第四種的例子:
第五種的例子:
總的來講,Spring IOC容器就是在建立Bean的時候有不少的方式給了咱們實現,其中也包括了不少關於Bean的配置~
對於Bean相關的注入教程代碼和簡化配置(p和c名稱空間)我就不一一說明啦,大家去看Spring入門這一篇就夠了和Spring【依賴注入】就是這麼簡單就好了。
總的對比圖:
分別的應用場景:
至於一些小的知識點:
上面這些小知識點比較少狀況會用到,這也不去講解啦。知道有這麼一回事,到時候查查就會用啦~~~
將SpringIOC相關知識點整理了一遍,要想知道哪些知識點是比較重要的。很簡單,咱們去找找相關的面試題就知道了,若是該面試題是常見的,那麼說明這個知識點仍是相對比較重要的啦!
如下的面試題從各類博客上摘抄下來,摘抄量較大的會註明出處的~
什麼是spring?
Spring 是個java企業級應用的開源開發框架。Spring主要用來開發Java應用,可是有些擴展是針對構建J2EE平臺的web應用。Spring框架目標是簡化Java企業級應用開發,並經過POJO爲基礎的編程模型促進良好的編程習慣。
使用Spring框架的好處是什麼?
Spring由哪些模塊組成?
簡單能夠分紅6大模塊:
BeanFactory 實現舉例
Bean工廠是工廠模式的一個實現,提供了控制反轉功能,用來把應用的配置和依賴從正真的應用代碼中分離。
在spring3.2以前最經常使用的是XmlBeanFactory的,但如今被廢棄了,取而代之的是:XmlBeanDefinitionReader和DefaultListableBeanFactory
什麼是Spring的依賴注入?
依賴注入,是IOC的一個方面,是個一般的概念,它有多種解釋。這概念是說你不用建立對象,而只須要描述它如何被建立。你不在代碼裏直接組裝你的組件和服務,可是要在配置文件裏描述哪些組件須要哪些服務,以後一個容器(IOC容器)負責把他們組裝起來。
有哪些不一樣類型的IOC(依賴注入)方式?
哪一種依賴注入方式你建議使用,構造器注入,仍是 Setter方法注入?
你兩種依賴方式均可以使用,構造器注入和Setter方法注入。最好的解決方案是用構造器參數實現強制依賴,setter方法實現可選依賴。
什麼是Spring beans?
Spring beans 是那些造成Spring應用的主幹的java對象。它們被Spring IOC容器初始化,裝配,和管理。這些beans經過容器中配置的元數據建立。好比,以XML文件中<bean/>
的形式定義。
這裏有四種重要的方法給Spring容器提供配置元數據。
解釋Spring框架中bean的生命週期
解釋不一樣方式的自動裝配
只用註解的方式時,註解默認是使用byType的!
IOC的優勢是什麼?
IOC 或 依賴注入把應用的代碼量降到最低。它使應用容易測試,單元測試再也不須要單例和JNDI查找機制。最小的代價和最小的侵入性使鬆散耦合得以實現。IOC容器支持加載服務時的餓漢式初始化和懶加載。
哪些是重要的bean生命週期方法? 你能重載它們嗎?
有兩個重要的bean 生命週期方法,第一個是setup
, 它是在容器加載bean的時候被調用。第二個方法是 teardown
它是在容器卸載類的時候被調用。
The bean 標籤有兩個重要的屬性(init-method
和destroy-method
)。用它們你能夠本身定製初始化和註銷方法。它們也有相應的註解(@PostConstruct
和@PreDestroy
)。
怎麼回答面試官:你對Spring的理解?
來源:
下面我就截幾個答案:
1、
2、
Spring框架中的單例Beans是線程安全的麼?
Spring框架並無對單例bean進行任何多線程的封裝處理。關於單例bean的線程安全和併發問題須要開發者自行去搞定。但實際上,大部分的Spring bean並無可變的狀態(好比Serview類和DAO類),因此在某種程度上說Spring的單例bean是線程安全的。若是你的bean有多種狀態的話(好比 View Model 對象),就須要自行保證線程安全。
最淺顯的解決辦法就是將多態bean的做用域由「singleton」變動爲「prototype」
FileSystemResource和ClassPathResource有何區別?
在FileSystemResource 中須要給出spring-config.xml文件在你項目中的相對路徑或者絕對路徑。在ClassPathResource中spring會在ClassPath中自動搜尋配置文件,因此要把ClassPathResource文件放在ClassPath下。
若是將spring-config.xml保存在了src文件夾下的話,只需給出配置文件的名稱便可,由於src文件夾是默認。
簡而言之,ClassPathResource在環境變量中讀取配置文件,FileSystemResource在配置文件中讀取配置文件。
這篇文章的主要知識點我畫了一張思惟導圖來總結啦,當學習到AOP的時候,這張思惟導圖會繼續補充的哦~~~
參考資料:
若是文章有錯的地方歡迎指正,你們互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同窗,能夠關注微信公衆號:Java3y。
文章的目錄導航: