第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

首頁 慕課教程 Spring 入門教程 Spring 入門教程 Spring IoC (控制反轉(zhuǎn))

Spring IoC(控制反轉(zhuǎn))

1. 前言

通過第一章第二小節(jié),我們已經(jīng)可以使用 Spring 框架實(shí)現(xiàn)對(duì)自定義的 Java 對(duì)象管理,由 Spring 框架加載對(duì)象,實(shí)例化對(duì)象,放入容器。其實(shí)這就是 Spirng 的核心功能之 IoC,那么什么是 IoC 呢?什么又是容器呢?
跟我來,一步步揭開他們的神秘面紗。

2. 什么是 IoC?

來自百度百科的解釋 —— 控制反轉(zhuǎn)(IoC):
(Inversion of Control,縮寫為 IoC),是面向?qū)ο缶幊讨械囊环N設(shè)計(jì)原則,可以用來降低計(jì)算機(jī)代碼之間的耦合度。其中最常見的方式叫做依賴注入(Dependency Injection,簡(jiǎn)稱 DI),還有一種方式叫 “依賴查找”(Dependency Lookup)。通過控制反轉(zhuǎn),對(duì)象在被創(chuàng)建的時(shí)候,由一個(gè)調(diào)控系統(tǒng)內(nèi)所有對(duì)象的外界實(shí)體將其所依賴的對(duì)象的引用傳遞給它。也可以說,依賴被注入到對(duì)象中。

慕課解釋

如何理解好 IoC 呢?上一個(gè)小節(jié)中,我們使用簡(jiǎn)單的語言對(duì)它做了一個(gè)描述 —— IoC 是一種設(shè)計(jì)模式。將實(shí)例化對(duì)象的控制權(quán),由手動(dòng)的 new 變成了 Spring 框架通過反射機(jī)制實(shí)例化。

那我們來深入分析一下為什么使用 IoC 做控制反轉(zhuǎn),它到底能幫助我們做什么。
我們假設(shè)一個(gè)場(chǎng)景:

我們?cè)趯W(xué)習(xí) Web 階段的過程中,一定實(shí)現(xiàn)過數(shù)據(jù)的查詢功能,那么這里我就舉一個(gè)實(shí)例:
我們有這樣幾個(gè)類:

  • UserServlet
  • UserService 接口
  • UserServiceImpl 接口的實(shí)現(xiàn)類
  • UserDao

代碼如下:


/*
UserServlet  作為控制器 接收瀏覽器的請(qǐng)求
*/
public class UserServlet extends HttpServletRequest {
 //用戶的業(yè)務(wù)類 提供邏輯處理 用戶相關(guān)的方法實(shí)現(xiàn)
 private UserService userService;
 
 public void service(HttpServletRequest request,HttpServletResponse response){
    //手動(dòng)實(shí)例化UserService接口的實(shí)現(xiàn)類
    userService = new UserServiceImpl();
    List<User> list =  userService.findAll();
    //省略結(jié)果的跳轉(zhuǎn)代碼
     
 }   
}
/*
用戶的業(yè)務(wù)接口UserService
*/
public interface UserService{
 public List<User> findAll(); 
}
/*
UserServiceImpl 作為用戶的業(yè)務(wù)實(shí)現(xiàn)類 實(shí)現(xiàn)類UserService的接口
*/
public class UserServiceImpl implements UserService{
 //用戶的Dao
 private UserDao userDao;
 
 public List<User> findAll(){
     //手動(dòng)實(shí)例化Dao
     userDao = new UserDao();
     return userDao.findAll();
 }
}

問題分析:

上面的代碼有什么問題嗎? 按照我們學(xué)習(xí)過的知識(shí)… 答案是沒有。因?yàn)?Dao 只要數(shù)據(jù)源編寫代碼正確, 完全可以實(shí)現(xiàn)數(shù)據(jù)的增刪改查 ,對(duì)嗎?

但是分析分析它我們發(fā)現(xiàn):

  1. 代碼耦合性太強(qiáng) 不利于程序的測(cè)試:
    因?yàn)?userServlet 依賴于 userService ,而 userService 依賴于 userDao , 那么只要是被依賴的對(duì)象,一定要實(shí)例化才行。所以我們采取在程序中硬編碼,使用 new 關(guān)鍵字對(duì)對(duì)象做實(shí)例化。 不利于測(cè)試,因?yàn)槟悴荒艽_保所有使用的依賴對(duì)象都被成功地初始化了。有的朋友很奇怪,對(duì)象實(shí)例化有什么問題嗎? 如果構(gòu)造參數(shù)不滿足要求,或者你的構(gòu)造進(jìn)行了邏輯處理,那么就有可能實(shí)例化失?。?/p>

  2. 代碼也不利于擴(kuò)展:
    假設(shè)一下,我們花了九牛二虎外加一只雞的力氣,整理好了所有的類使用的依賴,確保不會(huì)產(chǎn)生問題,那么一旦后續(xù)我們的方法進(jìn)行擴(kuò)充,改造了構(gòu)造函數(shù),或者判斷邏輯,那么是不是所有手動(dòng) new 對(duì)象的地方都需要更改? 很明顯這就不是一個(gè)優(yōu)雅的設(shè)計(jì)。

解決方式:

Spring 的 IoC 完美的解決了這一點(diǎn), 對(duì)象的實(shí)例化由 Spring 框架加載實(shí)現(xiàn),放到 Spring 的容器中管理,避免了我們手動(dòng)的 new 對(duì)象,有需要用到對(duì)象實(shí)例依賴,直接向 Spring 容器要即可,而一旦涉及到對(duì)象的實(shí)例修改,那么 只需更改 Spring 加載實(shí)例化對(duì)象的地方,程序代碼無需改動(dòng),降低了耦合,提升了擴(kuò)展性。

3. 容器的使用

剛剛我們解釋了 IoC 的作用,是對(duì)象的實(shí)例化由主動(dòng)的創(chuàng)建變成了 Spring 的創(chuàng)建,并放入容器管理,那么這個(gè)容器是什么?
概念理解:
日常生活中有很多的容器,例如:水桶、茶杯、酒瓶,那么他們都有一個(gè)特點(diǎn),就是裝東西。而 Spring 的容器,就是裝對(duì)象的實(shí)例的。

3.1 IoC 容器的體系結(jié)構(gòu)

Spring 的容器有兩個(gè):

  1. BeanFactory
  2. ApplicationContext

他們兩個(gè)都是接口,那么有什么區(qū)別呢?見圖如下:
圖片描述

BeanFactory 才是 Spring 容器中的頂層接口。 ApplicationContext 是它的子接口。
簡(jiǎn)而言之,BeanFactory 提供了配置框架和基本功能,并在 ApplicationContext 中增加了更多針對(duì)企業(yè)的功能。
BeanFactoryApplicationContext 的區(qū)別: 創(chuàng)建對(duì)象的時(shí)間點(diǎn)不一樣。
ApplicationContext:只要一讀取配置文件,默認(rèn)情況下就會(huì)創(chuàng)建對(duì)象。
BeanFactory:什么時(shí)候使用,什么時(shí)候創(chuàng)建對(duì)象。

3.2 IoC 容器實(shí)例化的方式

上面已經(jīng)知道 Spring 的容器是通過一個(gè)接口 org.springframework.context.ApplicationContext 表示,并負(fù)責(zé)實(shí)例化,配置和組裝 Bean 對(duì)象。容器通過讀取 xml 文件中的配置信息來獲取關(guān)于實(shí)例化對(duì)象,配置屬性等命令。
ApplicationContext 只是一個(gè)接口,我們通常創(chuàng)建 ClassPathXmlApplicationContext 的實(shí)例或者 FileSystemXmlApplicationContext 的實(shí)例。前者是從類路徑中獲取上下文定義文件,后者是從文件系統(tǒng)或 URL 中獲取上下文定義文件 。例如:
圖片描述

代碼解釋:
15 行注釋掉的代碼是通過加載類路徑下的配置文件,一般來說 Java 工程放在 src 目錄下。我們使用的是 Maven 工程放在 resources 目錄下。

18 行代碼是通過加載本地 D 盤目錄下的文件來初始化容器, 實(shí)例化 bean 對(duì)象。

結(jié)論
通過上面的兩種方式測(cè)試,發(fā)現(xiàn)都可以成功初始化容器, 獲取測(cè)試的 bean 對(duì)象實(shí)例。
也證明了容器的初始化可以創(chuàng)建 ClassPathXmlApplicationContext 也可以創(chuàng)建 FileSystemXmlApplicationContext 的實(shí)例。

3.3 IoC 容器的使用實(shí)例

我們知道了加載配置文件初始化容器的方式,現(xiàn)在了解下容器的使用。其實(shí)對(duì)于我們而言,已經(jīng)不陌生了,在第一章第二小節(jié)中也已經(jīng)成功的從容器中獲取了對(duì)象實(shí)例。
這里我們就回顧一下:

  1. 容器的初始化必須先配置 xml 文件,代碼回顧如下:
<bean id="user"  class="com.wyan.entity.User" ></beans>

  1. 加載配置文件
ApplicationContext context =
                new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

  1. 調(diào)用方法
context.getBean("user")

4. 小結(jié)

本小節(jié)對(duì) IoC 概念做了一個(gè)詳解,同時(shí)介紹了 IoC 解決的問題,演示了 IoC 的使用實(shí)例,對(duì)于初學(xué)者來說搞清楚概念,理解作用,實(shí)踐出結(jié)果,就是出色的完成了任務(wù)。
技術(shù)沒有捷徑可走,多學(xué)習(xí)可以增加我們的知識(shí),勤練習(xí)可以增加我們的經(jīng)驗(yàn),善于總結(jié)思路可以提升我們的能力,一起加油。