Spring基礎(chǔ)—IOC控制反轉(zhuǎn)

什么是Spring的IOC

1尿背、IOC是Inversion of Control簡(jiǎn)寫默赂,中文稱之為控制反轉(zhuǎn)
2捻激、作用時(shí)將對(duì)象的創(chuàng)建權(quán)交由Spring框架去管理钧排,在沒用框架之前敦腔,創(chuàng)建對(duì)象是我們采用new xxx()來創(chuàng)建該對(duì)象,在Spring中對(duì)象的創(chuàng)建是交給IOC容器的恨溜,不需要我們自己去創(chuàng)建
3符衔、作用是降低了代碼的耦合度

SpringIOC創(chuàng)建對(duì)象

目標(biāo):通過IOC創(chuàng)建對(duì)象,調(diào)用對(duì)象的中方法

1糟袁、整個(gè)項(xiàng)目目錄
image.png
2判族、IDEA創(chuàng)建普通的maven項(xiàng)目,也可創(chuàng)建普通項(xiàng)目java項(xiàng)目導(dǎo)入架包
創(chuàng)建Maven項(xiàng)目第一步

創(chuàng)建Maven項(xiàng)目第二步

創(chuàng)建Maven項(xiàng)目第三步
3项戴、打開項(xiàng)目找到pom.xml文件配置如下主要是 <dependencies> </dependencies>里面的包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>springNewBean</groupId>
    <artifactId>work.chenc</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <!-- junit測(cè)試包 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!-- spring-context 包含Spring必須的架包-->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
    </dependencies>

</project>

spring-context 包含Spring必須的架包

架包展示

4形帮、新建一個(gè)類,并給類一個(gè)方法
package work.chenc.entity;

public class UserEntity {

    public UserEntity() {
        System.out.println("UserEntity無參構(gòu)造----------------");
    }

    public void doSomething() {
        System.out.println("UserEntity-doSomething........");
    }

}

5周叮、新建一個(gè)xml文件辩撑,位置可以自選,我選擇的是在resources目錄下
<?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">
       <!--
            id: getBean(id) 通過id獲取實(shí)例化的對(duì)象
            class: 需要?jiǎng)?chuàng)建對(duì)象的全路徑-根據(jù)類的全路徑獲取類的class(字節(jié)碼)
       -->
       <bean id="user" class="work.chenc.entity.UserEntity"></bean>
</beans>
6则吟、Junit測(cè)試-調(diào)用UserEntity中的doSomething方法
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import work.chenc.entity.UserEntity;

public class NewBeanTest {

    @Test
    public void testIocNewBean() {
        // 1槐臀、獲取ApplicationContent對(duì)象解析xml文件并創(chuàng)建對(duì)象 - spring內(nèi)部處理
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");
        // 2、獲取創(chuàng)建的對(duì)象
        UserEntity userEntity = context.getBean("user", UserEntity.class);
        userEntity.doSomething();
    }
}

補(bǔ)充說明:通過執(zhí)行結(jié)果可知氓仲、這里創(chuàng)建對(duì)象調(diào)用了類的無參構(gòu)造方法水慨,而我們New UserEntity() 默認(rèn)也只調(diào)用無參構(gòu)造

IOC底層原理

一、IOC之前創(chuàng)建對(duì)象的方法
原始方法和工廠模式創(chuàng)建對(duì)象.png

通過圖解可以看出原始方法對(duì)象之間的耦合性非常高敬扛,采用工廠雖然能降低UserDao和UserService之間的耦合性但是userFactory和UserService之間的耦合性還是非常高晰洒,為了解決這一情況,Spring為我們提供了IOC控制反轉(zhuǎn)啥箭,他能進(jìn)一步降低類與類之間的耦合性

IOC實(shí)現(xiàn)控制反轉(zhuǎn)

實(shí)現(xiàn)IOC主要用到的技術(shù):XML解析谍珊、工廠模式、反射

IOC創(chuàng)建對(duì)象的過程

通過IOC創(chuàng)建對(duì)象的重點(diǎn)在與xml文件急侥,如果類的路徑發(fā)成改變砌滞,我們只需要修改對(duì)應(yīng)的類的class屬性即可侮邀,這樣就大大的降低了代碼之間的耦合性

IOC接口說明

1、IOC思想是基于IOC容器贝润,IOC容器的底層實(shí)現(xiàn)就是對(duì)象工廠
2绊茧、Spring提供了兩種實(shí)現(xiàn)IOC的方式

a.BeanFactory:IOC容器的基本實(shí)現(xiàn),是Spring內(nèi)部使用的接口打掘,不提供開發(fā)人員使用
b.ApplicationContext: BeanFactory接口的子類华畏,提供了更強(qiáng)大的功能,一般供開發(fā)人員使用
區(qū)別:
BeanFactory在加載配置文件時(shí)尊蚁,不會(huì)創(chuàng)建對(duì)象亡笑,再獲取對(duì)象(使用)對(duì)象的時(shí)候才會(huì)創(chuàng)建
ApplicationContext在加載配置文件時(shí)就會(huì)創(chuàng)建對(duì)象(項(xiàng)目啟動(dòng)加載配置文件就會(huì)創(chuàng)建對(duì)象)

3、ApplicationContext接口的實(shí)現(xiàn)類
FileSystemXmlApplicationContext:這里路勁必須系統(tǒng)絕對(duì)路徑
ClassPathXmlApplicationContext:這里src下的路徑

// 1横朋、根據(jù)ApplicationContent 上下文對(duì)象解析并加載配置文件bean.xm 在src目錄下
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
ApplicationContext context = new FileSystemXmlApplicationContext("系統(tǒng)下的絕對(duì)路徑");
FileSystemXmlApplicationContext

ClassPathXmlApplicationContext

補(bǔ)充:
藍(lán)色的實(shí)線===》類繼承類
綠色的實(shí)線===》 接口繼承接口
綠色的虛線===》 類實(shí)現(xiàn)接口
由上圖可以確定 ApplicationContent的確BeanFactory的子類仑乌,F(xiàn)ileSystemXmlApplicationContext及ClassPathXmlApplicationContext都是ApplicationContext的實(shí)現(xiàn)類

簡(jiǎn)單實(shí)現(xiàn)通過配置文件及反射創(chuàng)建對(duì)象并調(diào)用對(duì)象方法

這里需要一個(gè)dom4j架包,我這里直接使用的Maven創(chuàng)建的普通項(xiàng)目叶撒,測(cè)試用的junit架包绝骚,這是我的pom.xml引入的架包
ps:dom4j在解析xml需要用到

<dependencies>
        <!-- 測(cè)試包 -->
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- 引入dom4j -->
        <!-- https://mvnrepository.com/artifact/dom4j/dom4j -->
       <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>

    </dependencies>
1、創(chuàng)建一個(gè)UserDao類祠够,代碼如下
public class UserDao {
    public void find() {
        System.out.println("------------執(zhí)行了UserDao.find()方法------------");
    }
}
2、創(chuàng)建一個(gè)bean.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="user" class="entity.UserDao"></bean>
</beans>
3粪牲、核心代碼
       // 1古瓤、獲取文件 - 絕對(duì)路徑
        File file = new File("/Users/chenlibrary/Documents/project/chenlibrary/SpringIOC_demo/src/main/resources/bean.xml");
        // 相對(duì)路徑
//      File file = new File("src/main/resources/bean.xml");
        // 2、獲取文件流
        FileInputStream inputStream = new FileInputStream(file);
        // 3. 創(chuàng)建SAXReader對(duì)象
        SAXReader reader = new SAXReader();
        // 4腺阳、獲取文件Document對(duì)象
        Document doc = reader.read(inputStream);
        // 獲取文件節(jié)點(diǎn)
        Element root = doc.getRootElement();
        // 獲取文件中所有bean元素
        List<Element> list = root.elements("bean");
        // 迭代
        if (list != null && list.size() > 0) {
            for (Element bean : list) {
                // 反射操作
                Class clazz = Class.forName(bean.attributeValue("class"));
                //生成對(duì)象
                UserDao userDao = (UserDao) clazz.newInstance();
                userDao.find();
            }
        }

File file = new File("XXXX")落君,這里可以根據(jù)xml的絕對(duì)路徑或相對(duì)路徑找到xml文件
絕對(duì)路徑window下及從盤符開始到xml文件的目錄,我這里是mac下的絕對(duì)路勁
相對(duì)路徑是從當(dāng)前項(xiàng)目的位置開始找的,下圖是我的xml文件地址

xml文件地址

這里只是簡(jiǎn)單的實(shí)現(xiàn)了IOC的中的通過解析xml配置亭引,再通過反射獲取配置文件中類的字節(jié)碼文件在創(chuàng)建對(duì)象绎速,至于工廠模式這里暫無涉及,待后續(xù)繼續(xù)學(xué)習(xí)焙蚓。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末纹冤,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子购公,更是在濱河造成了極大的恐慌萌京,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宏浩,死亡現(xiàn)場(chǎng)離奇詭異知残,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)比庄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門求妹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乏盐,“玉大人,你說我怎么就攤上這事制恍「改埽” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵吧趣,是天一觀的道長(zhǎng)法竞。 經(jīng)常有香客問我,道長(zhǎng)强挫,這世上最難降的妖魔是什么岔霸? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮俯渤,結(jié)果婚禮上呆细,老公的妹妹穿的比我還像新娘。我一直安慰自己八匠,他們只是感情好絮爷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著梨树,像睡著了一般坑夯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抡四,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天柜蜈,我揣著相機(jī)與錄音,去河邊找鬼指巡。 笑死淑履,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的藻雪。 我是一名探鬼主播秘噪,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼勉耀!你這毒婦竟也來了指煎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤瑰排,失蹤者是張志新(化名)和其女友劉穎贯要,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體椭住,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡崇渗,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宅广。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡葫掉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出跟狱,到底是詐尸還是另有隱情俭厚,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布驶臊,位于F島的核電站挪挤,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏关翎。R本人自食惡果不足惜扛门,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望纵寝。 院中可真熱鬧论寨,春花似錦、人聲如沸爽茴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)室奏。三九已至火焰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胧沫,已是汗流浹背荐健。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留琳袄,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓纺酸,卻偏偏與公主長(zhǎng)得像窖逗,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子餐蔬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容