深度理解SpringIOC,面試你根本不需要慌!

来源:https://www.cnblogs.com/ziph/archive/2020/07/12/13289982.html
-Advertisement-
Play Games

文章已托管到GitHub,大家可以去GitHub查看閱讀,歡迎老闆們前來Star! 搜索關註微信公眾號 碼出Offer 領取各種學習資料! 深度理解Spring IOC(控制反轉) 一、IOC概述 Inverse Of Controll即為控制反轉,簡稱IOC 。 簡單來說,IOC反轉了依賴關係的滿 ...


文章已托管到GitHub,大家可以去GitHub查看閱讀,歡迎老闆們前來Star! 搜索關註微信公眾號 碼出Offer 領取各種學習資料!

深度理解Spring IOC(控制反轉)


一、IOC概述

Inverse Of Controll即為控制反轉,簡稱IOC

簡單來說,IOC反轉了依賴關係的滿足方式,由之前的自己創建依賴對象,變為由工廠推送。(變主動為被動,即反轉)它解決了具有依賴關係的組件之間的強耦合,使得項目形態更加穩健

二、什麼是IOC?

2.1 瞭解IOC思想

大概瞭解了IOC是控制反轉,至於現在我們並不清楚它的思想和作用。那麼問題來了,IOC(控制反轉)是什麼呢?

控制反轉,簡稱IOC。顧名思義,它是由“控制”和“反轉”兩個詞語組合而成。那麼我們就順藤摸瓜,分別分析一下這兩個詞語!

2.2 控制

控制一詞,我們需要想的就很多。比如說,達成控制的條件必須是兩個對象 ,控制可以分為誰控制誰控制你做什麼 。那我們一一列舉這幾種情況:

  1. 在Java中我們以new的方式創建對象,開發者控制控制著開發工具並間接的控製程序創建所需要的依賴對象,對於程式來說是直接的控制創建對象;如果使用IOC呢?那就可以是IOC容器直接的控制創建對象
  2. 既然是IOC控制創建對象,那麼控制創建對象是怎麼控制的呢?使用IOC創建對象是需要標簽引入外部對象,這說明瞭IOC容器控制著創建依賴對象的入口

2.3 反轉

反轉一詞,我們想的也很多。比如說,達成反轉的條件必須是兩個對象有反轉就有正轉 ,然後就是反轉了些什麼 。那麼我們也一一列舉說明:

  1. 在Java中我們是間接的實用程式來創建對象,這可以看作正轉。那有了IOC容器,一下子就變了,我們不用自己new對象,而是直接反轉為由IOC創建生成依賴對象並存入IOC容器中
  2. 使用IOC容器創建對象我們只需要通過配置來告訴它需要創建的對象是什麼,並標識一下以後使用什麼來獲取IOC容器中創建好的對象即可(配置使用IOC的過程),這時候等你想要IOC容器中對象就直接用這個唯一標識來獲取就好,而獲取的過程肯定是IOC通過這個唯一標識來查找並返回給我們該對象
  3. 也許有的小伙伴還是不明白反轉。為什麼要把IOC容器幫我們創建對象的行為叫反轉呢?因為由容器幫我們查找及註入依賴對象,對象只是被動的接受依賴對象。如果不反轉呢?開發者就需要創建對象,並找到、獲取、使用該對象,此過程中的所有都有開發者來控制的

三、IOC的作用

通過控制反轉,對象在被創建的時候,由一個調控系統內所有對象的外界實體將其所依賴的對象的引用傳遞給它。也可以說,依賴被註入到對象中。

比如:Class A中用到了Class B的對象b,一般情況下,需要在A的代碼中顯式的new一個B的對象。

在使用了IOC之後呢?A的代碼只需要定義一個私有的B對象,不需要直接new來獲得這個對象,而是通過相關的容器控製程序來將B對象在外部new出來並註入到A類里的引用中。而具體獲取的方法、對象被獲取時的狀態由配置文件(xml)來指定

既然由配置文件來指定創建對象關係,就大大降低了各個組件之間的強耦合併有利於維護,是項目變得更加穩健靈活

四、IOC解決Dao層和Service層的強耦合

在原始的Web開發中,Dao層和Service層是密不可分的。Dao層為數據訪問層,只與資料庫打交道。Servcie層為業務處理層,只處理實現相應的業務。而我們將Web開發中的Dao層和Service層串在一起,就需要在Service層new一個私有的Dao層實現對象(XxxDaoImpl)。有了IOC的思想,再想想傳統的Dao層與Service層的實現就顯得很不靈活,一旦修改了Dao層實現類,就必須將項目中的源碼都修改掉,顯然是一件非常可怕的事情。

五、使用IOC解決Dao層和Service層的強耦合

既然解決Dao層和Service層的強耦合那必須得這兩個組件對吧。

Dao層

// Dao層介面
package com.mylifes1110.dao;

import com.mylifes1110.bean.User;

public interface UserDao {
    int insertUser(User user);
}

// Dao層實現類
package com.mylifes1110.dao.impl;

import com.mylifes1110.bean.User;
import com.mylifes1110.dao.UserDao;

public class UserDaoImpl implements UserDao {

    @Override
    public int insertUser(User user) {
        System.out.println("------insertUser and UserDao------");
        return 0;
    }
}

註意: 我們在使用IOC時,必須將Dao層實現類對象註入到IOC容器中,這必有一個註入方式來告知IOC容器創建對象和獲取對象,在Service層我們並不需要new實現類對象,而是創建一個Service層的Setter方法來註入UserDaoImpl依賴到UserServcieImpl中(這裡可以把它們想為拼裝),此時所用的註入方式叫做Setter方法依賴註入,現在不需要糾結,後續我會將依賴註入的所有方式列舉並分析依賴註入思想和依賴註入與IOC的關係。

Service層

// Service層介面
package com.mylifes1110.service;

import com.mylifes1110.bean.User;

public interface UserService {
    int insertUser(User user);
}

// Service層實現類
package com.mylifes1110.service.impl;

import com.mylifes1110.bean.User;
import com.mylifes1110.dao.UserDao;
import com.mylifes1110.service.UserService;

public class UserServiceImpl implements UserService {
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public int insertUser(User user) {
        System.out.println("------insertUser and UserService------");
        return userDao.insertUser(null);
    }
}

spring-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/beans/spring-context.xsd"
>

    <!--id:唯一標識 class:需要被創建的目標對象全限定名-->
    <bean id
="UserDao" class="com.mylifes1110.dao.impl.UserDaoImpl"/>

    <!--id:唯一標識 class:需要被創建的目標對象全限定名-->
    <bean id
="UserService" class="com.mylifes1110.service.impl.UserServiceImpl">
        <!--Setter方法依賴註入 name:Service層定義的userDao屬性 ref:Dao層bean標簽唯一標識-->
        <property name="userDao" ref="UserDao"/>
    </bean>

</beans>

測試類

/**
@MethodName insertUser1
@Param []
@Description 測試IOC的使用
@Author Ziph
@Date 2020/7/12
*/

@Test
public void insertUser1() {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
    UserService userService = (UserService) context.getBean("UserService");
    userService.insertUser(null);
    // 列印結果
    ------insertUser and UserService------
    ------insertUser and UserDao------
}
在這裡插入圖片描述
在這裡插入圖片描述

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1 #include <stdio.h> 2 3 void createbtree(int *btree,int *data,int len) 4 { 5 int level; //樹的層數 6 int i; 7 8 btree[1] = data[1]; //創建根節點 9 for( i = 2; ...
  • python virtualenv虛擬環境配置與使用 By:賴富玉 QQ:1033553122 概述 python開發過程中,我們可能需要同時開發多款應用,這些應用可能公用同一個版本的Python程式,但是使用不同版本的第三方庫,比如A應用使用six 1.12.0,而B應用需要使用six 1.15. ...
  • 最近一直在研究AQS的源碼,希望可以更深刻的理解AQS的實現原理。雖然網上有很多關於AQS的源碼分析,但是看完以後感覺還是一知半解。於是,我將自己的整個理解過程記錄下來了,希望對大家有所幫助。 基本原理 AQS是Java中鎖的基礎,主要由兩個隊列組成。一個隊列是同步隊列,另一個是條件隊列。 同步隊列 ...
  • 為了方便以後配置新的windows電腦java、idea,所以專門記錄一下 1:JDK JDK是 Java 語言的軟體開發工具包,主要用於移動設備、嵌入式設備上的java應用程式。JDK是整個java開發的核心,它包含了JAVA的運行環境(JVM+Java系統類庫)和JAVA工具。所以首先要配置好j ...
  • 描述Python的變數聲明,可覷其語言設計思路,實現更快地代碼閱讀。 變數聲明 C# public、protect、private、internal 明確指出適用範圍 (完全公開、子類可訪問、僅自己可訪問、程式集內可訪問) Python 有點神奇,沒有不能訪問的變數,一般通過“潛規則”暗示其私有性 ...
  • pyenv 簡介 pyenv 是 Python 版本管理工具。 pyenv 可以改變全局的 Python 版本,在系統中安裝多個版本的 Python, 設置目錄級別的 Python 版本,還能創建和管理 virtual python environments。 安裝 pyenv 安裝git:~]# ...
  • 一、記憶體模型及分區 JVM 分為堆區和棧區,還有方法區,初始化的對象放在堆裡面,引用放在棧裡面,class 類信息常量池(static 常量和 static 變數)等放在方法區。 1、棧(Stack-線程私有) 1.1 棧的結構是棧幀組成的,調用一個方法就壓入一幀,幀上面存儲局部變數表,操作數棧,方 ...
  • 一個整數類型的變數自身加 1 可以這樣寫: a = a + 1; 或者 a += 1; 不過,C語言還支持另外一種更加簡潔的寫法,就是: a++; 或者 ++a; 這種寫法叫做自加或自增,意思很明確,就是每次自身加 1。 相應的,也有a--和--a,它們叫做自減,表示自身減 1。 ++和--分別稱為 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...