Spring5基礎(2)——Spring IoC控制反轉(zhuǎn)(基礎)

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

csdn內(nèi)容同步桃序,id同名皂岔,csdn博客鏈接

Inversion of Control(IoC)控制反轉(zhuǎn):是一種通過描述(xml配置文件或注解)世蔗,并通過第三方去產(chǎn)生或獲取特定對象的方式铣猩。

實現(xiàn)控制反轉(zhuǎn)的是:IoC容器。
操作方法是:依賴注入弹灭。
控制反轉(zhuǎn)的結(jié)果是對象實例不再有調(diào)用者創(chuàng)建督暂,而是由Spring容器來創(chuàng)建,即控制權由調(diào)用者轉(zhuǎn)移到Spring容器穷吮。

Spring的依賴注入:Spring容器負責將被依賴的對象(需要的對象實例),賦值給調(diào)用者的成員變量饥努,相當于為調(diào)用者注入了它所依賴的實例捡鱼。

為什么要使用Spring IoC,作用是什么酷愧?

使用Spring IoC的作用是:消減程序間的耦合問題驾诈。

舉個栗子:比如在B類中需要一個A類的實例對象,在B類中若使用New關鍵字來創(chuàng)建A類實例溶浴,按如下所示:

package com.lipiao.demo;

public class A {
    String name;
    public void setName(String name) {
        this.name = name;
    }
}
package com.lipiao.demo;

public class B {

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        //修改前
        A a=new A();
        a.setName("A1");
        System.out.println(a.name);
    }
}

運行效果就是控制臺輸出A1:


解耦前

實際開發(fā)中肯定不止2個類乍迄,隨著邏輯處理越來越多,這樣的處理方式會使不同的類之間耦合越來越嚴重士败,代碼的維護會比較困難闯两。

耦合:程序間的依賴關系
包括:①類之間的依賴 ②方法之間的依賴
弊端 獨立性很差

解耦:盡可能降低程序間的依賴關系(經(jīng)可能是因為有的耦合沒法避免)
實際開發(fā)中應該做到:編譯期間不依賴,運行時才依賴

解耦思路:
第一步:使用反射來創(chuàng)建對象谅将,而避免使用new關鍵字
第二步:通過讀取配置文件來獲取要創(chuàng)建的對象權限定類名

使用java的反射特性來修改上面的B類中的代碼漾狼,假設A類所在包路徑為:com.lipiao.demo.A

package com.lipiao.demo;
public class B {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        //修改前
        A a=new A();
        a.setName("A1");
        System.out.println(a.name);
        
        //使用反射
        Class<?> classA = Class.forName("com.lipiao.demo.A");
        A a2=(A)classA.newInstance();
        a2.setName("A2");
        System.out.println(a2.name);
    }
}

運行效果如下:


使用java反射初步解耦

這樣New關鍵字就沒有啦,初步解耦就完成啦。

更多java反射特性的使用饥臂,本文不多撰寫啦逊躁,我找了一片博客:Java的高級特性 - 反射

但是以上代碼還沒有做到編譯期間不依賴,運行時才依賴隅熙。

進一步解耦就要使用Spring IoC控制反轉(zhuǎn)啦稽煤,通過依賴注入,讓IoC容器幫我們創(chuàng)建實例對象囚戚。

Spring IoC容器的基本使用

實現(xiàn)控制反轉(zhuǎn)的是:IoC容器酵熙。

Spring IoC容器的設計基于兩個接口:
①BeanFactory接口,使用絕對路徑

//3.使用Spring  IoC容器 BeanFactory接口 使用絕對路徑
        BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource
                ("C:\\Users\\11092\\IdeaProjects\\javaEE\\src\\main\\resources\\META-INF\\applicationContext.xml"));
        //通過容器創(chuàng)建A類實例,xml中id為A弯淘,getBean傳入A
        A a3 = (A) beanFactory.getBean("A");
        System.out.println(a3.name);

applicationContext.xml

<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">

    <bean id="A" class="com.lipiao.demo.A">
        <property name="name" value="A3"></property>
    </bean>
</beans>
XmlBeanFactory

②ApplicationContext接口

1.使用ClassPathXmlApplicationContext創(chuàng)建ApplicationContext接口實例绿店,使用相對路徑(resources根目錄)

//4.使用Spring  IoC容器 ApplicationContext接口
        //有3種創(chuàng)建ApplicationContext接口的方式:

        //4.1 ClassPathXmlApplicationContext 使用相對路徑(resources根目錄)
        ApplicationContext applicationContext4_1 =
                new ClassPathXmlApplicationContext("META-INF/applicationContext.xml");
        A a4_1= (A) applicationContext4_1.getBean("A4_1");
        System.out.println(a4_1.name);

applicationContext.xml

<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">

 <bean id="A4_1" class="com.lipiao.demo.A">
        <property name="name" value="A4_1"></property>
    </bean>
</beans>

會有兩條紅色的提示信息,一條是刷新ClassPathXmlApplicationContext庐橙,一條是從xml配置文件中加載對應的bean文件
運行結(jié)果:控制臺輸出A4_1


ClassPathXmlApplicationContext

2.使用FileSystemXmlApplicationContext創(chuàng)建ApplicationContext接口實例假勿,使用絕對路徑

//4.2 FileSystemXmlApplicationContext 使用絕對路徑
        ApplicationContext applicationContext4_2= new FileSystemXmlApplicationContext(
                "C:\\Users\\11092\\IdeaProjects\\javaEE\\src\\main\\resources\\META-INF\\applicationContext.xml");
        A a4_2= (A) applicationContext4_2.getBean("A4_2");
        System.out.println(a4_2.name);

applicationContext.xml

<bean id="A4_2" class="com.lipiao.demo.A">
        <property name="name" value="A4_2"></property>
    </bean>

會有兩條紅色的提示信息,一條是刷新ClassPathXmlApplicationContext态鳖,一條是從xml配置文件中加載對應的bean文件
運行結(jié)果:控制臺輸出A4_2

FileSystemXmlApplicationContext

3.使用web服務器實例化ApplicationContext容器
一般使用基于org.springframework.web.context.ContextLoaderListener的實現(xiàn)方式转培,在web.xml文件中添加:

<context-parm>
   <param-name>contextConfigLocation</param-name>
   <param-value>
      classpath:applicationContext.xml
   </param-value>
</context-parm>

<listener>
   <listener-class>
       org.springframework.web.context.ContextLoaderListener
   </listener-class>
</listener>

Spring IoC容器的依賴注入類型

①構(gòu)造方法注入
Spring框架可以采用java的反射機制,通過構(gòu)造方法完成依賴注入浆竭。
以下面這個C類為例:

package com.lipiao.demo;
//Spring  IoC容器依賴注入 1.構(gòu)造方法注入
public class C {
    String name;
    public C(String name) {
        this.name = name;
    }
}

applicationContext.xml中

<bean id="C5_1" class="com.lipiao.demo.C">
        <constructor-arg index="0" value="C_strName_constructor"/>
    </bean>

index用于定義參數(shù)的位置浸须,value表示參數(shù)為常數(shù)惨寿,若為實例引用,將value替換為ref
運行效果:
會有兩條紅色的提示信息删窒,一條是刷新ClassPathXmlApplicationContext裂垦,一條是從xml配置文件中加載對應的bean文件
控制臺打印C_strName_constructor

信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@7d907bac: startup date [Wed Jul 17 21:12:40 CST 2019]; root of context hierarchy
七月 17, 2019 9:12:40 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [META-INF/applicationContext.xml]
C_strName_constructor

②使用屬性的setter方法注入(這是最主流的注入方式)
使用setter注入方法和構(gòu)造方法注入類似,剛剛在介紹Spring IoC容器的基本使用的案例都是使用屬性setter注入的肌索。
還是看個例子吧蕉拢,同樣是上面的C類,修改C類代碼诚亚,添加setter方法晕换,刪掉構(gòu)造方法:

package com.lipiao.demo;
//Spring  IoC容器依賴注入 
// 1.構(gòu)造方法注入
// 2.setter方法注入
public class C {
    String name;
    //構(gòu)造方法注入
//    public C(String name) {
//        this.name = name;
//    }
    //setter方法注入
    public void setName(String name) {
        this.name = name;
    }
}

修改applicationContext.xml配置信息:

<bean id="C5_2" class="com.lipiao.demo.C">
        <property name="name" value="C_strName_setter"/>
    </bean>

運行效果:
會有兩條紅色的提示信息,一條是刷新ClassPathXmlApplicationContext站宗,一條是從xml配置文件中加載對應的bean文件
控制臺打印C_strName_setter

信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@148080bb: startup date [Wed Jul 17 21:29:37 CST 2019]; root of context hierarchy
七月 17, 2019 9:29:37 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [META-INF/applicationContext.xml]
C_strName_setter
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末闸准,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子梢灭,更是在濱河造成了極大的恐慌夷家,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件或辖,死亡現(xiàn)場離奇詭異瘾英,居然都是意外死亡,警方通過查閱死者的電腦和手機颂暇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門缺谴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人耳鸯,你說我怎么就攤上這事湿蛔。” “怎么了县爬?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵阳啥,是天一觀的道長。 經(jīng)常有香客問我财喳,道長察迟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任耳高,我火速辦了婚禮扎瓶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘泌枪。我一直安慰自己概荷,他們只是感情好,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布碌燕。 她就那樣靜靜地躺著误证,像睡著了一般继薛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上愈捅,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天遏考,我揣著相機與錄音,去河邊找鬼蓝谨。 笑死诈皿,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的像棘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼壶冒,長吁一口氣:“原來是場噩夢啊……” “哼缕题!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起胖腾,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤烟零,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后咸作,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锨阿,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年记罚,在試婚紗的時候發(fā)現(xiàn)自己被綠了墅诡。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡桐智,死狀恐怖末早,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情说庭,我是刑警寧澤然磷,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站刊驴,受9級特大地震影響姿搜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜捆憎,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一舅柜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧攻礼,春花似錦业踢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瞬沦。三九已至,卻和暖如春雇锡,著一層夾襖步出監(jiān)牢的瞬間逛钻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工锰提, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留曙痘,地道東北人。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓立肘,卻偏偏與公主長得像边坤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子谅年,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354

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