SpringMVC---依賴注入與面向切面


1、依賴注入與面向切面

1.1、出現背景

——如何簡化java開發?

       其中很重要的一點是“組件化”。

——如何更好的“組件化”?

       松耦合,以及盡可能的讓組件專注於本身。

——Spring框架的目的也只有一個,就是簡化java開發

 

1.2耦合

       很多框架通過強迫應用繼承它們的類或實現它們的接口,從而讓應用和框架綁死。而耦合又是必須的,有協作關系的類之間必定存在耦合,所以重要的是保持松散耦合

 

1.3、依賴注入DI(Dependency Injection)

       即利用第三方容器來管理類之間的耦合。在Spring中,對應的概念是Spring容器。它的設計思想主要是是反轉資源獲取的方向。

傳統的資源查找方式要求組件向容器發起請求查找資源,作為回應,容器適時的返回資源。而應用了 IoC 之后, 則是容器主動地將資源推送給它所管理的組件, 組件所要做的僅是選擇一種合適的方式來接受資源總結來說,Spring 就是一個實現了IoC的容器。

 

1.4、面向切面AOP(Aspect Oriented Programming)

(1)橫切關注點:多個組件可能都需要用到的系統服務,如日志、事務管理(與組件核心業務邏輯無關)。

(2)雙重復雜性:

 a. 橫切關注點重復出現在多個組件中,修改和維護須修改各個模塊相關實現。

 b. 組件因為這些與自身核心業務無關的代碼而變得混亂。

(3)切點:定義了何處(在程序執行過程中的某個事件/方法)

(4)通知:定義了切面的事務,以及何時執行(相對於切點前后/環繞)

(5)切面:切面由通知和切點組成,它在何時何處完成什么功能

(6)連接點:連接點是一個應用執行過程中能夠插入一個切面的點。

(7)織入: 織入是將切面應用到目標對象來創建的代理對象過程。

 

    仔細地觀察上圖,在程序執行過程中,可以有多個的連接點,在這些連接點上,我們便可以向其中插入切面(即你所想要插入的某個邏輯,這個邏輯,就是上面所說的橫切關注點),這樣我們就可以更好地理解下,什么是AOP?在運行時,動態地將代碼切入到類的指定方法、指定位置上的編程思想就是面向切面的編程。

這樣的思想有什么好處呢?試想一下,程序寫好了之后,你想要針對所有業務操作添加一個日志,傳統的做法是,改造每個業務方法,這樣勢必把代碼弄得一團糟,而且以后再擴展還是更亂。而AOP的思想則是引導你從另一個切面來看待和插入這個日志,不管加在哪,它其實都是屬於日志系統這個角度的。

舉個例子:

       那么,這樣說來,我們也就懂得為什么會有AOP的思想,殊途同歸,就是為了降低我們維護和開發程序的開銷,就是為了簡化Java開發。

在這里,我們主要講的是Spring的編程思想,理解這種思想后,再進行實際操作也會得心應手。

 

 

 

2、Bean的相關介紹

 

2.1、Bean的原理

        Bean就相當於定義一個組件,這個組件是用於具體實現某個功能的,可以重復使用。Bean的好處是:  

(1)可以不必再次編譯,就可以工作在任何支持Java的平台上。  

(2)可以以其他組件模式工作。  

(3)可以在內部、網間和網內傳輸。  

 

2.2、什么是配置bean?

        Spring幫我們做的就是根據配置文件來創建Bean實例,並調用Bean實例的方法來完成“依賴注入”,可以把Spring容器理解成一個大型工廠,Bean就是該工廠的產品,工廠(Spirng容器)里能生產出來什么樣的產品(Bean),完全取決於我們在配置文件中的配置。

 

2.3、那么我們該如何配置Bean呢?

Bean的配置形式,主要有以下2種:

(1)基於 XML文件的方式

(2)基於注解的方式(這點在下文會有詳細說明)

Bean的依賴注入方式,主要有以下3種:

(1)屬性注入方法

(2)構造函數注入方法

(3)工廠方法注入方法

 

  • 屬性注入方法:屬性注入即通過setXXX()方法注入Bean的屬性值或者依賴對象

  • 構造函數注入方法:構造函數注入方法保證一些必要的屬性在Bean實例化時就得到了設置,並在實例化后就可以使用。

       【如果有多個構造器,可以通過index和value進行更加精確的定位】 

 

  • 工廠方法注入方法(靜態工廠&實例工廠):即工廠類創建一個或多個工廠類實例,工廠類方法一般以接口或抽象類變量的形式返回目標類實例。不推薦使用。

 

2.4、 Bean的實例化

        在Spring IoC 容器讀取 Bean 配置創建 Bean 實例之前, 必須對它進行實例化。Spring 提供了兩種類型的 IoC 容器實現:

(1)Bean工廠 BeanFactory: IoC 容器的基本實現。

(2)應用上下文 ApplicationContext:提供了更多的高級特性,是BeanFactory 的子接口。

        BeanFactory 是 Spring 框架的基礎設施,面向 Spring 本身。而ApplicationContext面向使用 Spring 框架的開發者,幾乎所有的應用場合都直接使用ApplicationContext,而非底層的 BeanFactory。無論使用何種方式, 配置文件是相同的。

我們看看下面的例子

        而Bean的實例化還有一種形式,即基於注解的形式,這在下文會提及,也是一種較為常用的方法。

 

2.5、Bean的自動裝配

      自動裝配(常用)定義是只聲明Bean, 而把Bean之間的關系交給 IoC 容器來完成。Spring IoC 容器可以自動裝配Bean,我們需要做的僅僅是在 <bean> 的 autowire 屬性里指定自動裝配的模式。

(1)byType(根據類型自動裝配): 若IoC容器中有多個與目標Bean類型一致的 bean,在這種情況下,Spring 將無法判定哪個 bean 最合適該屬性,所以不能執行自動裝配。

(2)byName(根據名稱自動裝配): 必須將目標Bean的名稱和屬性名設置的完全相同。

(3)constructor(通過構造器自動裝配): 當Bean中存在多個構造器時,此種自動裝配方式將會很復雜,不推薦使用。

(4)autodetect(自動檢測):如果constructor裝配失敗,則采用byType。

 

2.6、基於注解配置bean

組件掃描(component scanning):  Spring 能夠從 classpath 下自動掃描,偵測和實例化具有特定注解的組件。特定組件包括:

@Component: 基本注解, 標識了一個受 Spring 管理的組件

@Respository: 標識持久層組件

@Service: 標識服務層(業務層)組件

@Controller: 標識表現層組件

對於掃描到的組件, Spring 有默認的命名策略:使用非限定類名, 第一個字母小寫,也可以在注解中通過 value 屬性值標識組件的名稱。

當在組件類上使用了特定的注解之后,還需要在 Spring 的配置文件中聲明<context:component-scan>,其中base-package 屬性指定一個需要掃描的基類包,Spring 容器將會掃描這個基類包里及其子包中的所有類。就像這樣:

Spring 還支持 @Resource 和 @Inject 注解,這兩個注解和 @Autowired 注解的功用類似。@Resource 注解要求提供一個 bean 名稱的屬性,若該屬性為空,則自動采用標注處的變量或方法名作為 bean 的名稱。@Inject 和 @Autowired 注解一樣也是按類型匹配注入的 bean, 但沒有 reqired 屬性。建議讀者使用@Autowired 注解。

當 Spring 容器啟動時,AutowiredAnnotationBeanPostProcessor 將掃描 Spring 容器中所有 Bean,當發現 Bean 中擁有@Autowired 注釋時就找到和其匹配(默認按byType匹配)的 Bean,並注入到對應的地方中去。 

當然,該實例也可以自動裝配具有@Resource 、@Inject注解的屬性。它可以對類成員變量、方法及構造函數進行標注,完成自動裝配的工作。我們可以通過@Autowired的使用來消除 set ,get方法,如下圖的例子:

2.7、Spring表達式語言:SpEL

Spring 表達式語言(簡稱SpEL):是一個支持運行時查詢和操作對象圖的強大的表達式語言。

語法類似於 EL:SpEL 使用 #{…} 作為定界符,所有在大框號中的字符都將被認為是 SpEL,SpEL 為bean 的屬性進行動態賦值提供了便利。

通過 SpEL 可以實現:

       (1)通過bean 的 id 對 bean 進行引用

       (2)調用方法以及引用對象中的屬性

       (3)計算表達式的值

       (4)正則表達式的匹配

 

2.8、Bean在Spring中的地位

其實 Spring 就是面向 Bean 的編程(BOP,Bean Oriented Programming),Bean 在 Spring 中才是真正的主角。

Bean 在 Spring 中作用就像 Object 對 OOP(Object OrientedProgramming) 的意義一樣,沒有對象的概念就像沒有面向對象編程,Spring 中沒有 Bean 也就沒有 Spring 存在的意義。

    Bean的生命周期:

    (1)調用 Bean 的初始化方法,Bean 可以使用了

    (2)當容器關閉時, 會調用 Bean 的銷毀方法 

 

 

3、SpringMVC調研流程

 

3.1、什么是Spring MVC

MVC實際上是一種設計模式

M代表model(模型)。模型表示企業數據和業務規則。被模型返回的數據是中立的,就是說模型與數據格式無關,這樣一個模型能為多個視圖提供數據。由於應用於模型的代碼只需寫一次就可以被多個視圖重用,所以減少了代碼的重復性。

      V代表View(視圖)。視圖是用戶看到並與之交互的界面。如html,jsp等。

      C代表Controller(控制器)。控制器接受用戶的輸入並調用模型和視圖去完成用戶的需求。所以當單擊Web頁面中的超鏈接和發送HTML表單時,控制器本身不輸出任何東西和做任何處理。它只是接收請求並決定調用哪個模型構件去處理請求,然后用確定用哪個視圖來顯示模型處理返回的數據。

 

3.2、跟蹤Spring MVC的請求

首先控制器接收到用戶的請求,並決定應該調用哪個模型來進行處理,然后模型用業務邏輯來處理用戶的請求並返回數據,最后控制器用相應的視圖格式化模型返回的數據,並通過表示層呈現給用戶。

 

3.3、搭建Spring MVC

通過配置xml的形式

 

3.4、Spring MVC與數據庫的結合

(1)DAO(數據訪問對象)

        DAO提供了數據讀取和寫入到數據庫中的一種方式,它們應該是以接口的方式發布功能。

可以通過Mybatis封裝數據操作,如下面的例子,實現了IUserDao中的insert接口,參數類型為User,將User插入數據庫User表中

(2)Service(服務對象)

       調用Dao的方法,實現我們所需要的操作,供Controller使用。

        一個經驗:設計良好的控制器本身只處理很少甚至不處理工作,而是將業務邏輯委托給一個或多個服務對象。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM