Spring框架自2002年誕生以來一直備受開發(fā)者青睞,它包括SpringMVC、SpringBoot、Spring Cloud、Spring Cloud Dataflow等解決方案。有人親切的稱之為:Spring 全家桶。 很多研發(fā)人員把spring看作心目中最好的java項目,沒有之一。 所以這是重點也是難點,工作中必須會,面試時肯定考。 那么,花費10分鐘,梳理Spring框架相關(guān)知識。 Spring知識點-匯總 spring系列包含非常多的項目,可以滿足java開發(fā)中的方方面面。 先來看常用框架的知識點匯總,如圖: 一、5個常用的spring框架 ▌1.spring framework 也就是我們經(jīng)常說的spring框架,包括了ioc依賴注入,Context上下文、bean管理、springmvc等眾多功能模塊,其它spring項目比如spring boot也會依賴spring框架。 ▌2.spring boot 它的目標(biāo)是簡化Spring應(yīng)用和服務(wù)的創(chuàng)建、開發(fā)與部署,簡化了配置文件,使用嵌入式web服務(wù)器,含有諸多開箱即用的微服務(wù)功能,可以和spring cloud聯(lián)合部署。 Spring Boot的核心思想是約定大于配置,應(yīng)用只需要很少的配置即可,簡化了應(yīng)用開發(fā)模式。 ▌3.Spring Data 是一個數(shù)據(jù)訪問及操作的工具集,封裝了多種數(shù)據(jù)源的操作能力,包括:jdbc、Redis、MongoDB等。 ▌4.Spring Cloud 是一套完整的微服務(wù)解決方案,是一系列不同功能的微服務(wù)框架的集合。Spring Cloud基于Spring Boot,簡化了分布式系統(tǒng)的開發(fā),集成了服務(wù)發(fā)現(xiàn)、配置管理、消息總線、負(fù)載均衡、斷路器、數(shù)據(jù)監(jiān)控等各種服務(wù)治理能力。比如sleuth提供了全鏈路追蹤能力,Netflix套件提供了hystrix熔斷器、zuul網(wǎng)關(guān)等眾多的治理組件。config組件提供了動態(tài)配置能力,bus組件支持使用RabbitMQ、kafka、Activemq等消息隊列,實現(xiàn)分布式服務(wù)之間的事件通信。 ▌5. Spring Security 主要用于快速構(gòu)建安全的應(yīng)用程序和服務(wù),在Spring Boot和Spring Security OAuth2的基礎(chǔ)上,可以快速實現(xiàn)常見安全模型,如單點登錄,令牌中繼和令牌交換。你可以了解一下oauth2授權(quán)機制和jwt認(rèn)證方式。oauth2是一種授權(quán)機制,規(guī)定了完備的授權(quán)、認(rèn)證流程。JWT全稱是JSON Web Token,是一種把認(rèn)證信息包含在token中的認(rèn)證實現(xiàn),oauth2授權(quán)機制中就可以應(yīng)用jwt來作為認(rèn)證的具體實現(xiàn)方法。 二、Struts的具體作用 struts是曾經(jīng)非?;鸨膚eb組合ssh中的控制層。我們知道web服務(wù)一般都采用MVC分層模型構(gòu)建,就是model層負(fù)責(zé)內(nèi)部數(shù)據(jù)模型,controller負(fù)責(zé)請求的分發(fā)控制,view層負(fù)責(zé)返回給用戶展示的視圖。struts實現(xiàn)的就是其中控制層的角色。 Struts采用Filter實現(xiàn),針對類進(jìn)行攔截,每次請求就會創(chuàng)建一個Action。使用struts的SSH組合已經(jīng)逐漸被使用springMVC的SSM組合代替,也就是Spring-MVC Spring MyBatis的組合,一方面原因是由于struts對幾次安全漏洞的處理,讓大家對struts的信心受到影響;另一方面,springmvc更加的靈活,不需要額外配置,不存在和spring整合等問題,使用更加方便,所以建議以SSM框架的學(xué)習(xí)為主。 三、常用的ORM框架 ORM就是對象關(guān)系匹配,是為了解決面向?qū)ο笈c關(guān)系數(shù)據(jù)庫存在的互不匹配的問題。簡單來說,就是把關(guān)系數(shù)據(jù)庫中的數(shù)據(jù)轉(zhuǎn)換成面向?qū)ο蟪绦蛑械膶ο蟆?/p> 常用的ORM框架有Hibernate和MyBatis,也就是ssh組合和ssm組合中的h與m。 它們的特點和區(qū)別如下: Hibernate對數(shù)據(jù)庫結(jié)構(gòu)提供了完整的封裝,實現(xiàn)了POJO對象與數(shù)據(jù)庫表之間的映射,能夠自動生成并執(zhí)行SQL語句。只要定義了POJO 到數(shù)據(jù)庫表的映射關(guān)系,就可以通過Hibernate提供的方法完成數(shù)據(jù)庫操作。Hibernate符合JPA規(guī)范,就是Java持久層API。 mybatis通過映射配置文件,將SQL所需的參數(shù)和返回的結(jié)果字段映射到指定對象,mybatis不會自動生成sql,需要自己定義sql語句,不過更方便對sql語句進(jìn)行優(yōu)化。 總結(jié)起來:
四、Netty簡介 Netty是一個高性能的異步事件驅(qū)動的網(wǎng)絡(luò)通信框架,Netty對JDK原生NIO進(jìn)行封裝,簡化了網(wǎng)絡(luò)服務(wù)的開發(fā)。下文會詳細(xì)講解 另外,同類型的框架還有mina、grizzly,不過目前使用的相對較少,一般不會在面試中出現(xiàn),可以作為興趣簡單了解。 五、RPC服務(wù) Motan、Dubbo、gRPC都是比較常用的高性能rpc框架,可以提供完善的服務(wù)治理能力,java版本的通信層都是基于前面提到的Netty實現(xiàn)。它們的特點稍后介紹。 六、其他常用框架 jersy和restEasy都是可以快速開發(fā)restful服務(wù)的框架。 和springmvc相比,這兩個框架都是基于jax-rs標(biāo)準(zhǔn),而springmvcs基于servlet,使用自己構(gòu)建的API,是兩個不同的標(biāo)準(zhǔn)。 shiro框架是一個與spring security類似的開源的權(quán)限管理框架,用于訪問授權(quán)、認(rèn)證、加密及會話管理。能夠支持單機與分布式session管理。 相比security,shiro更加簡單易用。 本篇文章將重點闡述Spring相關(guān)知識點,其他框架請期待下一篇 Spring知識點-詳解 一、spring基本概念
本文涉及的流程與實現(xiàn)默認(rèn)都是基于最新的5.x版本。 spring中的幾個重要概念如下: ▌1.IOC IOC,就是控制反轉(zhuǎn),如最左邊,拿公司招聘崗位來舉例: 假設(shè)一個公司有產(chǎn)品、研發(fā)、測試等崗位。如果是公司根據(jù)崗位要求,逐個安排人選,如圖中向下的箭頭,這是正向流程。如果反過來,不用公司來安排候選人,而是由第三方獵頭來匹配崗位和候選人,然后進(jìn)行推薦,如圖中向上的箭頭,這就是控制反轉(zhuǎn)。 在spring中,對象的屬性是由對象自己創(chuàng)建的,就是正向流程;如果屬性不是對象創(chuàng)建,而是由spring來自動進(jìn)行裝配,就是控制反轉(zhuǎn)。這里的DI也就是依賴注入,就是實現(xiàn)控制反轉(zhuǎn)的方式。正向流程導(dǎo)致了對象于對象之間的高耦合,IOC可以解決對象耦合的問題,有利于功能的復(fù)用,能夠使程序的結(jié)構(gòu)變得非常靈活。 ▌2.context上下文和bean spring進(jìn)行IOC實現(xiàn)時使用的有兩個概念:context上下文和bean。 如中間圖所示,所有被spring管理的、由spring創(chuàng)建的、用于依賴注入的對象,就叫做一個bean。Spring創(chuàng)建并完成依賴注入后,所有bean統(tǒng)一放在一個叫做context的上下文中進(jìn)行管理。 ▌3.AOP AOP就是面向切面編程。如右面的圖,一般程序執(zhí)行流程是從controller層調(diào)用service層、然后service層調(diào)用DAO層訪問數(shù)據(jù),最后在逐層返回結(jié)果。 這個是圖中向下箭頭所示的按程序執(zhí)行順序的縱向處理。但是,一個系統(tǒng)中會有多個不同的服務(wù),例如用戶服務(wù)、商品信息服務(wù)等等,每個服務(wù)的controller層都需要驗證參數(shù),都需要處理異常,如果按照圖中紅色的部分,對不同服務(wù)的縱向處理流程進(jìn)行橫切,在每個切面上完成通用的功能,例如身份認(rèn)證、驗證參數(shù)、處理異常等等、這樣就不用在每個服務(wù)中都寫相同的邏輯了,這就是AOP思想解決的問題。 AOP以功能進(jìn)行劃分,對服務(wù)順序執(zhí)行流程中的不同位置進(jìn)行橫切,完成各服務(wù)共同需要實現(xiàn)的功能。 二、spring框架 上圖列出了spring框架主要包含的組件。這張圖來自spring4.x的文檔。目前最新的5.x版本中右面的portlet組件已經(jīng)被廢棄掉,同時增加了用于異步響應(yīng)式處理的WebFlux組件。 并不需要對所有的組件都詳細(xì)了解,只需重點了解最常用的幾個組件實現(xiàn),以及知道每個組件用來實現(xiàn)哪一類功能。 圖中紅框是比較重要的組件,core組件是spring所有組件的核心;bean組件和context組件我剛才提到了,是實現(xiàn)IOC和依賴注入的基礎(chǔ);AOP組件用來實現(xiàn)面向切面編程;web組件包括springmvc是web服務(wù)的控制層實現(xiàn)。 三、spring中機制和實現(xiàn) ▌1.AOP AOP的實現(xiàn)是通過代理模式,在調(diào)用對象的某個方法時,執(zhí)行插入的切面邏輯。實現(xiàn)的方式有動態(tài)代理也叫運行時增強,比如jdk代理、CGLIB;靜態(tài)代理是在編譯時進(jìn)行織入或類加載時進(jìn)行織入,比如AspectJ。 關(guān)于AOP還需要了解一下對應(yīng)的Aspect、pointcut、advice等注解和具體使用方式。 ▌2.placeHolder動態(tài)替換 主要需要了解替換發(fā)生的時間,是在bean definition創(chuàng)建完成后,bean初始化之前,是通過實現(xiàn)BeanFactoryPostProcessor接口實現(xiàn)的。主要實現(xiàn)方式有PropertyPlaceholderConfigurer和PropertySourcesPlaceholderConfigurer。這兩個類實現(xiàn)邏輯不一樣,spring boot使用PropertySourcesPlaceholderConfigurer實現(xiàn)。 ▌3.事務(wù) 需要了解spring 中對事務(wù)規(guī)定的隔離類型和事務(wù)傳播類型。要知道事務(wù)的隔離級別是由具體的數(shù)據(jù)庫來實現(xiàn)的,在數(shù)據(jù)庫部分我會詳細(xì)介紹。 事務(wù)的傳播類型,可以重點了解最常用的REQUIRED和SUPPORTS類型。 ▌4.核心借口類
▌5.Scope bean的scope是指bean的作用域,默認(rèn)情況下是單例模式,這也是使用最多的一種方式;多例模式,即每次從beanFactory中獲取bean都會創(chuàng)建一個新的bean。 request、session、global-session是在web服務(wù)中使用的scope,request每次請求都創(chuàng)建一個實例,session是在一個會話周期內(nèi)保證只有一個實例。 global-session在5.x版本中已經(jīng)不在使用,同時增加了Application和Websocket兩種scope,分別保證在一個ServletContext與一個WebSocket中只創(chuàng)建一個實例。 ▌6.事件機制 spring的事件機制需要知道spring定義的五種標(biāo)準(zhǔn)事件,具體事件可見上圖,了解如何自定義事件和實現(xiàn)對應(yīng)的applicationListener來處理自定義事件。 三、spring應(yīng)用相關(guān) ▌1.常用注釋 a.類型類注釋: 類型類注釋包括controller、service等,需要重點了解 其中component和bean注解的區(qū)別如下:
b.設(shè)置類注解 重點了解@Autowire和@Qualifier以及bytype、byname等不同的自動裝配機制。 c.web類注解 主要以了解為主,關(guān)注@RequestMapping、@GetMapping、@PostMapping等路徑匹配注解,以及@PathVariable、@RequestParam 等參數(shù)獲取注解。 d.功能類注解 包括@ImportResource引用配置、@ComponentScan注解自動掃描、@Transactional事務(wù)注解等等,這里不一一介紹了。 ▌2.配置方式 需要了解配置spring的幾種方式,xml文件配置、注解配置和使用api進(jìn)行配置。 自動裝配機制需要了解按類型匹配進(jìn)行自動裝配,按bean名稱進(jìn)行自動裝配,構(gòu)造器中的自動裝配和自動檢測等主要的四種方式。 還需要了解一下list、set、map等集合類屬性的配置方式以及內(nèi)部bean的使用。 四、Spring的Context的初始化流程 圖中左上角是三種類型的context,xml配置方式的context、springboot的context和web服務(wù)的context。不論哪種context,創(chuàng)建后都會調(diào)用到AbstractApplicationContext類的refresh方法,這個方法是我們要重點分析的。 refresh方法中,操作共分13步: 第1步:對刷新進(jìn)行準(zhǔn)備,包括設(shè)置開始時間、設(shè)置激活狀態(tài)、初始化context環(huán)境中的占位符,這個動作根據(jù)子類的需求由子類來執(zhí)行,然后驗證是否缺失必要的properties; 第2步:刷新并獲得內(nèi)部的bean factory; 第3步:對bean factory進(jìn)行準(zhǔn)備工作,比如設(shè)置類加載器和后置處理器、配置不進(jìn)行自動裝配的類型、注冊默認(rèn)的環(huán)境bean; 第4步:為context的子類提供后置處理bean factory的擴展能力。如果子類想在bean定義加載完成后,開始初始化上下文之前做一些特殊邏輯,可以復(fù)寫這個方法; 第5步,執(zhí)行context中注冊的bean factory后綴處理器; 注:這里有兩種后置處理器,一種是可以注冊bean的后綴處理器,另一種是針對bean factory進(jìn)行處理的后置處理器。執(zhí)行的順序是,先按優(yōu)先級執(zhí)行可注冊bean的處理器,在按優(yōu)先級執(zhí)行針對beanfactory的處理器。 對springboot來說,這一步會進(jìn)行注解bean definition的解析。流程如右面小框中所示,由ConfigurationClassPostProcessor觸發(fā)、由ClassPathBeanDefinitionScanner解析并注冊到bean factory。 第6步:按優(yōu)先級順序在beanfactory中注冊bean的后綴處理器,bean后置處理器可以在bean初始化前、后執(zhí)行處理; 第7步:初始化消息源,消息源用來支持消息的國際化; 第8步:初始化應(yīng)用事件廣播器。事件廣播器用來向applicationListener通知各種應(yīng)用產(chǎn)生的事件,是一個標(biāo)準(zhǔn)的觀察者模式; 第9步,是留給子類的擴展步驟,用來讓特定的context子類初始化其他的bean; 第10步,把實現(xiàn)了ApplicationListener的bean注冊到事件廣播器,并對廣播器中的早期未廣播事件進(jìn)行通知; 第11步,凍結(jié)所有bean描述信息的修改,實例化非延遲加載的單例bean; 第12步,完成上下文的刷新工作,調(diào)用LifecycleProcessor的onFresh()方法以及發(fā)布ContextRefreshedEvent事件; 第13步:在finally中,執(zhí)行第十三步,重置公共的緩存,比如ReflectionUtils中的緩存、AnnotationUtils中的緩存等等; 至此,spring的context初始化完成。這里僅介紹了最主要的主流程,建議課后閱讀源碼來復(fù)習(xí)這個知識點,補全細(xì)節(jié)。 五:Spring中bean的生命周期 面試中經(jīng)常問到的bean的生命周期,先看綠色的部分,bean的創(chuàng)建過程: 第1步:調(diào)用bean的構(gòu)造方法創(chuàng)建bean; 第2步:通過反射調(diào)用setter方法進(jìn)行屬性的依賴注入; 第3步:如果實現(xiàn)BeanNameAware接口的話,會設(shè)置bean的name; 第4步:如果實現(xiàn)了BeanFactoryAware,會把bean factory設(shè)置給bean; 第5步:如果實現(xiàn)了ApplicationContextAware,會給bean設(shè)置ApplictionContext; 第6步:如果實現(xiàn)了BeanPostProcessor接口,則執(zhí)行前置處理方法; 第7步:實現(xiàn)了InitializingBean接口的話,執(zhí)行afterPropertiesSet方法; 第8步:執(zhí)行自定義的init方法; 第9步:執(zhí)行BeanPostProcessor接口的后置處理方法。 這時,就完成了bean的創(chuàng)建過程。 在使用完bean需要銷毀時,會先執(zhí)行DisposableBean接口的destroy方法,然后在執(zhí)行自定義的destroy方法。 這部分也建議閱讀源碼加深理解。 六:Spring擴展 對spring進(jìn)行定制化功能擴展時,可以選擇如下一些擴展點: ▌1.BeanFactoryPostProcessor 是beanFactory后置處理器,支持在bean factory標(biāo)準(zhǔn)初始化完成后,對bean factory進(jìn)行一些額外處理。在講context初始化流程時介紹過,這時所有的bean的描述信息已經(jīng)加載完畢,但是還沒有進(jìn)行bean初始化。例如前面提到的PropertyPlaceholderConfigurer,就是在這個擴展點上對bean屬性中的占位符進(jìn)行替換。 ▌2.BeanDefinitionRegistryPostProcessor 它擴展自BeanFactoryPostProcessor,在執(zhí)行BeanFactoryPostProcessor的功能前,提供了可以添加bean definition的能力,允許在初始化一般bean前,注冊額外的bean。例如可以在這里根據(jù)bean的scope創(chuàng)建一個新的代理bean。 ▌3.BeanPostProcessor 提供了在bean初始化之前和之后插入自定義邏輯的能力。與BeanFactoryPostProcessor的區(qū)別是處理的對象不同,BeanFactoryPostProcessor是對beanfactory進(jìn)行處理,BeanPostProcessor是對bean進(jìn)行處理。 注:上面這三個擴展點,可以通過實現(xiàn)Ordered和PriorityOrdered接口來指定執(zhí)行順序。實現(xiàn)PriorityOrdered接口的processor會先于實現(xiàn)Ordered接口的執(zhí)行。 ▌4.ApplicationContextAware 可以獲得ApplicationContext及其中的bean,當(dāng)需要在代碼中動態(tài)獲取bean時,可以通過實現(xiàn)這個接口來實現(xiàn)。 ▌5.InitializingBean 可以在bean初始化完成,所有屬性設(shè)置完成后執(zhí)行特定邏輯,例如對自動裝配對屬性進(jìn)行驗證等等。 ▌6.DisposableBean 用于在bean被銷毀前執(zhí)行特定的邏輯,例如做一些回收工作等。 ▌7.ApplicationListener 用來監(jiān)聽spring的標(biāo)準(zhǔn)應(yīng)用事件或者自定義事件。 七、springboot相關(guān)的知識點 ▌1.啟動流程 主要步驟首先要配置environment,然后準(zhǔn)備context上下文,包括執(zhí)行applicationContext的后置處理、初始化initializer、通知listener處理contextPrepared和contextLoaded事件。最后執(zhí)行refreshContext,也就是前面介紹過的AbstractApplicationContext類的refresh方法。 ▌2.配置文件 然后要知道在Spring Boot中有兩種上下文,一種是bootstrap, 另外一種是application。 bootstrap是應(yīng)用程序的父上下文,也就是說bootstrap會先于applicaton加載。bootstrap主要用于從額外的資源來加載配置信息,還可以在本地外部配置文件中解密屬性。bootstrap里面的屬性會優(yōu)先加載,默認(rèn)也不能被本地相同配置覆蓋。 ▌3.注解 @SpringBootApplication包含了@ComponentScan、@EnableAutoConfiguration、@SpringBootConfiguration三個注解 而@SpringBootConfiguration注解包含了@Configuration注解。也就是springboot的自動配置功能。 @Conditional注解就是控制自動配置的生效條件的注解,例如bean或class存在、不存在時進(jìn)行配置,當(dāng)滿足條件時進(jìn)行配置等等。 ▌4.特色模塊
|
|