Java開發學習(九)----IOC之核心容器

2022-07-07 06:01:06

這裡所說的核心容器,大家可以把它簡單的理解為ApplicationContext,前面雖然已經用到過,但是並沒有系統的介紹過,接下來咱們從以下幾個問題入手來下容器的相關知識:

  • 如何建立容器?

  • 建立好容器後,如何從容器中獲取bean物件?

  • 容器類的層次結構是什麼?

  • BeanFactory是什麼?

一、環境準備

在解決上述問題之前,先來準備下環境:

  • 建立一個Maven專案

  • pom.xml新增Spring的依賴

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
    </dependencies>
  • resources下新增applicationContext.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">
        <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
    </beans>
  • 新增BookDao和BookDaoImpl類

    public interface BookDao {
        public void save();
    }
    public class BookDaoImpl implements BookDao {
        public void save() {
            System.out.println("book dao save ..." );
        }
    }
  • 建立執行類App

    public class App {
        public static void main(String[] args) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
            BookDao bookDao = (BookDao) ctx.getBean("bookDao");
            bookDao.save();
        }
    }

最終建立好的專案結構如下:

二、容器

2.1 容器的建立方式

案例中建立ApplicationContext的方式為:

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

這種方式翻譯為:類路徑下的XML組態檔

除了上面這種方式,Spring還提供了另外一種建立方式為:

ApplicationContext ctx = new FileSystemXmlApplicationContext("applicationContext.xml");

這種方式翻譯為:檔案系統下的XML組態檔

使用這種方式,執行,會出現如下錯誤:

從錯誤資訊中能發現,這種方式是從專案路徑下開始查詢applicationContext.xml組態檔的,所以需要將其修改為檔案具體的路徑所在

說明:大家練習的時候,寫自己的具體路徑。這種方式雖能實現,但是當專案的位置發生變化後,程式碼也需要跟著改,耦合度較高,不推薦使用。

2.2 Bean的三種獲取方式

方式一,就是上面程式碼中獲取的方式:

BookDao bookDao = (BookDao) ctx.getBean("bookDao");

這種方式存在的問題是每次獲取的時候都需要進行型別轉換,有沒有更簡單的方式呢?

方式二:

BookDao bookDao = ctx.getBean("bookDao",BookDao.class);

這種方式可以解決型別強轉問題,但是引數又多加了一個,相對來說沒有簡化多少。

方式三:

BookDao bookDao = ctx.getBean(BookDao.class);

這種方式就類似我們之前所學習依賴注入中的按型別注入。必須要確保IOC容器中該型別對應的bean物件只能有一個。

2.3 容器類層次結構

(1)在IDEA中雙擊shift,輸入BeanFactory,如果沒找到的話請勾選Include non-project items選項

(2)點選進入BeanFactory類,ctrl+h,就能檢視到如下結構的層次關係

從圖中可以看出,容器類也是從無到有根據需要一層層疊加上來的。

2.4 BeanFactory的使用

使用BeanFactory來建立IOC容器的具體實現方式為:

public class AppForBeanFactory {
    public static void main(String[] args) {
        Resource resources = new ClassPathResource("applicationContext.xml");
        BeanFactory bf = new XmlBeanFactory(resources);
        BookDao bookDao = bf.getBean(BookDao.class);
        bookDao.save();
    }
}

為了更好的看出BeanFactoryApplicationContext之間的區別,在BookDaoImpl新增如下建構函式:

public class BookDaoImpl implements BookDao {
    public BookDaoImpl() {
        System.out.println("constructor");
    }
    public void save() {
        System.out.println("book dao save ..." );
    }
}

如果不去獲取bean物件,列印會發現:

  • BeanFactory是延遲載入,只有在獲取bean物件的時候才會去建立

  • ApplicationContext是立即載入,容器載入的時候就會建立bean物件

  • ApplicationContext要想成為延遲載入,只需要按照如下方式進行設定

    <?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="bookDao" class="com.itheima.dao.impl.BookDaoImpl"  lazy-init="true"/>
    </beans>

三、核心容器總結

3.1 容器相關

  • BeanFactory是IoC容器的頂層介面,初始化BeanFactory物件時,載入的bean延遲載入

  • ApplicationContext介面是Spring容器的核心介面,初始化時bean立即載入

  • ApplicationContext介面提供基礎的bean操作相關方法,通過其他介面擴充套件其功能

  • ApplicationContext介面常用初始化類

    • ClassPathXmlApplicationContext(常用)

    • FileSystemXmlApplicationContext

3.2 bean相關

其實整個設定中最常用的就兩個屬性idclass

3.3 依賴注入相關