欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解SpringIOC容器相關(guān)知識

 更新時間:2021年05月12日 16:12:05   作者:IPostYellow  
這篇文章主要記錄自己在狂神說java中的學(xué)習(xí)情況,文章里有自己學(xué)習(xí)的理解和擴展,新手難免有理解偏差或者錯誤,懇請大佬指正下,需要的朋友可以參考下

一、前言

IOC控制反轉(zhuǎn),不是一種技術(shù),而是一種設(shè)計思想,就是將原本在程序中手動創(chuàng)建對象的控制權(quán),交給Spring框架來管理。

區(qū)別:

  • 沒有IOC的思路:若要使用某個對象,就必須自己負責(zé)去寫對象的創(chuàng)建
  • IOC的思路:若要使用某個對象,只需要從Spring容器中獲取需要使用的對象,不關(guān)心對象的創(chuàng)建過程,也就是把創(chuàng)建對象的控制權(quán)交給了Spring框架。
  • 好萊塢法則:Don't call me, I 'll call you

舉例說明:

做菜,做蒜薹炒豬肉

你有兩種做法:

第一種,自己養(yǎng)豬,然后種蒜薹。等到豬長大了,你就可以殺豬,蒜薹成熟了,就收割。然后開始炒,做成了蒜薹炒豬肉。

第二種,從農(nóng)貿(mào)市場獲取豬和蒜薹,拿回來直接炒,做成了蒜薹炒豬肉。

此時的IOC就相當(dāng)于這個農(nóng)貿(mào)市場,我要做菜,我去農(nóng)貿(mào)市場拿過來就可以了,而不需要自己去弄。為什么要Java對象放到容器里?因為我們要做到拿來即用,便于管理。那你能管理農(nóng)貿(mào)市場嗎?你不能,那誰來管農(nóng)貿(mào)市場?Spring!這就是控制反轉(zhuǎn)IOC,我們把控制權(quán)交給了Spring框架,他來幫我們管這個農(nóng)貿(mào)市場,他來養(yǎng)豬,他來種菜。我們只需在要菜的時候,去市場買就好了。

再舉一個例子

過年了,想要給家里打掃個衛(wèi)生,你想請幾個鐘點工來打掃。也有兩種做法。

第一種:自己主動找,找身邊人看看誰認識鐘點工,你自己打電話邀約,談價格

第二種:直接找家政公司,直接提出需求即可。

第一種方式就是我們自己創(chuàng)建對象的方式,自己主動new幾個鐘點工。而第二種就是spring給我們提供的IOC方式,家政公司就是一個容器,能給我提供很多的服務(wù),鐘點工對象是spring幫我們創(chuàng)建的。

又過了幾天,我又想給廚房的油煙機清理一下,也能直接打電話給家政公司,提出需求。

那上述例子中的農(nóng)貿(mào)市場和家政公司哪里來?。?/p>

我們可以自己構(gòu)建,就像自己成立一個公司一樣。具體在程序中表現(xiàn)為:

1.使用配置文件或者注解的方式定義一下我們自己容器里存放的東西。

或者去別人的公司里找。具體在程序中表現(xiàn)為:

2.一定有很多人創(chuàng)建了自己的公司,這些服務(wù)都可以集成在我們自己的容器里,為我們提供強大的功能,比如spring自帶很多的template模板類。

二、IOC原理實戰(zhàn)

首先在pom.xml文件中加入spring的相關(guān)jar包。

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.0.RELEASE</version>
    </dependency>
</dependencies>

我們定義我們的接口和實現(xiàn)類

// UserDao接口
public interface UserDao {
    void getUser();
}
// UserDao實現(xiàn)類1,mysql實現(xiàn)
public class UserDaoImpl implements UserDao {
    public void getUser() {
        System.out.println("mysql實現(xiàn)");
    }
}
// UserDao實現(xiàn)類2,oracle實現(xiàn)
public class UserDaoImpl implements UserDao {
    public void getUser() {
        System.out.println("oracle實現(xiàn)");
    }
}

然后我們的業(yè)務(wù)實現(xiàn)類,在不使用set注入的情況下,是這樣的:

//業(yè)務(wù)接口
public interface UserService {
    void getUser();
}
//業(yè)務(wù)實現(xiàn)類
public class UserServiceImpl implements UserService {
    //傳統(tǒng)的方法中,如果這邊要改變,那就必須將這里的語句改變才可以
    private UserDao userDao = new UserDaoImpl();

    public void getUser() {
        userDao.getUser();
    }
}

對應(yīng)的測試類:

public class MyTest {
    public static void main(String[] args) {
        //用戶實際調(diào)用的是業(yè)務(wù)層,不需要接觸dao層
        UserServiceImpl userService =new UserServiceImpl();
        userService.getUser();
    }
}

但是你會發(fā)現(xiàn)使用這種方法如果我在測試這里想用oracle實現(xiàn),那就必須新增一個業(yè)務(wù)實現(xiàn)類或者修改我原本的業(yè)務(wù)實現(xiàn)類,違反了開閉原則。

所以我們的業(yè)務(wù)實現(xiàn)類要使用set方法動態(tài)注入我們的UserDao實現(xiàn)類。

public class UserServiceImpl implements UserService {
    private UserDao userDao;
    // 利用set進行動態(tài)實現(xiàn)值的注入
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void getUser() {
        userDao.getUser();
    }
}

如此一來只需要在測試類中通過set方法,傳入對應(yīng)的實現(xiàn)類對象,就可以實現(xiàn)調(diào)用不同的實現(xiàn)對象的getUser方法。

public class MyTest {
    public static void main(String[] args) {
        // 利用set注入的方法,我們可以不需要修改service中的代碼,從而實現(xiàn)多個不同對象的getUser方法
        UserServiceImpl userService = new UserServiceImpl();
        userService.setUserDao(new UserDaoImpl());
        userService.getUser();//mysql實現(xiàn)
        userService.setUserDao(new UserDaoOracleImpl());
        userService.getUser();//oracle實現(xiàn)
    }
}

這兩種模式的區(qū)別可以發(fā)現(xiàn)。之前,控制UserDao實現(xiàn)類的控制權(quán),在程序員手上,程序員寫在UserServiceImpl里,寫死了對應(yīng)的是實現(xiàn)類,如果要修改的話,程序員就必須去修改對應(yīng)的代碼。而后面這種方法,控制UserDao實現(xiàn)類的控制權(quán),就已經(jīng)不在程序員手上了?,F(xiàn)在程序是被動接收對象,然后動態(tài)set注入實現(xiàn)了可以隨意使用不同的實現(xiàn)類的getUser方法。

這其實就是一種控制反轉(zhuǎn)IOC的原型。這種思想從本質(zhì)上解決了問題,程序員不用再去管理對象的創(chuàng)建了。系統(tǒng)的耦合性大大降低??梢愿訉W⒌脑跇I(yè)務(wù)的實現(xiàn)上。spring的底層全部都是基于這種思想去實現(xiàn)的。

三、IOC本質(zhì)

在這里插入圖片描述

像上圖所示,IOC本質(zhì)上就是把左邊變成了右邊。本來是業(yè)務(wù)層里程序員寫來主動決定調(diào)用的下面的Mysql還是Oracle,但是現(xiàn)在通過IOC,可以把主動權(quán)交給用戶,讓用戶想用Mysql用Mysql,想用Oracle就用Oracle。

DI(依賴注入)是實現(xiàn)IOC的一種方法,在沒有IOC的程序中,我們使用面向?qū)ο缶幊蹋瑢ο蟮膭?chuàng)建與對象間的依賴關(guān)系完全硬編碼再程序中,對象的創(chuàng)建由程序自己控制(也就是程序員自己寫),控制反轉(zhuǎn)(IOC)后將對象的創(chuàng)建移交給第三方了,控制反轉(zhuǎn)的這個反轉(zhuǎn)說的就是獲得依賴對象的方式反轉(zhuǎn)了。

采用XML配置方式配置Bean的時候,Bean的定義信息和實現(xiàn)是分離的,而采用注解的方式的時候兩者是合為一體的,Bean的定義信息直接以注解的形式定義在實現(xiàn)類中,從而達到了零配置的目睹。

控制反轉(zhuǎn)是一種通過描述(XML或者注解)并通過第三方去生產(chǎn)或獲得特定對象的方式。在Spring中實現(xiàn)控制反轉(zhuǎn)的是IOC容器,其實現(xiàn)方式是依賴注入(Dependency Injection,DI)

四、spring helloworld

找到1.2.2實例化容器部分,發(fā)現(xiàn)了其配置文件格式:

在這里插入圖片描述

首先創(chuàng)建我們的實體類Hello:

package com.hj.pojo;
public class Hello {
    private String str;

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

    @Override
    public String toString() {
        return "Hello{" +
                "str='" + str + '\'' +
                '}';
    }
}

然后根據(jù)文檔中所述,在resources文件下創(chuàng)建beans.xml文件來使用spring創(chuàng)建對象。beans.xml內(nèi)容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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">

    <!--使用spring來創(chuàng)建對象,在spring中這些都稱為bean
    bean = 對象 相當(dāng)于 new Hello();
    正常是 類型 變量名 = new 類型();
          Hello hello = new Hello();
    利用bean來實現(xiàn),id就是變量名,class就是我們對象的類型
    里面的property相當(dāng)于給對象中的屬性設(shè)置一個值。
    -->
    <bean id="hello" class="com.hj.pojo.Hello">
        <!--
        ref:引用spring容器中創(chuàng)建好的對象
        value:具體的值,基本數(shù)據(jù)類型
        -->
        <property name="str" value="Spring"/>
    </bean>

</beans>

再次查看官方文檔,查詢?nèi)绾问褂萌萜鳌?/p>

在這里插入圖片描述

可以看到需要借助一個工廠來讀取bean的定義并進行訪問,然后創(chuàng)建對象。

import com.hj.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {    
	public static void main(String[] args) {        
		//獲取spring的上下文對象        
		ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");        
		//我們的對象現(xiàn)在都在spring中管理了,我們要使用,直接去取出來就可以了        
		Hello hello = (Hello) context.getBean("hello");        
		System.out.println(hello.toString());//Hello{str='Spring'}        
		//思考?        
		//Hello對象是誰創(chuàng)建的?是由Spring創(chuàng)建的        
		//Hello對象的屬性是怎么設(shè)置的?是由Spring容器設(shè)置的    
		}
	}

這個Hello對象由spring創(chuàng)建并且由spring容器設(shè)置屬性的過程就是控制反轉(zhuǎn)。

五、小結(jié)

控制:誰來控制對象的創(chuàng)建,傳統(tǒng)的應(yīng)用程序的對象是由程序本身控制創(chuàng)建的,使用spring后,對象是由spring來創(chuàng)建的。

反轉(zhuǎn):程序本身不創(chuàng)建對象,而變成被動的接收對象

依賴注入:就是利用set方法來進行注入

IOC是一種編程思想,由主動的編程去變成被動的接收。

我們回頭看Hello類里左邊有個豆子的標(biāo)志了,這說明這個類已經(jīng)被Spring托管了。

在這里插入圖片描述

所謂的IoC,一句話來概括:對象由spring來創(chuàng)建,管理和裝配。

到此這篇關(guān)于詳解SpringIOC和容器相關(guān)知識的文章就介紹到這了,更多相關(guān)SpringIOC和容器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解java開啟異步線程的幾種方法(@Async,AsyncManager,線程池)

    詳解java開啟異步線程的幾種方法(@Async,AsyncManager,線程池)

    在springboot框架中,可以使用注解簡單實現(xiàn)線程的操作,還有AsyncManager的方式,如果需要復(fù)雜的線程操作,可以使用線程池實現(xiàn),本文通過實例代碼介紹java開啟異步線程的幾種方法(@Async,AsyncManager,線程池),感興趣的朋友一起看看吧
    2023-09-09
  • 深入學(xué)習(xí)java位運算的基礎(chǔ)知識

    深入學(xué)習(xí)java位運算的基礎(chǔ)知識

    位運算是直接對整數(shù)在內(nèi)存中的二進制位進行操作嗎,位運算即可以節(jié)約內(nèi)存,同時使程序速度更快效率更高。文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,下面我們來一起學(xué)習(xí)下吧
    2019-06-06
  • java 根據(jù)坐標(biāo)截取圖片實例代碼

    java 根據(jù)坐標(biāo)截取圖片實例代碼

    這篇文章主要介紹了java 根據(jù)坐標(biāo)截取圖片實例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • java 關(guān)鍵字static詳細介紹及如何使用

    java 關(guān)鍵字static詳細介紹及如何使用

    這篇文章主要介紹了java 關(guān)鍵字static詳細介紹及如何使用的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Java不借助第三變量實現(xiàn)兩數(shù)交換的示例

    Java不借助第三變量實現(xiàn)兩數(shù)交換的示例

    本文主要介紹了Java不借助第三變量實現(xiàn)兩數(shù)交換的示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Java判斷范圍型的數(shù)據(jù)是否存在重疊的方法

    Java判斷范圍型的數(shù)據(jù)是否存在重疊的方法

    遇到了個問題,同一天可以輸入多個時間段,但是每個時間段的時間不能出現(xiàn)重疊,這不就是判斷數(shù)據(jù)返回是否有重疊的變種嗎,所以本文給大家介紹了Java判斷范圍型的數(shù)據(jù)是否存在重疊的方法,需要的朋友可以參考下
    2024-07-07
  • Java創(chuàng)建線程的兩種方式

    Java創(chuàng)建線程的兩種方式

    這篇文章主要介紹了Java創(chuàng)建線程的兩種方式,針對Java創(chuàng)建線程的兩種方式進行比較,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Spring Boot 集成 Kafkad的實現(xiàn)示例

    Spring Boot 集成 Kafkad的實現(xiàn)示例

    這篇文章主要介紹了Spring Boot 集成 Kafkad的示例,幫助大家更好的理解和學(xué)習(xí)使用Spring Boot框架,感興趣的朋友可以了解下
    2021-04-04
  • java判斷Long類型的方法和實例代碼

    java判斷Long類型的方法和實例代碼

    在本篇文章里小編給大家整理的是關(guān)于java判斷Long類型的方法和實例代碼,對此有需要的朋友們跟著學(xué)習(xí)參考下。
    2020-02-02
  • Java日常練習(xí)題,每天進步一點點(52)

    Java日常練習(xí)題,每天進步一點點(52)

    下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧,希望可以幫到你
    2021-08-08

最新評論