国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

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

發(fā)布時(shí)間:2021-07-06 11:13 來(lái)源:腳本之家 閱讀:0 作者:IPostYellow 欄目: 開(kāi)發(fā)技術(shù)

目錄

一、前言

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

區別:

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

舉例說(shuō)明:

做菜,做蒜薹炒豬肉

你有兩種做法:

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

第二種,從農貿市場(chǎng)獲取豬和蒜薹,拿回來(lái)直接炒,做成了蒜薹炒豬肉。

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

再舉一個(gè)例子

過(guò)年了,想要給家里打掃個(gè)衛生,你想請幾個(gè)鐘點(diǎn)工來(lái)打掃。也有兩種做法。

第一種:自己主動(dòng)找,找身邊人看看誰(shuí)認識鐘點(diǎn)工,你自己打電話(huà)邀約,談價(jià)格

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

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

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

那上述例子中的農貿市場(chǎng)和家政公司哪里來(lái)???

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

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

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

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

二、IOC原理實(shí)戰

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

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

我們定義我們的接口和實(shí)現類(lèi)

// UserDao接口
public interface UserDao {
    void getUser();
}
// UserDao實(shí)現類(lèi)1,mysql實(shí)現
public class UserDaoImpl implements UserDao {
    public void getUser() {
        System.out.println("mysql實(shí)現");
    }
}
// UserDao實(shí)現類(lèi)2,oracle實(shí)現
public class UserDaoImpl implements UserDao {
    public void getUser() {
        System.out.println("oracle實(shí)現");
    }
}

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

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

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

對應的測試類(lèi):

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

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

所以我們的業(yè)務(wù)實(shí)現類(lèi)要使用set方法動(dòng)態(tài)注入我們的UserDao實(shí)現類(lèi)。

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

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

如此一來(lái)只需要在測試類(lèi)中通過(guò)set方法,傳入對應的實(shí)現類(lèi)對象,就可以實(shí)現調用不同的實(shí)現對象的getUser方法。

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

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

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

三、IOC本質(zhì)

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

DI(依賴(lài)注入)是實(shí)現IOC的一種方法,在沒(méi)有IOC的程序中,我們使用面向對象編程,對象的創(chuàng )建與對象間的依賴(lài)關(guān)系完全硬編碼再程序中,對象的創(chuàng )建由程序自己控制(也就是程序員自己寫(xiě)),控制反轉(IOC)后將對象的創(chuàng )建移交給第三方了,控制反轉的這個(gè)反轉說(shuō)的就是獲得依賴(lài)對象的方式反轉了。

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

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

四、spring helloworld

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

首先創(chuàng )建我們的實(shí)體類(lèi)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 + '\'' +
                '}';
    }
}

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

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

</beans>

再次查看官方文檔,查詢(xún)如何使用容器。

可以看到需要借助一個(gè)工廠(chǎng)來(lái)讀取bean的定義并進(jìn)行訪(fǎng)問(wèn),然后創(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");        
		//我們的對象現在都在spring中管理了,我們要使用,直接去取出來(lái)就可以了        
		Hello hello = (Hello) context.getBean("hello");        
		System.out.println(hello.toString());//Hello{str='Spring'}        
		//思考?        
		//Hello對象是誰(shuí)創(chuàng  )建的?是由Spring創(chuàng  )建的        
		//Hello對象的屬性是怎么設置的?是由Spring容器設置的    
		}
	}

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

五、小結

控制:誰(shuí)來(lái)控制對象的創(chuàng )建,傳統的應用程序的對象是由程序本身控制創(chuàng )建的,使用spring后,對象是由spring來(lái)創(chuàng )建的。

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

依賴(lài)注入:就是利用set方法來(lái)進(jìn)行注入

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

我們回頭看Hello類(lèi)里左邊有個(gè)豆子的標志了,這說(shuō)明這個(gè)類(lèi)已經(jīng)被Spring托管了。

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

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

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。

国产欧美日韩久久久久| 无人区一码二码三码区别图片| 永久免费观看的毛片视频| XXX国产精品视频| 和人妻隔着帘子按摩中字| 人与禽性视频77777|