半夜思考之查漏補缺 , Spring 中 Bean 之間的依賴問題

每次看書都會發現本身的不足 . prototype

      當一個 singten 的 Bean 依賴一個 prototype 的 Bean 時 , 若是不加註意 , 會發生一些奇怪的事情 , prototype 變爲了 singten 了 , 這是爲何呢 ? 設計

      這是 Spring 容器自己的特性 , 當初始化 Spring 容器時 , 容器會預初始化容器中全部的 singleton 的 Bean , 因爲 singleton Bean 依賴於 propertype Bean , 所以 , 容器在初始化 singleton Bean 以前會先建立 propertype Bean , 而後將建立好的 propertype Bean 做爲屬性注入到 singleton Bean 中 , 一旦容器建立好 singleton Bean , 容器在它銷燬以前都不會爲它第二次注入 propertype Bean , 這樣一來 , propertype Bean 卻表現出了 singleton 的行爲了 , 與設計的初衷違背 . 代理

解決這個問題有兩種方式 : 接口

  • 放棄依賴注入 : singleton 做用域的 Bean 每次都須要 propertype 做用域的 Bean 時, 主動向容器請求新的 Bean 實例 , 便可保證每次注入的 Bean , 都是新的 propertype Bean 的實例 . ( 不推薦 )
  • 利用方法注入 : 使用 <lookup-method> 標籤指定一個抽象方法和 propertype Bean . 具體實現就是將 singleton Bean 的類聲明爲一個抽象類 , 並提供一個抽象方法 , 這個抽象方法就是用來注入 propertype Bean 的 . ( 推薦使用 )

下面舉一個栗子 : 作用域

       一個獵人 , 有打獵的功能 , 每次打獵都帶上獵狗 , 可是每次帶的獵狗都不一樣 , 也就是符合上面的一個是 singten , 一個是 prototype , 獵人依賴獵狗 . 容器

 

1依賴注入

注 : 利用方法注入的實質使用了代理 , 分爲兩種代理 , JDK 代理和 cglib 代理 , 若是目標抽象類實現過接口 , Spring 容器會採用 JDK 代理實現抽象方法 , 若是目標類沒有實現過接口 , Spring 會採用 cglib 代理 , 實現該抽象方法 . 請求

相關文章
相關標籤/搜索