spring 知識點總結

  我不建議過多的看這些框架的代碼,由於這些代碼要完成任務須要不少瑣碎的類實現,好比讀取某個包下面的全部類,解析class的頭文件,反射各類信息,再加上封裝,頗有可能在讀源碼的過程當中掉到各類細節裏出不來,因此讀這種源碼要事無鉅細,理解原理便可。基本原理其實就是經過反射解析類及其類的各類信息,包括構造器、方法及其參數,屬性。而後將其封裝成bean定義信息類、constructor信息類、method信息類、property信息類,最終放在一個map裏,也就是所謂的container,池等等,其實就是個map。html

         BeanFactory和BeanDefinition,一個是IOC的核心工廠接口,一個是IOC的bean定義接口,上章提到說咱們沒法讓BeanFactory持有一個Map<String,Object>來完成bean工廠的功能,是由於spring的初始化是能夠控制的,能夠到用的時候纔將bean實例化供開發者使用,除非咱們將bean的lazy-init屬性設置爲true,初始化bean工廠時採用延遲加載。spring

          那麼知道了上述兩個接口,我相信很多人甚至不看源碼都已經猜到spring是如何作的了。沒錯,就是讓bean工廠持有一個Map<String,BeanDefinition>,這樣就能夠在任什麼時候候咱們想用哪一個bean,取到它的bean定義,咱們就能夠創造出一個新鮮的實例。sql

      當你寫好配置文件,啓動項目後,框架會先按照你的配置文件找到那個要scan的包,而後解析包裏面的全部類,找到全部含有@bean,@service等註解的類,利用反射解析它們,包括解析構造器,方法,屬性等等,而後封裝成各類信息類放到一個map裏。每當你須要一個bean的時候,框架就會從container找是否是有這個類的定義啊?若是找到則經過構造器new出來(這就是控制反轉,不用你new,框架幫你new),再在這個類找是否是有要注入的屬性或者方法,好比標有@autowired的屬性,若是有則仍是到container找對應的解析類,new出對象,並經過以前解析出來的信息類找到setter方法,而後用該方法注入對象(這就是依賴注入)。若是其中有一個類container裏沒找到,則拋出異常,好比常見的spring沒法找到該類定義,沒法wire的異常。還有就是嵌套bean則用了一下遞歸,container會放到servletcontext裏面,每次reQuest從servletcontext找這個container便可,不用屢次解析類定義。若是bean的scope是singleton,則會重用這個bean再也不從新建立,將這個bean放到一個map裏,每次用都先從這個map裏面找。若是scope是session,則該bean會放到session裏面。僅此而已,不必花更多精力。建議仍是多看看底層的知識session

1afterPropertiesSet與init-method數據結構

(1)、init-method方法,初始化bean的時候執行,能夠針對某個具體的bean進行配置。init-method須要在applicationContext.xml配置文檔中bean的定義裏頭寫明。例如:<bean id="TestBean" class="nju.software.xkxt.util.TestBean" init-method="init"></bean>
這樣,當TestBean在初始化的時候會執行TestBean中定義的init方法。   
(2)、afterPropertiesSet方法,初始化bean的時候執行,能夠針對某個具體的bean進行配置。afterPropertiesSet 必須實現 InitializingBean接口。實現 InitializingBean接口必須實現afterPropertiesSet方法。 InitializingBean是一個接口,它僅僅包含一個方法:afterPropertiesSet()。Spring要求init-method是一個無參數的方法,若是init-method指定的方法中有參數,那麼Spring將會拋出異常init-method指定的方法能夠是public、protected以及private的,而且方法也能夠是final的。
(3)、BeanPostProcessor,針對全部Spring上下文中全部的bean,能夠在配置文檔applicationContext.xml中配置一個BeanPostProcessor,而後對全部的bean進行一個初始化方法以前和以後的代理。BeanPostProcessor接口中有兩個方法: postProcessBeforeInitialization和postProcessAfterInitialization。前者postProcessBeforeInitialization在實例化及依賴注入完成後、在任何初始化代碼(好比配置文件中的init-method)調用以前調用;後者postProcessAfterInitialization在初始化代碼調用以後調用
 postProcessBeforeInitialization方法在bean初始化以前執行, postProcessAfterInitialization方法在bean初始化以後執行。
mybatis


2 proxy-target-class 做用 該屬性值默認爲false,表示使用JDK動態代理織入加強;當值爲true時,表示使用CGLib動態代理織入加強;可是,即便設置爲false,若是目標類沒有生命接口,則spring將自動使用CGLib動態代理
當要使用實現了某個接口的類讓spring來生成bean時,無需在aop配置中添加proxy-target-class,由於它默認爲false.app

2 lazy-init詳解做用 該屬性值默認爲false,表示ApplicationContext實現的默認行爲就是在啓動時將全部singleton bean提早進行實例化(也就是依賴注入),lazy-init 設置只對scop屬性爲singleton的bean起做用。框架

3 Spring bean做用域與生命週期ide

 參考文章:Spring BeanBean的做用域及生命週期函數

實例化。Spring經過new關鍵字將一個Bean進行實例化,JavaBean都有默認的構造函數,所以不須要提供構造參數。填入屬性。Spring根據xml文件中的配置經過調用Bean中的setXXX方法填入對應的屬性。事件通知。Spring依次檢查Bean是否實現了BeanNameAware、BeanFactoryAware、ApplicationContextAware、BeanPostProcessor、InitializingBean接口,若是有的話,依次調用這些接口。使用。應用程序能夠正常使用這個Bean了。銷燬。若是Bean實現了DisposableBean接口,就調用其destroy方法。

注意:若是bean的scope設爲prototype時,當ctx.close時,destroy方法不會被調用.

緣由:對於prototype做用域的bean,有一點很是重要,那就是Spring不能對一個prototype bean的整個生命週期負責:容器在初始化、配置、裝飾或者是裝配完一個prototype實例後,將它交給客戶端,隨後就對該prototype實例漠不關心了。無論何種做用域,容器都會調用全部對象的初始化生命週期回調方法。但對prototype而言,任何配置好的析構生命週期回調方法都將不會 被調用。清除prototype做用域的對象並釋聽任何prototype bean所持有的昂貴資源,都是客戶端代碼的職責。(讓Spring容器釋放被prototype做用域bean佔用資源的一種可行方式是,經過使用bean的後置處理器,該處理器持有要被清除的bean的引用。)談及prototype做用域的bean時,在某些方面你能夠將Spring容器的角色看做是Java new 操做的替代者。任何遲於該時間點的生命週期事宜都得交由客戶端來處理。
4 BeanDefinition的載入和解析

對IoC容器來講,這個載入過程,至關於把定義的BeanDefinition在IoC容器中轉化成一個Spring內部表示的數據結構的過程。IoC容器對Bean的管理和依賴注入功能的實現,是經過對其持有的BeanDefinition進行各類相關操做來完成的。這些BeanDefinition數據在IoC容器中經過一個HashMap來保持和維護。固然這只是一種比較簡單的維護方式,若是須要提升IoC容器的性能和容量,徹底能夠本身作一些擴展。

IoC容器的初始化入口,也就是看一下refresh方法。這個方法的最初是在FileSystemXmlApplicationContext的構造函數中被調用的,它的調用標誌着容器初始化的開始,
這些初始化對象就是Bean. 

 

4 Spring容器初始化過程

spring的IoC容器初始化包括:Bean定義資源文件的定位、載入和註冊3個基本過程。當 BeanDefinition 註冊完畢之後, Spring Bean 工廠就能夠隨時根據須要進行實例化了。對於 XmlBeanFactory 來講,實例化默認是延遲進行的,也就是說在 getBean 的時候纔會;而對於 ApplicationContext 來講,實例化會在容器啓動後經過AbstractApplicationContext 中 reflash 方法自動進行,主要通過方法鏈: reflesh()   à finishBeanFactoryInitialization (factory) à DefaultListableBeanFactory.preInstantiateSingletons (), 在這裏會根據註冊的 BeanDefinition 信息依此調用 getBean(beanName) 。而真正實例化的邏輯和 BeanFactory 是「異曲同工」的,全部有關 Bean 實例化均可以從 getBean(beanName) 入手。IoC容器和上下文初始化通常不包含Bean依賴注入的實現。通常而言,依賴注入發送在應用第一次經過getBean方法向容器獲取Bean時。可是有個特例是:IoC容器預實例化配置的lazyinit屬性,若是某個Bean設置了lazyinit屬性,則該Bean的依賴注入在IoC容器初始化時就預先完成了

5 如何啓動spring容器:在Web項目中,啓動Spring容器的方式有三種,ContextLoaderListener、ContextLoadServlet、ContextLoaderPlugin。

5 ApplicationContext和beanfactory區別:BeanFacotry是spring中比較原始的Factory。如XMLBeanFactory就是一種典型的BeanFactory。原始的BeanFactory沒法支持spring的許多插件,如AOP功能、Web應用等。 ApplicationContext接口,它由BeanFactory接口派生而來,於是提供BeanFactory全部的功能

參考文章:Spring中ApplicationContext和beanfactory區別 .

 6 spring如何跟struts2: struts2-spring-plugin.jar這個插件重寫了struts的對象工廠,當建立一個action類時,它會根據struts的配置文件的class屬性的值與spring配置文件中的id屬性的值相匹配

參考文章:spring與struts2結合

 7 spring如何跟mybatis:Mybatis-Spring給咱們封裝了一個SqlSessionFactoryBean,這個對象包含了3個必備屬性,分別是數據源、掃描xml和掃描dao層用的

 

[html]  view plain  copy
 
  1. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
  2.               <property name="dataSource" ref="dataSource" />  
  3.               <property name="mapperLocations"  
  4.                      value="classpath:com/tiantian/ckeditor/mybatis/mappers/*Mapper.xml" />  
  5.               <property name="typeAliasesPackage" value="com.tiantian.ckeditor.model" />  
  6. </bean>  

 

mapperLocations:它表示咱們的Mapper文件存放的位置,當咱們的Mapper文件跟對應的Mapper接口處於同一位置的時候能夠不用指定該屬性的值。

configLocation:用於指定Mybatis的配置文件位置。若是指定了該屬性,那麼會以該配置文件的內容做爲配置信息構建對應的SqlSessionFactoryBuilder,可是後續屬性指定的內容會覆蓋該配置文件裏面指定的對應內容。

 typeAliasesPackage:它通常對應咱們的實體類所在的包,這個時候會自動取對應包中不包括包名的簡單類名做爲包括包名的別名。多個package之間能夠用逗號或者分號等來進行分隔。

我不建議過多的看這些框架的代碼,由於這些代碼要完成任務須要不少瑣碎的類實現,好比讀取某個包下面的全部類,解析class的頭文件,反射各類信息,再加上封裝,頗有可能在讀源碼的過程當中掉到各類細節裏出不來,因此讀這種源碼要事無鉅細,理解原理便可。基本原理其實就是經過反射解析類及其類的各類信息,包括構造器、方法及其參數,屬性。而後將其封裝成bean定義信息類、constructor信息類、method信息類、property信息類,最終放在一個map裏,也就是所謂的container,池等等,其實就是個map。

         BeanFactory和BeanDefinition,一個是IOC的核心工廠接口,一個是IOC的bean定義接口,上章提到說咱們沒法讓BeanFactory持有一個Map<String,Object>來完成bean工廠的功能,是由於spring的初始化是能夠控制的,能夠到用的時候纔將bean實例化供開發者使用,除非咱們將bean的lazy-init屬性設置爲true,初始化bean工廠時採用延遲加載。

          那麼知道了上述兩個接口,我相信很多人甚至不看源碼都已經猜到spring是如何作的了。沒錯,就是讓bean工廠持有一個Map<String,BeanDefinition>,這樣就能夠在任什麼時候候咱們想用哪一個bean,取到它的bean定義,咱們就能夠創造出一個新鮮的實例。

      當你寫好配置文件,啓動項目後,框架會先按照你的配置文件找到那個要scan的包,而後解析包裏面的全部類,找到全部含有@bean,@service等註解的類,利用反射解析它們,包括解析構造器,方法,屬性等等,而後封裝成各類信息類放到一個map裏。每當你須要一個bean的時候,框架就會從container找是否是有這個類的定義啊?若是找到則經過構造器new出來(這就是控制反轉,不用你new,框架幫你new),再在這個類找是否是有要注入的屬性或者方法,好比標有@autowired的屬性,若是有則仍是到container找對應的解析類,new出對象,並經過以前解析出來的信息類找到setter方法,而後用該方法注入對象(這就是依賴注入)。若是其中有一個類container裏沒找到,則拋出異常,好比常見的spring沒法找到該類定義,沒法wire的異常。還有就是嵌套bean則用了一下遞歸,container會放到servletcontext裏面,每次reQuest從servletcontext找這個container便可,不用屢次解析類定義。若是bean的scope是singleton,則會重用這個bean再也不從新建立,將這個bean放到一個map裏,每次用都先從這個map裏面找。若是scope是session,則該bean會放到session裏面。僅此而已,不必花更多精力。建議仍是多看看底層的知識

1afterPropertiesSet與init-method

(1)、init-method方法,初始化bean的時候執行,能夠針對某個具體的bean進行配置。init-method須要在applicationContext.xml配置文檔中bean的定義裏頭寫明。例如:<bean id="TestBean" class="nju.software.xkxt.util.TestBean" init-method="init"></bean>
這樣,當TestBean在初始化的時候會執行TestBean中定義的init方法。   
(2)、afterPropertiesSet方法,初始化bean的時候執行,能夠針對某個具體的bean進行配置。afterPropertiesSet 必須實現 InitializingBean接口。實現 InitializingBean接口必須實現afterPropertiesSet方法。 InitializingBean是一個接口,它僅僅包含一個方法:afterPropertiesSet()。Spring要求init-method是一個無參數的方法,若是init-method指定的方法中有參數,那麼Spring將會拋出異常init-method指定的方法能夠是public、protected以及private的,而且方法也能夠是final的。
(3)、BeanPostProcessor,針對全部Spring上下文中全部的bean,能夠在配置文檔applicationContext.xml中配置一個BeanPostProcessor,而後對全部的bean進行一個初始化方法以前和以後的代理。BeanPostProcessor接口中有兩個方法: postProcessBeforeInitialization和postProcessAfterInitialization。前者postProcessBeforeInitialization在實例化及依賴注入完成後、在任何初始化代碼(好比配置文件中的init-method)調用以前調用;後者postProcessAfterInitialization在初始化代碼調用以後調用
 postProcessBeforeInitialization方法在bean初始化以前執行, postProcessAfterInitialization方法在bean初始化以後執行。


2 proxy-target-class 做用 該屬性值默認爲false,表示使用JDK動態代理織入加強;當值爲true時,表示使用CGLib動態代理織入加強;可是,即便設置爲false,若是目標類沒有生命接口,則spring將自動使用CGLib動態代理
當要使用實現了某個接口的類讓spring來生成bean時,無需在aop配置中添加proxy-target-class,由於它默認爲false.

2 lazy-init詳解做用 該屬性值默認爲false,表示ApplicationContext實現的默認行爲就是在啓動時將全部singleton bean提早進行實例化(也就是依賴注入),lazy-init 設置只對scop屬性爲singleton的bean起做用。

3 Spring bean做用域與生命週期

 參考文章:Spring BeanBean的做用域及生命週期

實例化。Spring經過new關鍵字將一個Bean進行實例化,JavaBean都有默認的構造函數,所以不須要提供構造參數。填入屬性。Spring根據xml文件中的配置經過調用Bean中的setXXX方法填入對應的屬性。事件通知。Spring依次檢查Bean是否實現了BeanNameAware、BeanFactoryAware、ApplicationContextAware、BeanPostProcessor、InitializingBean接口,若是有的話,依次調用這些接口。使用。應用程序能夠正常使用這個Bean了。銷燬。若是Bean實現了DisposableBean接口,就調用其destroy方法。

注意:若是bean的scope設爲prototype時,當ctx.close時,destroy方法不會被調用.

緣由:對於prototype做用域的bean,有一點很是重要,那就是Spring不能對一個prototype bean的整個生命週期負責:容器在初始化、配置、裝飾或者是裝配完一個prototype實例後,將它交給客戶端,隨後就對該prototype實例漠不關心了。無論何種做用域,容器都會調用全部對象的初始化生命週期回調方法。但對prototype而言,任何配置好的析構生命週期回調方法都將不會 被調用。清除prototype做用域的對象並釋聽任何prototype bean所持有的昂貴資源,都是客戶端代碼的職責。(讓Spring容器釋放被prototype做用域bean佔用資源的一種可行方式是,經過使用bean的後置處理器,該處理器持有要被清除的bean的引用。)談及prototype做用域的bean時,在某些方面你能夠將Spring容器的角色看做是Java new 操做的替代者。任何遲於該時間點的生命週期事宜都得交由客戶端來處理。
4 BeanDefinition的載入和解析

對IoC容器來講,這個載入過程,至關於把定義的BeanDefinition在IoC容器中轉化成一個Spring內部表示的數據結構的過程。IoC容器對Bean的管理和依賴注入功能的實現,是經過對其持有的BeanDefinition進行各類相關操做來完成的。這些BeanDefinition數據在IoC容器中經過一個HashMap來保持和維護。固然這只是一種比較簡單的維護方式,若是須要提升IoC容器的性能和容量,徹底能夠本身作一些擴展。

IoC容器的初始化入口,也就是看一下refresh方法。這個方法的最初是在FileSystemXmlApplicationContext的構造函數中被調用的,它的調用標誌着容器初始化的開始,
這些初始化對象就是Bean. 

 

4 Spring容器初始化過程

spring的IoC容器初始化包括:Bean定義資源文件的定位、載入和註冊3個基本過程。當 BeanDefinition 註冊完畢之後, Spring Bean 工廠就能夠隨時根據須要進行實例化了。對於 XmlBeanFactory 來講,實例化默認是延遲進行的,也就是說在 getBean 的時候纔會;而對於 ApplicationContext 來講,實例化會在容器啓動後經過AbstractApplicationContext 中 reflash 方法自動進行,主要通過方法鏈: reflesh()   à finishBeanFactoryInitialization (factory) à DefaultListableBeanFactory.preInstantiateSingletons (), 在這裏會根據註冊的 BeanDefinition 信息依此調用 getBean(beanName) 。而真正實例化的邏輯和 BeanFactory 是「異曲同工」的,全部有關 Bean 實例化均可以從 getBean(beanName) 入手。IoC容器和上下文初始化通常不包含Bean依賴注入的實現。通常而言,依賴注入發送在應用第一次經過getBean方法向容器獲取Bean時。可是有個特例是:IoC容器預實例化配置的lazyinit屬性,若是某個Bean設置了lazyinit屬性,則該Bean的依賴注入在IoC容器初始化時就預先完成了

5 如何啓動spring容器:在Web項目中,啓動Spring容器的方式有三種,ContextLoaderListener、ContextLoadServlet、ContextLoaderPlugin。

5 ApplicationContext和beanfactory區別:BeanFacotry是spring中比較原始的Factory。如XMLBeanFactory就是一種典型的BeanFactory。原始的BeanFactory沒法支持spring的許多插件,如AOP功能、Web應用等。 ApplicationContext接口,它由BeanFactory接口派生而來,於是提供BeanFactory全部的功能

參考文章:Spring中ApplicationContext和beanfactory區別 .

 6 spring如何跟struts2: struts2-spring-plugin.jar這個插件重寫了struts的對象工廠,當建立一個action類時,它會根據struts的配置文件的class屬性的值與spring配置文件中的id屬性的值相匹配

參考文章:spring與struts2結合

 7 spring如何跟mybatis:Mybatis-Spring給咱們封裝了一個SqlSessionFactoryBean,這個對象包含了3個必備屬性,分別是數據源、掃描xml和掃描dao層用的

 

[html]  view plain  copy
 
  1. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
  2.               <property name="dataSource" ref="dataSource" />  
  3.               <property name="mapperLocations"  
  4.                      value="classpath:com/tiantian/ckeditor/mybatis/mappers/*Mapper.xml" />  
  5.               <property name="typeAliasesPackage" value="com.tiantian.ckeditor.model" />  
  6. </bean>  

 

mapperLocations:它表示咱們的Mapper文件存放的位置,當咱們的Mapper文件跟對應的Mapper接口處於同一位置的時候能夠不用指定該屬性的值。

configLocation:用於指定Mybatis的配置文件位置。若是指定了該屬性,那麼會以該配置文件的內容做爲配置信息構建對應的SqlSessionFactoryBuilder,可是後續屬性指定的內容會覆蓋該配置文件裏面指定的對應內容。

 typeAliasesPackage:它通常對應咱們的實體類所在的包,這個時候會自動取對應包中不包括包名的簡單類名做爲包括包名的別名。多個package之間能夠用逗號或者分號等來進行分隔。

相關文章
相關標籤/搜索