在上一講中,我們對Spring的基本使用進行了一個簡單的回顧,接下來,我們就來看一下Spring核心功能結構,
Spring核心功能結構
Spring大約有20個模塊,由1300多個不同的檔案構成,而這些模塊可以分為下面幾部分:
- 核心容器
- AOP和設備支持
- 資料訪問與集成
- Web組件
- 通信報文
- 集成測驗
- ······
下面這張圖就是Spring框架的總體架構圖,

接下來,我就帶領著大家逐一看一下Spring里面的這些模塊,
核心容器
核心容器由Beans、Core、Context和Expression(Spring Expression Language,SpEL)4個模塊組成,
spring-beans和spring-core模塊
spring-beans和spring-core模塊是Spring框架的核心模塊,包含了控制反轉(Inversion of Control,IoC)和依賴注入(Dependency Injection,DI),
這倆模塊里面有一個核心介面叫BeanFactory,為什么說它是核心介面呢?因為Spring IoC里面有一個很重要的概念,那就是容器,而BeanFactory介面定義的就是容器共有的功能,很顯然,BeanFactory就是容器物件頂層介面,下面,我們不妨再來重新認識一遍BeanFactory,
BeanFactory使用控制反轉對應用程式的配置和依賴性規范與實際的應用程式代碼進行了分離,大家要知道,bean以及依賴的管理,我們都是在Spring的組態檔里面進行配置的,這樣,是不是就能大大降低程式之間的耦合啊?
BeanFactory屬于延時加載,也就是說在實體化容器物件后并不會自動實體化bean,只有當bean被使用時,BeanFactory才會對該bean進行實體化與依賴關系的裝配,這句話什么意思呢?我們不妨先回到咱們的Maven工程(即spring_demo)中,然后再通過代碼演示來理解一下這句話,現在我們創建Spring的容器物件就不再使用ApplicationContext介面了,而是來使用BeanFactory介面,如下所示,
package com.meimeixia.controller;
import com.meimeixia.service.UserService;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
/**
* @author liayun
* @create 2021-09-19 18:41
*/
public class UserController {
public static void main(String[] args) throws Exception {
// 1. 創建Spring的容器物件
// ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
// 2. 從容器物件中獲取UserService物件
UserService userService = beanFactory.getBean("userService", UserService.class);
// 3. 呼叫UserService物件的方法進行業務邏輯處理
userService.add();
}
}
以上UserController類的代碼修改完畢之后,我們并不會看到延時加載的效果,為了看到延時加載的效果,我們還得分別在UserDaoImpl和UserServiceImpl這倆類里面提供一個無參構造方法,因為bean在實體化的時候,肯定是要呼叫其構造方法的,
-
UserDaoImpl類:
package com.meimeixia.dao.impl; import com.meimeixia.dao.UserDao; /** * 資料訪問層實現類 * @author liayun * @create 2021-09-19 18:29 */ public class UserDaoImpl implements UserDao { public UserDaoImpl() { System.out.println("userDao被創建了"); } @Override public void add() { System.out.println("UserDao..."); } } -
UserServiceImpl類:
package com.meimeixia.service.impl; import com.meimeixia.dao.UserDao; import com.meimeixia.service.UserService; /** * 業務邏輯層實作類 * @author liayun * @create 2021-09-19 18:37 */ public class UserServiceImpl implements UserService { // 因為業務邏輯層是要呼叫資料訪問層中的功能的,所以在這兒我們得宣告一個UserDao型別的變數 private UserDao userDao; // 注意了,這兒我們并沒有為該變數進行賦值,賦值的操作得交給Spring去做,只是這樣做的前提是我們得為該變數提供一個setter方法 public void setUserDao(UserDao userDao) { this.userDao = userDao; } public UserServiceImpl() { System.out.println("userService被創建了"); } @Override public void add() { System.out.println("UserService..."); userDao.add(); } }
為了方便大家看到延時加載的效果,于是我在UserController類的如下代碼處打上了一個斷點,然后我會以Debug的方式來運行UserController類的代碼,

此時,程式肯定是要停留在斷點處的,然后我們按下F6鍵讓程式再往下運行一行代碼,當你切換到控制臺時,你會發現控制臺并沒有任何列印結果,如下圖所示,

現在容器物件已經實體化完了,而且我們還為UserDaoImpl和UserServiceImpl這倆類提供了一個無參構造方法,照理來說,此時應該自動實體化bean的(就是自動創建UserDaoImpl和UserServiceImpl這倆類的物件),我們應該能夠看到控制臺中會列印相應結果的,因為創建UserDaoImpl和UserServiceImpl這倆類的物件,就必須得呼叫其無參構造,但是,控制臺我們沒有看到任何列印結果,這就說明在實體化容器物件后并不會自動實體化bean,原因正是BeanFactory屬于延時加載,
那什么時候實體化bean呢?使用容器物件里面的getBean方法獲取對應的物件時就會實體化bean了,當然了,并不是我們自個去實體化,而是Spring幫我們去實體化,所以,當你按下F6鍵讓程式再往下運行一行代碼之后,你就能夠看到控制臺中會列印相應結果了,如下圖所示,

足以證明只有當bean被使用時,BeanFactory才會對該bean進行實體化與依賴關系的裝配!OK,這里就給大家演示完了BeanFactory的延時加載,
spring-context模塊
spring-context模塊構架于核心模塊(即spring-beans和spring-core這倆模塊)之上,擴展了BeanFactory,為它添加了bean生命周期控制、框架事件體系及資源加載透明化等功能,此外,該模塊還提供了許多企業級支持,如郵件訪問、遠程訪問、任務調度等,
大家注意了,ApplicationContext是該模塊的核心介面,它的超類是BeanFactory,也就是說它是BeanFactory的子介面,與BeanFactory不同,ApplicationContext實體化后會自動對所有的單實體bean進行實體化與依賴關系的裝配,使之處于待用狀態,
這又是啥子意思呢?還是回到咱們的Maven工程(即spring_demo)中,這里我依舊通過代碼來給大家進行演示,現在我們創建Spring的容器物件還是使用ApplicationContext介面了,如下所示,
package com.meimeixia.controller;
import com.meimeixia.service.UserService;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
/**
* @author liayun
* @create 2021-09-19 18:41
*/
public class UserController {
public static void main(String[] args) throws Exception {
// 1. 創建Spring的容器物件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
// 2. 從容器物件中獲取UserService物件
UserService userService = applicationContext.getBean("userService", UserService.class);
// 3. 呼叫UserService物件的方法進行業務邏輯處理
userService.add();
}
}
依舊在UserController類的如下代碼處打上了一個斷點,然后以Debug的方式來運行UserController類的代碼,

此時,程式肯定是要停留在斷點處的,然后我們按下F6鍵讓程式再往下運行一行代碼,當你切換到控制臺時,你會發現現在控制臺有列印結果了,如下圖所示,

這也就是說在實體化容器物件后就會自動實體化bean,我想大家也應該猜到原因了,就是與BeanFactory相反,ApplicationContext屬于非延時加載,所以,這里大家一定要非常清楚BeanFactory和ApplicationContext的區別,
spring-context-support模塊
spring-context-support模塊是對Spring IoC容器及IoC子容器的擴展支持,
這里面涉及到了一個IoC子容器,想必大家都用過Spring MVC吧!它和Spring就牽扯到了一個父容器和子容器的關系,當然,這一塊我們不做重點說明啊!
spring-context-indexer模塊
spring-context-indexer模塊是Spring的類管理組件和Classpath掃描組件,
想必大家都知道,如果我們在組態檔里面配置了一個組件掃描的話,那么它就會自動去掃描對應類路徑下面的那些類有沒有對應的注解,
spring-expression模塊
spring-expression模塊是統一運算式語言(EL)的擴展模塊,可以查詢、管理運行中的物件,同時也可以方便地呼叫物件方法,以及操作陣列、集合等,它的語法類似于傳統EL,但提供了額外的功能,最出色的要數函式呼叫和簡單字串的模板函式,EL的特性是基于Spring產品的需求而設計的,可以非常方便地同Spring IoC進行互動,
AOP和設備支持
用過Spring框架的話,那么你肯定用過AOP,相信你應該也是比較熟悉的,所以這里我就不再做過多贅述了,
資料訪問與集成
其實,資料訪問與集成這一模塊說白了就是對Dao層進行封裝的一個組件,
Web組件
對Web層進行封裝的組件,
通信報文
從以上Spring框架的總體架構圖中可以看到,Messaging代表的就是通信報文,這里我只是提一嘴,
集成測驗
從以上Spring框架的總體架構圖中可以看到,Test代表的就是集成測驗,說白了就是Spring集成JUnit來進行單元測驗,
當然了,Spring框架里面肯定還有一些其他模塊,但我在這里不可能一一列出來,于是就只挑了如上幾個模塊來說了一下,其中要重點關注核心容器這一模塊,
bean概述
接下來,我來為大家講一講Spring中的bean,因為bean對于Spring來說特別特別重要,所以我單獨把它拿過來給大家講一講,
Spring就是面向bean的編程(簡稱BOP,Bean Oriented Programming),bean在Spring中處于核心地位,bean對于Spring的意義就像Object對于OOP的意義一樣,如果Spring中沒有了bean,那么也就沒有Spring存在的意義了,Spring IoC容器通過組態檔或者注解的方式來管理bean物件之間的依賴關系,
接下來,我們來看一下什么是bean?
Spring中bean用于對一個類進行封裝,如下面的配置:
<bean id="userDao" class="com.meimeixia.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.meimeixia.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
你會發現以上配置中用到了兩個<bean>標簽,而每一個<bean>標簽就代表著一個bean,就拿第一個<bean>標簽來說,id屬性的值就是bean物件的名稱,而class屬性的值就是bean物件所屬類的全限定類名,為什么要宣告這倆屬性呢?因為Spring底層在去創建bean物件時,是通過反射的方式根據全限定類名去創建該類的物件的,
為什么bean如此重要呢?這是因為:
- Spring將bean物件交由一個叫IoC的容器進行管理,也就是說IoC容器是以bean物件為單位來進行管理的,
- bean物件之間的依賴關系在組態檔中體現,并由Spring完成,
這里,我們簡單地去聊了一下Spring中的bean,對于bean,大家應該還是要知道一點的,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/312118.html
標籤:java
上一篇:Java方法(三)
