16張思維導圖講解spring,另有源碼相伴,你再敢說學不會

體系架構圖講解知識點

“spring源碼,看過嗎?“當朋友跟我說起來面試的時候問到的這個問題,我表面波瀾不驚,內心實則一萬隻神獸奔騰而過,面試都已經這樣的了嗎?

突然感覺好難啊,平時應付工作就已經精疲力竭了,哪裏來的功夫去做別的啊,我個人覺得應該大多數的程序員可能跟我一樣的狀態,那該怎麼辦,那就把有限的精力花在刀刃上吧,爲此,我整理了關於sping、ioc、aop的相關知識,形成了一套腦圖供大家學習使用,有體系的學習總好過漫無目的的瞎撞吧

關於Spring

Spring是一個開源框架,是爲了解決企業應用程序開發複雜性而創建的。框架的主要優勢之一就是其分層架構,分層架構允許您選擇使用哪一個組件,同時爲 J2EE 應用程序開發提供集成的框架。

它是一個全面的、企業應用開發一站式的解決方案,貫穿表現層、業務層、持久層。但是Spring仍然可以和其他的框架無縫整合。

Sping架構

Spring框架是分模塊存在,除了最核心的Spring Core Container(即Spring容器)是必要模塊之外,其他模塊都是可選,視需要而定。大約有20多個模塊。

 

Spring3與Spring4是有區別的,4.0主要是對Java 8的新函數式語法進行支持,還有加強了對網絡各種新技術比如http-streaming, websocket的更好的支持。

一般來說,Spring主要分爲7個模塊:

 

 

Spring的主要jar包

 

 

常用註解

bean注入與裝配的的方式有很多種,可以通過xml,getset方式,構造函數或者註解等。簡單易用的方式就是使用Spring的註解了,Spring提供了大量的註解方式,讓項目閱讀和開發起來更加方便。

 

第三方框架集成

Spring框架的開發不是爲了替代現有的優秀第三方框架,而是通過集成的方式把它們都連接起來。下面總結了一些常集成的優秀框架。

spring ioc

寫過java的都知道:所有的對象都必須創建;或者說:使用對象之前必須先創建。而使用ioc之後,你就可以不再手動創建對象,而是從ioc容器中直接獲取對象。

就好像我們無需考慮對象的銷燬回收一樣,因爲java垃圾回收機制幫助我們實現了這個過程;而ioc則是讓我們無需考慮對象的創建過程,由ioc容器幫我們實現對象的創建、注入等過程。

 

控制反轉

 

spring ioc容器

在Spring框架中的核心組件只有三個:Core、Context和Bean。它們構建起了整個Spring的骨骼架構,沒有它們就不可能有AOP、Web等特性功能。

 

如果說在三個核心中再選出一個核心,那就非Bean莫屬了。可以說,Spring就是面向Bean的編程,Bean在Spring中才是真正的主角。

Spring爲何如此流行?你會發現Spring解決了一個非常關鍵的問題,它可以讓你對對象之間的關係轉而用配置文件來管理,或者註解,也就是它的依賴注入機制。而這個注入關係在一個叫Ioc的容器中管理。Ioc容器就是被Bean包裹的對象。Spring正是通過把對象包裝在Bean中從而達到管理這些對象及做一些列額外操作的目的。

 

 

 

核心組件協同工作

 

BeanFactory與ApplacationContext的區別

IOC中最核心的接口是Beanfactory提供IOC的高級服務,而ApplicationContext是建立在BeanFactory基礎之上提供抽象的面向應用的服務。

 

3種注入方式

在Spring框架中,依賴注入(DI)的設計模式是用來定義對象彼此間的依賴。使用xml配置bean的情況下,它主要有兩種類型:

  • Setter方法注入

  • 構造器注入

當然,有了註解之後,使用註解的方式更加方便快捷。即自動裝配功能實現屬性自動注入(@autowire)。

寫到這裏,讓我想起了最近在牛客網上看的一道選擇題了:


 
下面有關spring的依賴注入,說法錯誤的是?

A、依賴注入通常有如下兩種:設置注入和構造注入:
B、構造注入可以在構造器中決定依賴關係的注入順序,優先依賴的優先注入
C、當設值注入與構造注入同時存在時,先執行構造注入,再執行設值注入
D、設值注入是指IoC容器使用屬性的setter方法來注入被依賴的實例。這種注入方式比較簡單、直觀

牛客網給出的答案是選C,不過網友們好像對答案有不同的意見哈。查看網友評論及答案

原理解析

Spring的代碼還真是不好讀,分得太細了,文字也是難以描述出來,看了別人有關的博客,貼了好多代碼,畫了好多ER圖來描述關鍵接口或類之間的關係。這麼一篇這麼長文章下來,大家也未必會認真讀代碼,看ER圖,乾脆也不跟風了。就貼了一點在我看來特關鍵的代碼,嘿嘿。

######context的初始化過程

當運行 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); 構造方法ClassPathXmlApplicationContext(String configLocation)調用了this(new String[] {configLocation}, true, null);, 該構造方法具體代碼如下。

 

 

######從時序圖來看啓動上述初始化

 

springaop

AOP(Aspect-OrientedProgramming,面向方面編程),可以說是OOP(Object-Oriented Programing,面向對象編程)的補充和完善。OOP允許你定義從上到下的關係,但並不適合定義從左到右的關係。例如日誌功能。日誌代碼往往水平地散佈在所有對象層次中,而與它所散佈到的對象的核心功能毫無關係。這種散佈在各處的無關的代碼被稱爲橫切(cross-cutting)代碼,在OOP設計中,它導致了大量代碼的重複,而不利於各個模塊的重用。

 

而AOP技術則恰恰相反,它利用一種稱爲“橫切”的技術,剖解開封裝的對象內部,並將那些影響了多個類的公共行爲封裝到一個可重用模塊,並將其名爲“Aspect”,即方面。所謂“方面”,簡單地說,就是將那些與業務無關,卻爲業務模塊所共同調用的邏輯或責任封裝起來,便於減少系統的重複代碼,降低模塊間的耦合度,並有利於未來的可操作性和可維護性。

aop使用場景

aop框架種類

  • AspectJ

  • JBoss AOP

  • Spring AOP

使用aop可以做的事情有很多。

  • 性能監控,在方法調用前後記錄調用時間,方法執行太長或超時報警。

  • 緩存代理,緩存某方法的返回值,下次執行該方法時,直接從緩存裏獲取。

  • 軟件破解,使用AOP修改軟件的驗證類的判斷邏輯。

  • 記錄日誌,在方法執行前後記錄系統日誌。

  • 工作流系統,工作流系統需要將業務代碼和流程引擎代碼混合在一起執行,那麼我們可以使用AOP將其分離,並動態掛接業務。

  • 權限驗證,方法執行前驗證是否有權限執行當前方法,沒有則拋出沒有權限執行異常,由業務代碼捕捉。

觀察一下傳統編碼方式與使用aop的區別

 

核心概念

描述AOP常用的一些術語有通知(Adivce)、切點(Pointcut)、連接點(Join point)、切面(Aspect)、引入(Introduction)、織入(Weaving)、通知(Advice)等。

 

簡單例子

相比xml配置,基於註解的方式更加簡潔方便。


 
@Aspect
public class TransactionDemo {

@Pointcut(value="execution(* com.yangxin.core.service.*.*.*(..))")
public void point(){

}

@Before(value="point()")
public void before(){
System.out.println("transaction begin");
}

@AfterReturning(value = "point()")
public void after(){
System.out.println("transaction commit");
}

@Around("point()")
public void around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("transaction begin");
joinPoint.proceed();
System.out.println("transaction commit");
}
}

在applicationContext.xml中配置。


 
<aop:aspectj-autoproxy />
<bean id = "transactionDemo" class = "com.yangxin.core.transaction.TransactionDemo" />

spring aop原理

通過前面介紹可以知道:AOP 代理其實是由 AOP 框架動態生成的一個對象,該對象可作爲目標對象使用。AOP 代理包含了目標對象的全部方法,但 AOP 代理中的方法與目標對象的方法存在差異:AOP 方法在特定切入點添加了增強處理,並回調了目標對象的方法。

 

Spring 的 AOP 代理由 Spring 的 IoC 容器負責生成、管理,其依賴關係也由 IoC 容器負責管理。因此,AOP 代理可以直接使用容器中的其他 Bean 實例作爲目標,這種關係可由 IoC 容器的依賴注入提供。

aop開發時,其中需要程序員參與的只有 3 個部分:

  • 定義普通業務組件。

  • 定義切入點,一個切入點可能橫切多個業務組件。

  • 定義增強處理,增強處理就是在 AOP 框架爲普通業務組件織入的處理動作。

爲了理清關係,先來個類關係圖。

 

兩種動態代理方式

Spring默認採取的動態代理機制實現AOP,當動態代理不可用時(代理類無接口)會使用CGlib機制。

Spring提供了兩種方式來生成代理對象: JDKProxy和Cglib,具體使用哪種方式生成由AopProxyFactory根據AdvisedSupport對象的配置來決定。默認的策略是如果目標類是接口,則使用JDK動態代理技術,否則使用Cglib來生成代理。

JDK動態代理

  • JDK動態代理主要涉及到java.lang.reflect包中的兩個類:Proxy和InvocationHandler。InvocationHandler是一個接口,通過實現該接口定義橫切邏輯,並通過反射機制調用目標類的代碼,動態將橫切邏輯和業務邏輯編制在一起。

  • Proxy利用InvocationHandler動態創建一個符合某一接口的實例,生成目標類的代理對象。

CGLib動態代理

  • CGLib全稱爲Code Generation Library,是一個強大的高性能,高質量的代碼生成類庫,可以在運行期擴展Java類與實現Java接口,CGLib封裝了asm,可以再運行期動態生成新的class。和JDK動態代理相比較:JDK創建代理有一個限制,就是隻能爲接口創建代理實例,而對於沒有通過接口定義業務方法的類,則可以通過CGLib創建動態代理。

知識拓展

通過上面的分析,大家是否有種熟悉的感覺,似乎和攔截器、過濾器的功能相似。那麼問題來了,aop與攔截器、過濾器是什麼關係。

先來回顧一下攔截器與過濾器。如下圖一網友的測試,在web.xml中註冊了TestFilter1和TestFilter2。然後在spring的配置文件中配置了BaseInterceptor和TestInterceptor。得到的結果如下圖所示。從圖中可以看出,攔截器和過濾器都橫切了業務方法,看似符合aop的思想。

 

Filter過濾器:攔截web訪問url地址。Interceptor攔截器:攔截以 .action結尾的url,攔截Action的訪問。Spring AOP攔截器:只能攔截Spring管理Bean的訪問(業務層Service)

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