SpringIOC實現原理及獲取方式總結

1.什麼是Spring

Spring 被稱爲 J2EE 的春天,是一個開源的輕量級的 Java 開發框架, 具有控制反轉(IOC)和麪向切面(AOP)兩大核心。Java Spring 框架通過聲明式方式靈活地進行事務的管理,提高開發效率和質量。

2.SpringIOC

2.1IOC(DI) - 控制反轉(依賴注入)

所謂的IOC稱之爲控制反轉,簡單來說就是將對象的創建的權利及對象的生命週期的管理過程交由Spring框架來處理,從此在開發過程中不再需要關注對象的創建和生命週期的管理,而是在需要時由Spring框架提供,這個由spring框架管理對象創建和生命週期的機制稱之爲控制反轉。而在創建對象的過程中Spring可以依據配置對對象的屬性進行設置,這個過稱之爲依賴注入,也即DI。

IOC(Inversion of Control):控制反轉

DI(Dependency Injection):依賴注入

IOC是一種思想,而DI是實現IOC的主要技術途徑。

DI主要有兩種注入方式,及Setter注入和構造器注入。

2.2IOC入門案例

a.創建一個java項目

spring並不是非要在javaweb環境下才可以使用,一個普通的java程序中也可以使用Spring。

b.導入Spring的lib目錄下引入IOC相關的jar包

6個spring相關的包,一個其他包( commons-logging)

Jakarta  Commons-logging(JCL)是apache最早提供的日誌的門面接口。提供簡單的日誌實現以及日誌解耦功能。

將jar包Add as Library

idea是兩級管理:在  模塊下,可以有項目(一般開發選擇Project Library)練習中則導入Module Library(給demo單獨導包)

 c.創建Spring的配置文件

Spring採用xml文件作爲配置文件,xml文件名字任意,但通常都取名爲applicationContext.xml,通常將該文件放置在類加載的目錄裏下(src目錄),方便後續使用。

spring配置文件模板

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

</beans>

 d.創建bean類,並在spring中進行配置交由spring來管理

public class Person {
    public void eat(){
        System.out.println("eating...");
    }
}
<?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">

    <bean id="person" class="cn.ww.beans.Person"/>
</beans>

e.在程序中通過Spring容器獲取對象並使用

package cn.ww.test;

import cn.ww.beans.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 測試類
 */
public class DemoTest {
    /**
     * 傳統的通過創建對象調用方法
     */
    @Test
    public void test01(){
        //1.創建對象
        Person p = new Person();
        //2.調用方法
        p.eat();
    }

    /**
     * 通過spring獲取對象並調用方法
     */
    @Test
    public void test02(){
        //1.初始化spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.通過spring容器獲取bean,getBean中的person 爲applicationContext 配置文件中的 bean的id
        Person p = (Person) context.getBean("person");
        //3.調用方法
        p.eat();
        //4.關閉spring容器
        ((ClassPathXmlApplicationContext)context).close();
    }
}

測試通過spring獲取對象並調用對象方法成功 

 

3.IOC的實現原理

在初始化一個Spring容器時,Spring會去解析指定的xml文件,當解析到其中的<bean>標籤時,會根據該標籤中的class屬性指定的類的全路徑名,通過反射創建該類的對象,並將該對象存入內置的Map中管理。其中鍵就是該標籤的id值值就是該對象。之後,當通過getBean方法來從容器中獲取對象時,其實就是根據傳入的條件在內置的Map中尋找是否有匹配的鍵值,如果有則將該鍵值對中保存的對象返回,如果沒有匹配到則拋出異常。

由此可以推測而知:

  • 默認情況下,多次獲取同一個id的bean,得到的將是同一個對象。
  • 不可以配置多個id相同的bean
  • 可以配置多個id不同但class相同的bean

4.IOC獲取對象的方式

通過context.getBean()方法獲取bean時,可以通過如下兩種方式獲取:

  1. 傳入id值
  2. 傳入class類型

通過class方式獲取bean時,如果同一個類配置過多個bean,則在獲取時因爲無法確定到底要獲取哪個bean會拋出異常。

而id是唯一的,不存在這樣的問題,所以建議大家儘量使用id獲取bean。

/**

 * 獲取對象的方式

 *  通過id獲取bean

 *      如果找不到,拋異常NoSuchBeanDefinitionException

 *      如果找到唯一的,返回對象

 *      因爲id不重複,不可能找到多個

 *  通過class獲取bean

 *      如果找不到,拋出異常NoSuchBeanDefinitionException

 *      如果找到唯一,返回對象

 *      如果找到多個,拋出異常NoUniqueBeanDefinitionException

 */

@Test

public void  test04(){

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

 

    //獲取對象方式1:通過id獲取

    //Person p = (Person)context.getBean("person");

    //p.eat();

    //p.say();

    //獲取對象方式2:通過class獲取

    Person p = context.getBean(Person.class);

    p.eat();

    p.say();

 

    ((ClassPathXmlApplicationContext)context).close();

}

SpringIOC在通過class獲取bean時,如果找不到該類型的bean還會去檢查是否存在該類型的子孫類型的bean,如果有則返回,如果找不到或找到多個則拋出異常。這符合java面向對象思想中的多態的特性。

@Test

public void test02() {

//1.初始化spring容器

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

//2.獲取Bean

JavaTeacher jt = (JavaTeacher) context.getBean(Teacher.class);

System.out.println(jt);

}
 

5.別名標籤

 在 Spring中提供了別名標籤<alias>可以爲配置的<bean>起一個別名,要注意的是這僅僅是對指定的<bean>起的一個額外的名字,並不會額外的創建對象存入map。(當類名較長時,可以取別名,方便調用,簡化代碼)

格式:<alias name="要起別名的bean的id"  alias="要指定的別名"/>

如下圖,在applicationContext配置文件中配置person的別名爲pre

在獲取bean時可以直接通過別名來獲取

測試結果正常

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章