SSM工作流程與原理詳解
點擊上方藍色字體,選擇“標星公眾號”
優(yōu)質文章,第一時間送達
? 作者?|??阿波羅的手
來源 |? urlify.cn/rqAFf2
自學ssm->springboot->springcloud,所以很多東西會用但理解較淺,所以現在從最開始的ssm開始進行對原理以及運行過程的整理知識歸納,若有錯誤感謝指正。
1.0Spring
1.1?Spring運行原理

1. Data Access/Integration(數據訪問/集成)
數據訪問/集成層包括 JDBC、ORM、OXM、JMS 和 Transactions 模塊,具體介紹如下。
JDBC 模塊:提供了一個 JDBC 的抽象層,大幅度減少了在開發(fā)過程中對數據庫操作的編碼。
ORM 模塊:對流行的對象關系映射 API,包括 JPA、JDO、Hibernate 和 iBatis 提供了的集成層。
OXM 模塊:提供了一個支持對象/XML 映射的抽象層實現,如 JAXB、Castor、XMLBeans、JiBX 和 XStream。
JMS 模塊:指 Java 消息服務,包含的功能為生產和消費的信息。
Transactions 事務模塊:支持編程和聲明式事務管理實現特殊接口類,并為所有的 POJO。
2. Web 模塊
Spring 的 Web 層包括 Web、Servlet、Struts 和 Portlet 組件,具體介紹如下。
Web 模塊:提供了基本的 Web 開發(fā)集成特性,例如多文件上傳功能、使用的 Servlet 監(jiān)聽器的 IoC 容器初始化以及 Web 應用上下文。
Servlet模塊:包括 Spring 模型—視圖—控制器(MVC)實現 Web 應用程序。
Struts 模塊:包含支持類內的 Spring 應用程序,集成了經典的 Struts Web 層。
Portlet 模塊:提供了在 Portlet 環(huán)境中使用 MVC實現,類似 Web-Servlet 模塊的功能。
3. Core Container(核心容器)
Spring 的核心容器是其他模塊建立的基礎,由 Beans 模塊、Core 核心模塊、Context 上下文模塊和 Expression Language 表達式語言模塊組成,具體介紹如下。
Beans 模塊:提供了 BeanFactory,是工廠模式的經典實現,Spring 將管理對象稱為 Bean。
Core 核心模塊:提供了 Spring 框架的基本組成部分,包括 IoC 和 DI 功能。
Context 上下文模塊:建立在核心和 Beans 模塊的基礎之上,它是訪問定義和配置任何對象的媒介。ApplicationContext 接口是上下文模塊的焦點。
Expression Language 模塊:是運行時查詢和操作對象圖的強大的表達式語言。
4. 其他模塊
Spring的其他模塊還有 AOP、Aspects、Instrumentation 以及 Test 模塊,具體介紹如下。
AOP 模塊:提供了面向切面編程實現,允許定義方法攔截器和切入點,將代碼按照功能進行分離,以降低耦合性。
Aspects 模塊:提供與 AspectJ 的集成,是一個功能強大且成熟的面向切面編程(AOP)框架。
Instrumentation 模塊:提供了類工具的支持和類加載器的實現,可以在特定的應用服務器中使用。
Test 模塊:支持 Spring 組件,使用 JUnit 或 TestNG 框架的測試。
1.2Spring IoC容器的基本概念
1.基本講解
在傳統(tǒng)方法中,Java對象需要調用另外一個Java對象時(如①調用②),調用者(①)通常采用“new”被調用者(②)來創(chuàng)建對象,這種方式會增加調用者和被調用者之間的耦合性。
當Spring框架出現后,對象實例不再由調用者來創(chuàng)建,即不通過直接new被調用者來創(chuàng)建對象,而是交給Spring容器來創(chuàng)建。
這時候調用者的程序將不再進行直接控制,而實轉交給了Spring容器,這就是Spring的控制反轉。
從Spring容器角度出發(fā),Spring容器負責將被依賴對象賦值給調用者的成員變量,相當于調用者注入它所有依賴的實例,這就是Spring的依賴注入。
舉一個很直白的例子:
海綿寶寶做出第一個美味蟹黃堡,當海綿寶寶想做多幾個蟹黃堡(調用者)時就得參照第一個蟹黃堡(被調用者)來進行制作。
一旦第一個蟹堡王丟了或者變味了,他后面就沒辦法做出一模一樣的美味蟹黃堡(耦合度高),所以這時候海綿寶寶把第一個蟹黃堡放到一個按照配方運轉的制造機器里(Spring容器),往后創(chuàng)造新的蟹黃堡都交給制造機來控制(Spring的控制反轉)。
2.通過Web服務其方式實例化ApplicationContext容器(最常用的方式)
Spring IoC容器的設計主要是基于BeanFactory和ApplicationContext兩個接口,而ApplicationContext是BeanFactory的子接口
"1.0"?encoding="UTF-8"?>
"http://www.w3.org/2001/XMLSchema-instance"
????xmlns="http://xmlns.jcp.org/xml/ns/javaee"
????xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee?http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
????id="WebApp_ID"?version="3.1">
????StudentShopping
????
????
????
????????contextConfigLocation
????????classpath:applicationContext.xml
????
????
????
????????org.springframework.web.context.ContextLoaderListener
????
?web.xml中ContextLoaderListener的作用:
就是啟動Web容器時,讀取在contextConfigLocation中定義的xml文件,自動裝配ApplicationContext的配置信息,并產生WebApplicationContext對象,然后將這個對象放置在ServletContext的屬性里,這樣我們只要得到Servlet就可以得到WebApplicationContext對象,并利用這個對象訪問spring容器管理的bean。
1.3依賴注入的理解
以下只進行簡單代碼講解,關于spring依賴注入類型具體實現可參考這篇文章:
https://blog.csdn.net/lyc_liyanchao/article/details/82428726
而這兩種注入可以分別用兩種注解來實現一個是 @Autowired 和 @Resource :
@Autowired ?可以用作構造注入 /@Resource ?用作 setter注入。
@Autowired注解是按照類型(byType)裝配依賴對象,默認情況下它要求依賴對象必須存在,如果允許null值,可以設置它的required屬性為false。
@Resource有兩個重要的屬性:name和type,而Spring將@Resource注解的name屬性解析為bean的名字,而type屬性則解析為bean的類型。所以,如果使用name屬性,則使用byName的自動注入策略,而使用type屬性時則使用byType自動注入策略。
另外在構造方法注入中,
當構造方法的參數出現混淆、無法區(qū)分時,可以通過
這也解釋了為什么@Autowired 可用作構造注入
public?class?Car?{
????
????private?String?brand;
????private?String?corp;
????private?double?price;
????private?int?maxSpeed;
????public?Car(String?brand,?String?corp,?double?price)?{
????????this.brand?=?brand;
????????this.corp?=?corp;
????????this.price?=?price;
????}
????public?Car(String?brand,?String?corp,?int?maxSpeed)?{
????????this.brand?=?brand;
????????this.corp?=?corp;
????????this.maxSpeed?=?maxSpeed;
????}
????@Override
????public?String?toString()?{
????????return?"Car?[brand="?+?brand?+?",?corp="?+?corp?+?",?price="?+?price
????????????????+?",?maxSpeed="?+?maxSpeed?+?"]";
????}
}
"1.0"?encoding="UTF-8"?>
????xmlns="http://www.springframework.org/schema/beans"
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
????xmlns:p="http://www.springframework.org/schema/p"
????xsi:schemaLocation="http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
????
????"car"?class="com.auguigu.spring.beans.Car">
????????"Audi"?type="java.lang.String">
????????"Shanghai"?type="java.lang.String">
????????"30000"?type="int">
????
????
????"car2"?class="com.auguigu.spring.beans.Car">
????????"BMW"?type="java.lang.String">
????????"BeiJing"?type="java.lang.String">
????????"300.00"?type="double">
????
1.4關于@Autowired的使用(拓展)
方法1:
//構造函數注入的方式:
public?class?TestController?{
private?final?TestService?testService;
????????@Autowired
????????public?TestController(TestService?testService)?{
????????????????this.testService?=?testService;
????????}
????????…
}
?方法2:
//變量注入的方式:
public?class?TestController?{
????????@Autowired
????????private?TestService?testService;???
???????????…
?}
?采用方法2可能會導致NPE(Null Pointer Exception),產生代碼如下:
public?class?TestController?{
????????@Autowired
????????private?TestService?testService;
????????private?String?testname;
?????//先執(zhí)行此處構造函數,而此時testService相當于并未注入,所以報控制針異常
????????public?TestController(){
??????????this.testname?=?testService.getTestName();
?????}
?}
?該類的構造函數中的變量值是通過TestService實例來調用TestService類中的方法獲得,而Java類會先執(zhí)行構造函數,然后在通過@Autowired注入實例,因此在執(zhí)行構造函數的時候就會報錯。
解決方法:
//解決方案就是采用構造函數的注入方式,如下:
public?class?TestController?{
????????private?TestService?testService;
????????private?String?testname;
????????@Autowired
?????????public?TestController(TestService?testService){
????????????????this.testService?=?testService;
????????????????this.testname?=?testService.getTestName();
??????????}
?}
?因此,采用構造函數注入有以下號處:
依賴不為空(省去了我們對其檢查),當要實例化TestController的時候,由于自己實現了有參數的構造函數,所以不會調用默認構造函數,那么就需要Spring容器傳入所需要的參數,所以就兩種情況:
1、有該類型的參數->傳入,OK 。
2:無該類型的參數->報錯。
所以保證不會為空。
2.0MyBatis
2.1MyBatis運行流程

?MyBatis運行流程解析
1、讀取 MyBatis 配置文件:mybatis-config.xml 為 MyBatis 的全局配置文件,配置了 MyBatis 的運行環(huán)境等信息,例如數據庫連接信息。
2、加載映射文件。映射文件即 SQL 映射文件,該文件中配置了操作數據庫的 SQL 語句,需要在 MyBatis 配置文件 mybatis-config.xml 中加載。mybatis-config.xml 文件可以加載多個映射文件,每個文件對應數據庫中的一張表。
3、構造會話工廠:通過 MyBatis 的環(huán)境等配置信息構建會話工廠 SqlSessionFactory。
4、創(chuàng)建會話對象:由會話工廠創(chuàng)建 SqlSession 對象,該對象中包含了執(zhí)行 SQL 語句的所有方法。
5、Executor 執(zhí)行器:MyBatis 底層定義了一個 Executor 接口來操作數據庫,它將根據 SqlSession 傳遞的參數動態(tài)地生成需要執(zhí)行的 SQL 語句,同時負責查詢緩存的維護。
6、MappedStatement 對象:在 Executor 接口的執(zhí)行方法中有一個 MappedStatement 類型的參數,該參數是對映射信息的封裝,用于存儲要映射的 SQL 語句的 id、參數等信息。【MappedStatement維護了一條
輸入參數映射:輸入參數類型可以是 Map、List 等集合類型,也可以是基本數據類型和 POJO 類型。輸入參數映射過程類似于 JDBC 對 preparedStatement 對象設置參數的過程。
輸出結果映射:輸出結果類型可以是 Map、 List 等集合類型,也可以是基本數據類型和 POJO 類型。輸出結果映射過程類似于 JDBC 對結果集的解析過程。
2.2MyBatis核心組件

1、SqlSessionFactoryBuilder(構造器):它會根據配置或者代碼來生成 SqlSessionFactory,采用的是分步構建的 Builder 模式。【SqlSessionFactoryBuilder 的作用在于創(chuàng)建 SqlSessionFactory,創(chuàng)建成功后,SqlSessionFactoryBuilder 就失去了作用,所以它只能存在于創(chuàng)建 SqlSessionFactory 的方法中,而不要讓其長期存在】
2、SqlSessionFactory(工廠接口):依靠它來生成 SqlSession,使用的是工廠模式。【SqlSessionFactory 可以被認為是一個數據庫連接池,它的作用是創(chuàng)建 SqlSession 接口對象。因為 MyBatis 的本質就是 Java 對數據庫的操作,所以 SqlSessionFactory 的生命周期存在于整個 MyBatis 的應用之中,所以一旦創(chuàng)建了 SqlSessionFactory,就要長期保存它,直至不再使用 MyBatis 應用,所以可以認為 SqlSessionFactory 的生命周期就等同于 MyBatis 的應用周期。我們往往希望 SqlSessionFactory 作為一個單例,讓它在應用中被共享。所以說 SqlSessionFactory 的最佳作用域是應用作用域。】
3、SqlSession(會話):一個既可以發(fā)送 SQL 執(zhí)行返回結果,也可以獲取 Mapper 的接口。在現有的技術中,一般我們會讓其在業(yè)務邏輯代碼中“消失”,而使用的是 MyBatis 提供的 SQL Mapper 接口編程技術,它能提高代碼的可讀性和可維護性。【SqlSessionFactory 相當于數據庫連接池,那么 SqlSession 就相當于一個數據庫連接(Connection 對象),你可以在一個事務里面執(zhí)行多條 SQL,然后通過它的 commit、rollback 等方法,提交或者回滾事務。它應該存活在一個業(yè)務請求中,處理完整個請求后,應該關閉這條連接,讓它歸還給 SqlSessionFactory,否則數據庫資源就很快被耗費精光,系統(tǒng)就會癱瘓,所以用 try...catch...finally... 語句來保證其正確關閉。】
4、SQL Mapper(映射器):MyBatis 新設計存在的組件,它由一個 Java 接口和 XML 文件(或注解)構成,需要給出對應的 SQL 和映射規(guī)則。它負責發(fā)送 SQL 去執(zhí)行,并返回結果。【Mapper 是一個接口,它由 SqlSession 所創(chuàng)建,所以它的最大生命周期至多和 SqlSession 保持一致,盡管它很好用,但是由于 SqlSession 的關閉,它的數據庫連接資源也會消失,所以它的生命周期應該小于等于 SqlSession 的生命周期。Mapper 代表的是一個請求中的業(yè)務處理,所以它應該在一個請求中,一旦處理完了相關的業(yè)務,就應該廢棄它。】
2.3為什么要利用Spring來整合MyBatis?
1、MyBatis與Spring的整合步驟
"dataSource"?class="org.apache.commons.dbcp.BasicDataSource">
????"driverClassName"?value="com.mysql.jdbc.Driver"?/>
????"url"?value="jdbc:mysql://127.0.0.1:3306/springtest?seUnicode=true&characterEncoding=utf-8"?/>
????"username"?value="root"?/>
????"password"?value="1128"?/>
????
????"maxTotal"?value="30"/>
????
????"maxIdle"?value="10"/>
????
????"initialSize"?value="5"/>
"sqlSessionFactory"?class="org.mybatis.spring.SqlSessionFactoryBean">
????
????"dataSource"?ref="dataSource"?/>
????
????"configLocation"?value="classpath:mybatis-config.xml"?/>
由上面可以得知,我們都知道Spring在整合Mybatis的時候都會配置一個SqlSessionFactoryBean對象來生成一個SqlSessionFactory,而這個SqlSessionFactory就是作為SqlSession(數據庫會話)的關鍵部分,那么Spring又怎么把這個對象與DAO接口類關聯放在mapperRegistry里。
@Mapper
public?interface?AdminDao?{
????public?List?login(Auser?auser);
}
?AdminMapper.xml文件
"1.0"?encoding="UTF-8"??>
PUBLIC?"-//mybatis.org//DTD?Mapper?3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
"com.dao.AdminDao">
????
????
使用 Spring 管理 MyBatis 數據操作接口的方式有多種,其中最常用、最簡潔的一種是基于 MapperScannerConfigurer 的整合。
該方式需要在 Spring 的配置文件中加入以下內容:
????
???
????"org.mybatis.spring.mapper.MapperScannerConfigurer">
????????
????????"basePackage"?value="com.dao"?/>
????????"sqlSessionFactoryBeanName"?value="sqlSessionFactory"?/>
????
?如果理解不了上面橙色標記的話的含義,根據上面的代碼其實可以理解成:
采用MapperScannerConfigurer掃描類讓dao包的接口和SQL聯系起來,從而實現調用者通過接口自由使用相關數據庫訪問操作的功能。
2、為什么要利用Spring來整合MyBatis
通過對Spring的講解可以得知Spring的控制反轉機制降低了調用者和被調用者之間的耦合性,因此將MyBatis放入Spring容器后開發(fā)者只需要進行業(yè)務處理,不需要再寫 SqlSession 對象的創(chuàng)建、數據庫事務的處理等煩瑣代碼,提高了開發(fā)效率。
3.0SpringMVC
3.1基礎知識
1、MVC概念:
模型(Model):用于存儲數據以及處理用戶請求的用戶邏輯
視圖(View):向控制器提交數據,顯示模型中的數據
控制器(Controller):根據視圖提出的請求判斷將請求和數據提交給哪個模型處理,將處理后的有關接結果交給哪個視圖顯示更新
2、基于Servlet的MVC模式
模型:一個或多個JavaBean對象,用于存儲數據和處理業(yè)務邏輯
視圖:一個或多個JSP頁面,向控制器提交數據和為模型提供數據顯示,JSP頁面主要使用HTML標記和JavaBean標記顯示數據
控制器:一個或多個Servlet對象,根據視圖提交的請求進行控制,將請求轉發(fā)給處理業(yè)務的JavaBean,并將處理結果放到實體模型JavaBean中,輸出給視圖顯示

3、SpringMVC工作原理
客戶端請求提交到DispatcherServlet;
由DispatcherServlet控制器尋找到一個或多個HandlerMapping,找到處理請求Controller;
DispatcherServlet將請求提交到Controller
Controller調用業(yè)務邏輯處理后返回ModelAndView
DispatcherServlet心找一個或多個視圖解析器,找到ModelAndView指定的視圖
視圖負責把結果顯示在客戶端
4、SpringMVC接口在工作流程中起的作用
SpringMVC所有請求都經過DispatcherServlet來統(tǒng)一分布,在DispatcherServlet借助SpringMVC提供的HandlerMapping定位到具體的Controller。
Controller處理完用戶請求后將返回ModelAndView(包含模型和視圖)對象給DispatcherServlet前端控制器。
ViewResolver接口(視圖解析器)在Web應用中查找View對象,從而將相應的結果渲染給客戶
從宏觀角度考慮,DispatcherServlet是整個Web應用的控制器;
從微觀角度考慮,Controller是單個Http請求處理過程中的控制器,而ModelAndView是Http請求過程中返回的模型和視圖。

4、在ssm整合項目中SpringMvc相關:
web.xml配置文件
"1.0"?encoding="UTF-8"?>
"http://www.w3.org/2001/XMLSchema-instance"
????xmlns="http://xmlns.jcp.org/xml/ns/javaee"
????xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee?http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
????id="WebApp_ID"?version="3.1">
????StudentShopping
????
????
????
????????contextConfigLocation
????????classpath:applicationContext.xml
????
????
????
????????org.springframework.web.context.ContextLoaderListener
????
????
????????springmvc
????????org.springframework.web.servlet.DispatcherServlet
????????1
????
????
????
????????springmvc
????????/
????
????
????????encodingFilter
????????org.springframework.web.filter.CharacterEncodingFilter
????????
????????????encoding
????????????UTF-8
????????
????????
????????????forceEncoding
????????????true
????????
????
????
????????encodingFilter
????????/*
????
????
?SpringMVC的配置文件內包含的 Controller映射以及視圖解析器:
"1.0"?encoding="UTF-8"?>
"http://www.springframework.org/schema/beans"
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
????xmlns:context="http://www.springframework.org/schema/context"
????xmlns:mvc="http://www.springframework.org/schema/mvc"
????xmlns:p="http://www.springframework.org/schema/p"
????xsi:schemaLocation="http://www.springframework.org/schema/mvc?
????????http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
????????http://www.springframework.org/schema/beans?
????????http://www.springframework.org/schema/beans/spring-beans.xsd
????????http://www.springframework.org/schema/context?
????????http://www.springframework.org/schema/context/spring-context-4.3.xsd">
????????????base-package="com.controller"?/>
????
????"/css/"?mapping="/css/**">
????"/images/"?mapping="/images/**">
????"/logos/"?mapping="/logos/**">
????
????
????"/login"?class="com.controller.admin.LoginController"/>
??
????????????class="org.springframework.web.servlet.view.InternalResourceViewResolver"
????????id="internalResourceViewResolver">
????????"prefix"?value="/WEB-INF/jsp/"?/>
????????"suffix"?value=".jsp"?/>
????
????"multipartResolver"
????????class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
????????p:defaultEncoding="UTF-8"?
????????p:maxUploadSize="5400000"
????????p:uploadTempDir="fileUpload/temp">
????
粉絲福利:實戰(zhàn)springboot+CAS單點登錄系統(tǒng)視頻教程免費領取
???
?長按上方微信二維碼?2 秒 即可獲取資料
感謝點贊支持下哈?
