spring基於注解和配置源碼解讀


我們先來建立一個maven項目,引入spring文件,不愛弄的在文章最下面有代碼地址可以去下載。先看,后面自己下載代碼自己去嘗試。先給你們吧,邊嘗試邊看吧。

一、IOC容器注冊組件的方式

1. 基礎XML注入Bean

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

是不是超級簡單的,我們由淺入深一點點來。

2. 基於注解的方式來配置

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

我們通過方法名就可以直接得到我們的對象了,默認就是按照方法來裝配。也可以通過@Bean(value="newName") 來指定裝配的名字。

3. 按照包掃描的方式裝配(重點),使用@ComponentScan(basePackages={"包的全路徑"})

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

這里在來說幾個參數,excludeFilters排除某一些對象,語法如下

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

FilterType有五種,分別是ANNOTATION(注解類),ASSIGNABLE_TYPE(類名),ASPECTJ(不常用,文檔說AspectJ類型模式表達式匹配),REGEX(正則表達式匹配),CUSTOM(自定義),常用的三種我標記了紅色。下面看一下具體寫法

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

剛才我們說到了自定義過濾,我們來看一下怎么寫自定義的過濾,實現我們TypeFilter接口,重寫我們的match即可,只關注返回的true。下面是一個事例

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

與包含相反的還有一個,只允許引入什么,也就是我們的includeFilters,需要注意需要把useDefaultFilters屬性設置為false(true表示掃描全部的)。語法和excludeFilters完全一致

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

4.回過頭來,我們看一下Bean的作用域。

@Lazy懶加載,使用才實例化,看下代碼,我們在Bean里加入構造方法,更方便得出什么時候實例化的。

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

指定@Scpoe可以有四種作用域

a) singleton 單實例的(默認),單例的生命周期有spring容器來控制,非懶加載時在spring實例化以后就產生了對象,容器銷毀則對象銷毀

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

輸出結果為true,說明我們的對象是單例的,單例的對象,生命周期由spring來管理的。

b) prototype 多實例的

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

多例的不受ioc容器來管理,銷毀時是由GC來清理的,還有request同一次請求和session同一個會話級別的,這里就不一一演示了。

5.@Configuration注解,來判斷是否注入Bean的。

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

上面的代碼什么意思呢?就是我們是否需要注入carBean,如果包含user這個對象,就注入我們的carBean,不包含就不注入,這里有個意思的事,Configuration配置里類的注入是有順序的,我們必須把我們作為判斷條件的Bean放在上面,否則Conditional會識別你沒有那個判斷條件的Bean。

6.@Import引入方式注入Bean

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

直接在注解內寫入我們的要注入的類即可,也可以使用接口的方式來實現,我們來看換一下。

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

實現ImportSelector類,然后返回類名全路徑即可。自動裝配就是基於@Import實現的。

實現ImportBeanDefinitionRegistrar,重寫registerBeanDefinitions方法,也是可以的。

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

7.通過FactoryBean注入

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

說到這所有往IOC容器中添加組件的方式就全部說完了,簡單總結一下:

  • @Bean注入,可以指定四種作用域,單例,多例(生命周期不受IOC容器管理),一次請求和一次會話,也可以設置懶加載,
  • @ComponentScan指定包掃描的方式來注入,配合@Controller,@Repository,@Service,@Component注解來使用。
  • @Import方式注入,兩種實現類ImportSelector和ImportBeanDefinitionRegistrar兩種方式。
  • @FactoryBean,工程Bean的方式也可以注入。注意不帶&是取得最終對象,帶&是取得真實Bean。三個方法,一個指定對象,一個指定類型,一個指定是否為單例。

二、Bean的生命周期---初始化方法和銷毀方法

針對單實例bean的話,容器啟動的時候,bean的對象就創建了,而且容器銷毀的時候,也會調用Bean的銷毀方法。

針對多實例bean的話,容器啟動的時候,bean是不會被創建的而是在獲取bean的時候被創建,而且bean的銷毀不受IOC容器的管理。

1.我們先來看個最簡單的方法,用initMethod和destroyMethod來指定我們的初始化方法和銷毀方法

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

我們在指定了我們的init初始方法,銷毀方法為destroy方法。調用順序是,Car的構造方法,Car的init方法,Car的destroy方法,也可以自己嘗試使用@Lazy注解。碼雲代碼里有可以自己去嘗試。

2.通過 InitializingBean和DisposableBean 的兩個接口實現bean的初始化以及銷毀方法

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

3.通過JSR250規范 提供的注解@PostConstruct 和@ProDestory標注的方法

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

4.通過Spring的BeanPostProcessor的 bean的后置處理器會攔截所有bean創建過程 (這個方法后面講源碼的時候會去講內部實現,自己覺得有必要看這個的源碼)

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

這里也總結一下,我們來指定容器內對象的初始化方法和銷毀方法的方式一共有四種

  • 用@Bean的initMethod 和destroyMethod 來給予初始化方法和銷毀方法。
  • 通過 InitializingBean和DisposableBean 的二個接口實現bean的初始化以及銷毀方法。
  • 通過JSR250規范 提供的注解@PostConstruct 和@ProDestory標注的方法。
  • 通過Spring的BeanPostProcessor的 bean的后置處理器會攔截所有bean創建過程。

三、給屬性賦值

這里的東西不多,我就盡快說一下啦,賦值的方式有三種我們來看一下。

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

這里值得一提的就是導入文件最好設置一下encoding = "utf-8",不然漢字會亂碼。

四、自動裝配:

主動裝配平時是我們最熟悉的,用的也是最多的,我們來復習一下。

1.@Autowired 自動裝配首先時按照類型進行裝配,若在IOC容器中發現了多個相同類型的組件,那么就按照 屬性名稱來進行裝配

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

在這里我們設置了兩個AutowiredDao的對象,一個標識為1,一個標識為2,ServiceBean默認是按照名字來裝配的。

2.我們也可以通過@Qualifier來指定裝配名字。

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

3.我們使用Qualifier是如果名字寫錯了,可能裝配錯誤會報錯,這時我們可以使用required = false來阻止異常的拋出

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

注意:這里我並沒有說@Resource注解,這個注解其實不是spring里的,是JSR250規范的,但是不支持@Primary 和@Qualifier的支持

五、環境切換:

我們有時候需要通過不同的環境來切換我們的配置,我們通過@Profile注解,來根據環境來激活標識不同的Bean,

@Profile標識在類上,那么只有當前環境匹配,整個配置類才會生效

@Profile標識在Bean上 ,那么只有當前環境的Bean才會被激活

由淺入深,講解spring實戰詳細使用——spring源碼篇

 

激活切換環境的方法

  • 方法一:通過運行時jvm參數來切換 -Dspring.profiles.active=test,dev,prod多個參數表中間使用英文的逗號來分隔
  • 方法二:通過代碼的方式來激活
由淺入深,講解spring實戰詳細使用——spring源碼篇

 

如果兩個都寫了,按照代碼中的來實現,參數不再起作用

 

本文轉自:https://www.toutiao.com/i6739477833774531084/?tt_from=mobile_qq&utm_campaign=client_share&timestamp=1569194991&app=news_article&utm_source=mobile_qq&utm_medium=toutiao_android&req_id=2019092307295101001104910817789FC5&group_id=6739477833774531084


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM