最全阿里開源框架知識面試題總結

文章目錄

1.簡單講講tomcat結構,以及其類加載器流程,線程模型等?

Tomcat的核心組件就Connector和Container,一個Connector+一個Container(Engine)構成一個Service,Service就是對外提供服務的組件,有了Service組件Tomcat就能對外提供服務了,但是光有服務還不行,還需要有環境讓你提供服務才行,所以最外層的Server就是爲Service提供了生存的土壤。

img

Connector是一個連接器,主要負責接受請求並把請求交給Container,Container就是一個容器,主要裝的是具有處理請求的組件。Service主要是爲了關聯Container與Connect,只有兩個結合起來才能夠處理一個請求。Server負責管理Service集合,從圖中我們可以看到Tomcat可以提供多種服務,那麼這些Service就是由Server來管理的。具體工作包括:對外提供一個接口訪問Service,對內維護Service集合,維護Service集合包括管理Service聲明週期等等。

<!-- Server代表整個容器,是Tomcat的頂層元素。服務器默認在8005端口,shutdown命令=關閉Tomcat -->
<Server>
    <Listener />
    <GlobaNamingResources>
    </GlobaNamingResources>
    <!-- Service包含多個Connector元素,而這些Connector元素共享一個Engine元素。 -->
    <Service>
    	<!-- Connector元素代表與客戶時間交互的組件,它負責接收客戶的請求,已經向客戶響應結果,
    	配置http爲https主要是修改Connector -->
        <Connector />
        <!-- 每個Service只能有一個Engine元素,處理同一個Service中所有Connector元素接收到的客戶請求.
        Engine用來處理Connetcor收到的Http請求它匹配請求和自己的虛擬主機,並把請求轉給對應的Host來處理 -->
        <Engine>
            <Logger />
            <Realm />
            	<!-- 一個Engine包含多個host元素,每個host元素定義了一個虛擬主機,它包含一個或多個Web應用 -->
                <host>
                    <Logger />
                    <!-- 由Context接口定義.是使用最頻繁的元素,對應於一個Web App -->
                    <Context />
                </host>
        </Engine>
    </Service>
</Server>

類加載器流程:Tomcat啓動時,會創建以下4種類加載器:

1.Bootstrap引導類加載器:加載JVM啓動所需的類,以及標準擴展類(位於jar/lib/ext上)

2.System系統類加載器:加載Tomcat啓動時的類,比如bootstrap.jar通常在catalina.bat或者catalina.sh中指定。指定位置位於CATALINA_HOME/bin下。

3.Common通用類加載器:加載tomcat使用以及應用通用的一些類,位於CATALINA_HOME/lib下,比如servlet-api.jar。

4.webapp應用類加載器:每個應用在創建後,都會創建一個唯一的類加載器。該類加載器會加載位於WEB-INF/lib下的jar文件中的class和WEB-INF/classes下的class文件。

img

紅色虛線表示:應用需要到某個類時,則會按照下面的順序進行類加載。
①、使用bootstrap引導類加載器加載
②、使用system系統類加載器加載
③、使用應用類加載器在WEB-INF/classes中加載
④、使用應用類加載器在WEB-INF/lib中加載
⑤、使用common類加載器在CATALINA_HOME/lib中加載

線程模型:支持以下四種線程模型:

img

2.tomcat如何調優?涉及哪些參數?

Tomcat調優主要從四個方面考慮:

1.吞吐量;

2.Responsetime;

3.Cpuload;

4.MemoryUsage。

參數調優:

一、Tomcat啓動參數的優化:

Tomcat 的啓動參數位於tomcat的安裝目錄\bin目錄下,如果你是Linux操作系統就是catalina.sh文件,如果你是Windows操作系統那麼你需要改動的就是catalina.bat文件。

Linux系統中catalina.sh文件中添加如下參數(重要參數隨後說明):

export JAVA_OPTS="-server -Xms1400M -Xmx1400M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking 
-XX:PermSize=128M -XX:MaxPermSize=256M -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=31
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC  -XX:+CMSParallelRemarkEnabled 
-XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m  
-XX:+UseFastAccessorMethods
-XX:+UseCMSInitiatingOccupancyOnly -Djava.awt.headless=true "

Windowns系統中catalina.bat文件中添加如下參數(重要參數隨後說明):

set JAVA_OPTS=-server -Xms1400M -Xmx1400M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking 
-XX:PermSize=128M -XX:MaxPermSize=256M -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=31 
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC  -XX:+CMSParallelRemarkEnabled 
-XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m  
-XX:+UseFastAccessorMethods 
-XX:+UseCMSInitiatingOccupancyOnly -Djava.awt.headless=true

-Server(重要):只要Tomcat是運行在生產環境中,這個參數必須添加。因爲Tomcat默認是java-client模式運行,添加server後表示以真實的production的模式運行,將擁有更大、更高的併發處理能力,更快、更強的JVM垃圾回收機制,可以獲得更多的負載和吞吐量等等。

-Xms -Xmx:既JVM內存設置了,把Xms與Xmx兩個值設成一樣是最優的做法。(否則當內存=Xmx向Xms變化時,CPU高速運轉觸發垃圾回收機制,嚴重時會導致系統‘卡殼’,因此一開始我們就把這兩個設成一樣,使得Tomcat在啓動時就爲最大化參數充分利用系統的效率。)

PS:在設這個最大內存即Xmx值時請先打開一個命令行:能夠正常顯示JDK的版本信息,說明這個值能夠用。

img

-Xmn:設置年輕代大小爲512m。整個堆大小=年輕代 + 老年代 + 持久代。持久代一般固定大小爲64m,所以增大年輕代後,將會減小年老代。此值對系統性能影響較大,Sun官方推薦配置爲整個堆的3/8。

-Xss:是指設定每個線程的堆棧大小。這個就要依據程序,看一個線程大約需要佔用多少內存,可能會有多少線程同時運行等。一般不易設置超過1M,要不然容易出現out ofmemory。

二、Tomcat容器內優化:

打開tomcat安裝目錄\conf\server.xml文件。其中如下參數的默認值遠遠不夠我們使用,我們對其進行了更改,更改後的配置如下:

<Connector port="8080" protocol="HTTP/1.1"           
URIEncoding="UTF-8"  minSpareThreads="25" maxSpareThreads="75"          
enableLookups="false" disableUploadTimeout="true" connectionTimeout="20000" 
acceptCount="300"  maxThreads="300" maxProcessors="1000" minProcessors="5"
useURIValidationHack="false"    
compression="on" compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" 
redirectPort="8443" />

3.講講Spring加載流程?

ClassPathXmlApplicationContext實現beanFactory接口,是一個具體的實例化工廠。服務器啓動時,解析xml配置文件,將對應文件中每個bean的id作爲key,屬性封裝到beandefinition(是個對象)作爲value,封裝到一個ConCurrentHashMap容器A中。 同時,還有一個ConCurrentHashMap容器B存儲bean的實例化對象,默認是空。當有一個請求時,首先去B中,查找。如果B容器沒有,則訪問A容器,如果是單例,則創建之後,仍要保存到B中,下次可以使用。如果是非單例的,則直接創建,並不在B中保存副本。

spring加載流程
1.監聽器加載spring
2.加載配置文件
3.工廠生產實例化對象
4.放入ServletContext

4.Spring AOP的實現原理?

AOP(Aspect-OrientedProgramming,面向方面編程),可以說是OOP(Object-Oriented Programing,面向對象編程)的補充和完善。OOP引入封裝、繼承和多態性等概念來建立一種對象層次結構,用以模擬公共行爲的一個集合。當我們需要爲分散的對象引入公共行爲的時候,OOP則顯得無能爲力。也就是說,OOP允許你定義從上到下的關係,但並不適合定義從左到右的關係。例如日誌功能。日誌代碼往往水平地散佈在所有對象層次中,而與它所散佈到的對象的核心功能毫無關係。對於其他類型的代碼,如安全性、異常處理和透明的持續性也是如此。這種散佈在各處的無關的代碼被稱爲橫切(cross-cutting)代碼,在OOP設計中,它導致了大量代碼的重複,而不利於各個模塊的重用。

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

使用“橫切”技術,AOP把軟件系統分爲兩個部分:核心關注點和橫切關注點。業務處理的主要流程是核心關注點,與之關係不大的部分是橫切關注點。橫切關注點的一個特點是,他們經常發生在覈心關注點的多處,而各處都基本相似。比如權限認證、日誌、事務處理。Aop 的作用在於分離系統中的各種關注點,將核心關注點和橫切關注點分離開來。

實現AOP的技術,主要分爲兩大類:

一、採用動態代理技術,利用截取消息的方式,對該消息進行裝飾,以取代原有對象行爲的執行;

二、採用靜態織入的方式,引入特定的語法創建“方面”,從而使得編譯器可以在編譯期間織入有關“方面”的代碼。

AOP使用場景:

Authentication 權限

Caching 緩存

Context passing 內容傳遞

Error handling 錯誤處理

Lazy loading 懶加載

Debugging 調試

logging, tracing, profiling and monitoring 記錄跟蹤 優化 校準

Performance optimization 性能優化

Persistence  持久化

Resource pooling 資源池

Synchronization 同步

Transactions 事務

如何使用Spring AOP:

可以通過配置文件或者編程的方式來使用Spring AOP。

配置可以通過xml文件來進行,大概有四種方式:

  1. 配置ProxyFactoryBean,顯式地設置advisors, advice, target等。

  2. 配置AutoProxyCreator,這種方式下,還是如以前一樣使用定義的bean,但是從容器中獲得的其實已經是代理對象。

  3. 通過aop:config來配置。

  4. 通過<aop: aspectj-autoproxy>來配置,使用AspectJ的註解來標識通知及切入點。

也可以直接使用ProxyFactory來以編程的方式使用Spring AOP,通過ProxyFactory提供的方法可以設置target對象, advisor等相關配置,最終通過 getProxy()方法來獲取代理對象。

5.講講Spring事務的傳播屬性?

一、事務的定義
事務是指多個操作單元組成的合集,多個單元操作是整體不可分割的,要麼都操作不成功,要麼都成功。其必須遵循四個原則(ACID)。

1.原子性(Atomicity):即事務是不可分割的最小工作單元,事務內的操作要麼全做,要麼全不做。

2.一致性(Consistency):在事務執行前數據庫的數據處於正確的狀態,而事務執行完成後數據庫的數據還是應該處於正確的狀態,即數據完整性約束沒有被破壞;如銀行轉帳,A轉帳給B,必須保證A的錢一定轉給B,一定不會出現A的錢轉了但B沒收到,否則數據庫的數據就處於不一致(不正確)的狀態。

3.隔離性(Isolation):併發事務執行之間互不影響,在一個事務內部的操作對其他事務是不產生影響,這需要事務隔離級別來指定隔離性。

4.持久性(Durability):事務一旦執行成功,它對數據庫的數據的改變必須是永久的,不會因比如遇到系統故障或斷電造成數據不一致或丟失。

img

據底層所使用的不同的持久化 API 或框架,使用如下:

1.DataSourceTransactionManager:適用於使用JDBC和iBatis進行數據持久化操作的情況,在定義時需要提供底層的數據源作爲其屬性,也就是 DataSource。

2.HibernateTransactionManager:適用於使用Hibernate進行數據持久化操作的情況,與 HibernateTransactionManager 對應的是 SessionFactory。

3.JpaTransactionManager:適用於使用JPA進行數據持久化操作的情況,與 JpaTransactionManager 對應的是 EntityManagerFactory。

二、事務的分類

數據庫分爲本地事務跟全局事務:

1.本地事務:普通事務,獨立一個數據庫,能保證在該數據庫上操作的ACID。

2.分佈式事務:涉及兩個或多個數據庫源的事務,即跨越多臺同類或異類數據庫的事務(由每臺數據庫的本地事務組成的),分佈式事務旨在保證這些本地事務的所有操作的ACID,使事務可以跨越多臺數據庫。

Java事務類型分爲JDBC事務跟JTA事務:

1.JDBC事務:即爲上面說的數據庫事務中的本地事務,通過connection對象控制管理。

2.JTA事務:JTA指Java事務API(Java Transaction API),是Java EE數據庫事務規範,JTA只提供了事務管理接口,由應用程序服務器廠商(如WebSphere Application Server)提供實現,JTA事務比JDBC更強大,支持分佈式事務。

按是否通過編程分爲聲明式事務和編程式事務:

1.聲明式事務:通過XML配置或者註解實現。

2.編程式事務:通過編程代碼在業務邏輯時需要時自行實現,粒度更小。

三、事務的基本原理

Spring事務的本質其實就是數據庫對事務的支持,沒有數據庫的事務支持,spring是無法提供事務功能的。對於純JDBC操作數據庫,想要用到事務,可以按照以下步驟進行:

  1. 獲取連接 Connection con = DriverManager.getConnection()
  2. 開啓事務con.setAutoCommit(true/false);
  3. 執行CRUD(CRUD是指在做計算處理時的增加(Create)、讀取查詢(Retrieve)、更新(Update)和刪除(Delete)幾個單詞的首字母簡寫)
  4. 提交事務/回滾事務 con.commit() / con.rollback();
  5. 關閉連接 conn.close();

使用Spring的事務管理功能後,我們可以不再寫步驟 2 和 4 的代碼,而是由Spirng 自動完成。
那麼Spring是如何在我們書寫的 CRUD 之前和之後開啓事務和關閉事務的呢?解決這個問題,也就可以從整體上理解Spring的事務管理實現原理了。下面簡單地介紹下,註解方式爲例子:

1.配置文件開啓註解驅動,在相關的類和方法上通過註解@Transactional標識。

2.spring 在啓動的時候會去解析生成相關的bean,這時候會查看擁有相關注解的類和方法,並且爲這些類和方法生成代理,並根據@Transaction的相關參數進行相關配置注入,這樣就在代理中爲我們把相關的事務處理掉了(開啓正常提交事務,異常回滾事務)。

3.真正的數據庫層的事務提交和回滾是通過binlog或者redo log實現的。

四、Spring事務的傳播屬性

所謂spring事務的傳播屬性,就是定義在存在多個事務同時存在的時候,spring應該如何處理這些事務的行爲。這些屬性在TransactionDefinition中定義,具體常量的解釋見下表:

常量名稱 常量解釋
PROPAGATION_REQUIRED 支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇,也是 Spring 默認的事務的傳播。
PROPAGATION_REQUIRES_NEW 新建事務,如果當前存在事務,把當前事務掛起。新建的事務將和被掛起的事務沒有任何關係,是兩個獨立的事務,外層事務失敗回滾之後,不能回滾內層事務執行的結果,內層事務失敗拋出異常,外層事務捕獲,也可以不處理回滾操作
PROPAGATION_SUPPORTS 支持當前事務,如果當前沒有事務,就以非事務方式執行。
PROPAGATION_MANDATORY 支持當前事務,如果當前沒有事務,就拋出異常。
PROPAGATION_NOT_SUPPORTED 以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
PROPAGATION_NEVER 以非事務方式執行,如果當前存在事務,則拋出異常。
PROPAGATION_NESTED 如果一個活動的事務存在,則運行在一個嵌套的事務中。如果沒有活動事務,則按REQUIRED屬性執行。它使用了一個單獨的事務,這個事務擁有多個可以回滾的保存點。內部事務的回滾不會對外部事務造成影響。它只對DataSourceTransactionManager事務管理器起效。

6.Spring如何管理事務的?

Spring事務管理主要包括3個接口,Spring的事務主要是由他們三個共同完成的。

1)PlatformTransactionManager:事務管理器–主要用於平臺相關事務的管理

主要有三個方法:

commit 事務提交;

rollback 事務回滾;

getTransaction 獲取事務狀態。

2)TransactionDefinition:事務定義信息–用來定義事務相關的屬性,給事務管理器PlatformTransactionManager使用

這個接口有下面四個主要方法:

getIsolationLevel:獲取隔離級別;

getPropagationBehavior:獲取傳播行爲;

getTimeout:獲取超時時間;

isReadOnly:是否只讀(保存、更新、刪除時屬性變爲false–可讀寫,查詢時爲true–只讀)。

事務管理器能夠根據這個返回值進行優化,這些事務的配置信息,都可以通過配置文件進行配置。

3)TransactionStatus:事務具體運行狀態–事務管理過程中,每個時間點事務的狀態信息。

例如它的幾個方法:

hasSavepoint():返回這個事務內部是否包含一個保存點;

isCompleted():返回該事務是否已完成,也就是說,是否已經提交或回滾;

isNewTransaction():判斷當前事務是否是一個新事務。

聲明式事務的優缺點:

優點

不需要在業務邏輯代碼中編寫事務相關代碼,只需要在配置文件配置或使用註解(@Transaction),這種方式沒有侵入性。

缺點

聲明式事務的最細粒度作用於方法上,如果像代碼塊也有事務需求,只能變通下,將代碼塊變爲方法。

7.Spring怎麼配置事務(具體說出一些關鍵的xml 元素)?

配置事務的方法有兩種:

1)基於XML的事務配置;

2)基於註解方式的事務配置。

鋪墊:

1)spring的事務管理是通過Aop的方式來實現;

*2)*聲明式事務是spring對事務管理的最常用的方式,因爲這種方式對代碼的影響最小,因此也就符合非侵入式的輕量級的容器的概念。

<tx:advice id=“bankAdvice” transaction-manager=“transactionManager”>
<tx:attributes>
<tx:method name=“transfer” propagation=“REQUIRED”/>
</tx:attributes>
</tx:advice>

<aop:config>
<aop:pointcut id=“bankPointcut” expression=“execution(* *.transfer(…))”/>
<aop:advisor advice-ref=“bankAdvice” pointcut-ref=“bankPointcut”/>
</aop:config>

8.說說你對Spring的理解,非單例注入的原理?它的生命週期?循環注入的原理,aop的實現原理,說說aop中的幾個術語,它們是怎麼相互工作的?

Spring的理解:

1)Spring是一個開源框架,主要是爲簡化企業級應用開發而生。可以實現EJB可以實現的功能,Spring是一個IOC和AOP容器框架。

控制反轉(IOC):Spring容器使用了工廠模式爲我們創建了所需要的對象,我們使用時不需要自己去創建,直接調用Spring爲我們提供的對象即可,這就是控制反轉的思想。

依賴注入(DI):Spring使用Java Bean對象的Set方法或者帶參數的構造方法爲我們在創建所需對象時將其屬性自動設置所需要的值的過程就是依賴注入的基本思想。

面向切面編程(AOP):在面向對象編程(OOP)思想中,我們將事物縱向抽象成一個個的對象。而在面向切面編程中,我們將一個個對象某些類似的方面橫向抽象成一個切面,對這個切面進行一些如權限驗證,事物管理,記錄日誌等公用操作處理的過程就是面向切面編程的思想。

2)在Spring中,所有管理的都是JavaBean對象,而BeanFactory和ApplicationContext就是Spring框架的那個IOC容器,現在一般使用ApplicationContext,其不但包括了BeanFactory的作用,同時還進行了更多的擴展。

非單例注入原理:在大部分情況下,容器中的bean都是singleton類型的。如果一個singleton bean要引用另外一個singleton bean或者一個非singleton bean要引用另外一個非singleton,通常情況下將一個bean定義爲另一個bean的property值就可以了。不過對於具有不同生命週期的bean來說這樣做就會有問題了,比如在調用一個singleton類型bean A的某個方法時,需要引用另一個非singleton(prototype)類型的bean B,對於bean A來說,容器只會創建一次,這樣就沒法在需要的時候每次讓容器爲bean A提供一個新的的bean B實例。

9.SpringMVC中DispatcherServlet初始化過程?

//初始化多媒體解析器

initMultipartResolver(context);

//初始化位置解析器

initLocaleResolver(context);

//初始化主題解析器

initThemeResolver(context);

//初始化HandlerMappings

initHandlerMappings(context);

//初始化HandlerAdapters

initHandlerAdapters(context);

//初始化異常解析器

initHandlerExceptionResolvers(context);

//初始化請求到視圖名轉換器

initRequestToViewNameTranslator(context);

//初始化視圖解析器

initViewResolvers(context);

//初始化FlashMapManager

initFlashMapManager(context);

在使用SpringMVC框架,會在web.xml文件配置一個DispatcherServlet,這正是web容器開始初始化,同時會在建立自己的上下文來持有SpringMVC的bean對象。

先從DispatcherServlet入手,從名字來看,它是一個Servlet。它的定義如下:

public class DispatcherServlet extends FrameworkServlet { }

它是繼承FrameworkServlet,來看一下整個的繼承關係。

從繼承關係來看,DispatcherServlet繼承FrameworkServlet和HttpServletBean而繼承HttpServlet,通過使用Servlet API來對HTTP請求進行響應,成爲SpringMVC的前端處理器。

注:作爲Servlet,DispatcherServlet的啓動和Servlet的啓動相關聯的。在Servlet初始化過程中,Servlet的init方法會被調用,以進行初始化,然而DispatcherServlet的基類,所以從HttpServletBean中的初始化過程開始。

DispatcherServlet的工作分爲2部分,一部分是初始化(也就是圖的上半部分),有initServletBean()啓動,通過initWebApplicationContext()方法最終調用DispatcherServlet中的initStrategies()方法。另一部分(也就是圖的下半部分),是對HTTP請求進行響應,作爲Servlet,Web容器會調用Servlet的doGet()和doPost()方法,在經過FrameworkServlet的processRequest()簡單處理後,會調用DispatcherServlet的doService方法,在這個方法調用中封裝了doDispatch(),繼續調用processDispatchResult方法返回調用信息。

10.使用Spring框架的好處是什麼? Spring由哪些模塊組成?

輕量:Spring 是輕量的,基本的版本大約2MB。

控制反轉(IOC):Spring通過控制反轉實現了鬆散耦合,對象們給出它們的依賴,而不是創建或查找依賴的對象們。

面向切面的編程(AOP):Spring支持面向切面的編程,並且把應用業務邏輯和系統服務分開。

容器:Spring包含並管理應用中對象的生命週期和配置。

MVC框架:Spring的WEB框架是個精心設計的框架,是Web框架的一個很好的替代品。

事務管理:Spring 提供一個持續的事務管理接口,可以擴展到上至本地事務下至全局事務(JTA)。

異常處理:Spring提供方便的API把具體技術相關的異常(比如由JDBC,Hibernate or JDO拋出的)轉化爲一致的unchecked異常。

Spring 框架的基本模塊:

Core module

這是基本的Spring模塊,提供spring框架的基礎功能,BeanFactory是任何以spring爲基礎的應用的核心。Spring 框架建立在此模塊之上,它使Spring成爲一個容器。

Bean module

Bean 工廠是工廠模式的一個實現,提供了控制反轉功能,用來把應用的配置和依賴從正真的應用代碼中分離。最常用的BeanFactory 實現是XmlBeanFactory 類。

XmlBeanFactory 最常用的就是org.springframework.beans.factory.xml.XmlBeanFactory ,它根據XML文件中的定義加載beans。該容器從XML 文件讀取配置元數據並用它去創建一個完全配置的系統或應用

Context module

Expression Language module

JDBC module

Spring 通過提供ORM模塊,支持我們在直接JDBC之上使用一個對象/關係映射映射(ORM)工具,Spring 支持集成主流的ORM框架,如Hiberate,JDO和 iBATIS SQL Maps。Spring的事務管理同樣支持以上所有ORM框架及JDBC。

ORM module

OXM module

Java Messaging Service(JMS) module

Transaction module

Web module

Spring的WEB模塊是構建在application context 模塊基礎之上,提供一個適合web應用的上下文。這個模塊也包括支持多種面向web的任務,如透明地處理多個文件上傳請求和程序級請求參數的綁定到你的業務對象。它也有對Jakarta Struts的支持。

Web-Servlet module

Web-Struts module

Web-Portlet module

11.SpringMVC用到的註解?作用是什麼?原理?

SpringMVC核心原理

1、用戶發送請求給服務器。url:user

2、服務器收到請求。發現Dispatchservlet可以處理。於是調用DispatchServlet。

3、DispatchServlet內部,通過HandleMapping檢查這個url有沒有對應的Controller。如果有,則調用Controller。

4、Control開始執行

5、Controller執行完畢後,如果返回字符串,則ViewResolver將字符串轉化成相應的視圖對象;如果返回ModelAndView對象, 該對象本身就包含了視圖對象信息。

6、DispatchServlet將執視圖對象中的數據,輸出給服務器。

7、服務器將數據輸出給客戶端。

相關jar包含義

org.springframework.aop-3.0.3.RELEASE.jar      ----->  spring的aop面向切面編程

org.springframework.asm-3.0.3.RELEASE.jar      ----->  spring獨立的asm字節碼生成程序

org.springframework.beans-3.0.3.RELEASE.jar     ----->  IOC的基礎實現

org.springframework.context-3.0.3.RELEASE.jar    ----->   IOC基礎上的擴展服務

org.springframework.core-3.0.3.RELEASE.jar     ----->  spring的核心包

org.springframework.expression-3.0.3.RELEASE.jar  ----->  spring的表達式語言

org.springframework.web-3.0.3.RELEASE.jar     ------>  web工具包

org.springframework.web.servlet-3.0.3.RELEASE.jar  ------>  mvc工具包

在SpringMVC中,控制器Controller負責處理由DispatcherServlet分發的請求,它把用戶請求的數據經過業務處理層處理之後封裝成一個Model ,然後再把該Model返回給對應的View進行展示。

在SpringMVC中提供了一個非常簡便的定義Controller的方法,你無需繼承特定的類或實現特定的接口,只需使用@Controller標記一個類是Controller,然後使用@RequestMapping和@RequestParam等一些註解用以定義URL請求和Controller方法之間的映射,這樣的Controller就能被外界訪問到。此外Controller不會直接依賴於HttpServletRequest和HttpServletResponse等HttpServlet對象,它們可以通過Controller的方法參數靈活的獲取到。

@Controller:

該註解表明該類扮演控制器的角色,Spring不需要你繼承任何其他控制器基類或引用Servlet API。

@RequestMapping:

該註解是用來映射一個URL到一個類或一個特定的方處理法上。

12.springboot啓動機制?

我們知道,如果不需要特殊的配置,只需要在main方法裏調用SpringApplicatio.run()方法即可啓動Spring Boot應用。

public static void main(String[] args) throws Exception {    SpringApplication.run(Application.class, args);
}

SpringApplication啓動流程:

img

第一步、初始化監聽器

這裏會初始化Spring Boot自帶的監聽器,以及添加到SpringApplication的自定義監聽器。

第二步、發佈ApplicationStartedEvent事件

到這一步,SpringBoot會發佈一個ApplicationStartedEvent事件。如果你想在這個時候執行一些代碼可以通過實現ApplicationListener接口實現。

第三步、裝配參數和環境

在這一步,首先會初始化參數,然後裝配環境,確定是web環境還是非web環境。

第四步、發佈ApplicationEnvironmentPreparedEvent事件

準確的說,這個應該屬於第三步,在裝配完環境後,就觸發ApplicationEnvironmentPreparedEvent事件。如果想在這個時候執行一些代碼,可以訂閱這個事件的監聽器,方法同第二步。

第五步,打印Banner

看過Spring Boot實例教程 - 自定義Banner的同學會很熟悉,啓動的Banner就是在這一步打印出來的。

第六步,創建ApplicationContext

這裏會根據是否是web環境,來決定創建什麼類型的ApplicationContext,ApplicationContext不要多說了吧,不知道ApplicationContext是啥的同學,出門左轉補下Spring基礎知識吧。

第七步,裝配Context

這裏會設置Context的環境變量、註冊Initializers、beanNameGenerator等。

第八步,發佈ApplicationPreparedEvent事件

這裏放在第七步會更準確,因爲這個是在裝配Context的時候發佈的。

值得注意的是:這裏是假的,假的,假的,源碼中是空的,並沒有真正發佈ApplicationPreparedEvent事件。不知道作者這麼想的???

第九步,註冊、加載等

註冊springApplicationArguments、springBootBanner,加載資源等。

第十步,發佈ApplicationPreparedEvent事件

注意,到這裏纔是真正發佈了ApplicationPreparedEvent事件。這裏和第八步好讓人誤解。

第十一步,refreshContext

裝配context beanfactory等非常重要的核心組件。

第十二步,afterRefreshContext

這裏會調用自定義的Runners,不知道Runners是什麼的同學,請參考Spring Boot官方文檔 - SpringApplication

第十三步,發佈ApplicationReadyEvent事件

最後一步,發佈ApplicationReadyEvent事件,啓動完畢,表示服務已經可以開始正常提供服務了。通常我們這裏會監聽這個事件來打印一些監控性質的日誌,表示應用正常啓動了。添加方法同第二步。

注意:如果啓動失敗,這一步會發布ApplicationFailedEvent事件。

到這裏,Spring Boot啓動的一些關鍵動作就介紹完了。

13.什麼是Spring beans?

Spring beans是那些形成Spring應用的主幹的java對象。它們被Spring IOC容器初始化,裝配,和管理。這些beans通過容器中配置的元數據創建。比如,以XML文件中 的形式定義。

Spring 框架定義的beans都是單件beans。在bean tag中有個屬性”singleton”,如果它被賦爲true,bean就是單件,否則就是一個 prototype bean。默認是true,所以所有在Spring框架中的beans缺省都是單件。

14.你怎樣定義類的作用域?

當定義一個在Spring裏,我們還能給這個bean聲明一個作用域。它可以通過bean定義中的scope屬性來定義。如,當Spring要在需要的時候每次生產一個新的bean實例,bean的scope屬性被指定爲prototype。另一方面,一個bean每次使用的時候必須返回同一個實例,這個bean的scope 屬性 必須設爲 singleton。

15.如何給Spring容器提供配置元數據?

這裏有三種重要的方法給Spring 容器提供配置元數據。

XML配置文件。

基於註解的配置。

基於Java的配置。

15.解釋Spring支持的幾種bean的作用域?

Spring框架支持以下五種bean的作用域:

singleton : bean在每個Spring ioc容器中只有一個實例。

prototype:一個bean的定義可以有多個實例。

request:每次http請求都會創建一個bean,該作用域僅在基於web的Spring ApplicationContext情形下有效。

session:在一個HTTP Session中,一個bean定義對應一個實例。該作用域僅在基於web的Spring ApplicationContext情形下有效。

global-session:在一個全局的HTTP Session中,一個bean定義對應一個實例。該作用域僅在基於web的Spring ApplicationContext情形下有效。

缺省的Spring bean 的作用域是Singleton。

16.Spring框架中的單例bean是線程安全的嗎?

不,Spring框架中的單例bean不是線程安全的。

Spring框架並沒有對單例bean進行任何多線程的封裝處理。關於單例bean的線程安全和併發問題需要開發者自行去搞定。但實際上,大部分的Spring bean並沒有可變的狀態(比如Service類和DAO類),所以在某種程度上說Spring的單例bean是線程安全的。如果你的bean有多種狀態的話(比如 View Model 對象),就需要自行保證線程安全。

最淺顯的解決辦法就是將多態bean的作用域由“singleton”變更爲“prototype”。

17.解釋Spring框架中bean的生命週期?

Spring容器從XML文件中讀取bean的定義,並實例化bean。

Spring根據bean的定義填充所有的屬性。

如果bean實現了BeanNameAware接口,Spring傳遞bean的ID到setBeanName方法。

如果Bean實現了BeanFactoryAware接口, Spring傳遞beanfactory給setBeanFactory方法。

如果有任何與bean相關聯的BeanPostProcessors,Spring會在postProcesserBeforeInitialization()方法內調用它們。

如果bean實現IntializingBean了,調用它的afterPropertySet方法,如果bean聲明瞭初始化方法,調用此初始化方法。

如果有BeanPostProcessors 和bean 關聯,這些bean的postProcessAfterInitialization() 方法將被調用。

如果bean實現了DisposableBean,它將調用destroy()方法。

18.哪些是重要的bean生命週期方法? 你能重載它們嗎?

有兩個重要的bean 生命週期方法,第一個是setup , 它是在容器加載bean的時候被調用。第二個方法是 teardown它是在容器卸載類的時候被調用。

The bean標籤有兩個重要的屬性(init-method和destroy-method)。用它們你可以自己定製初始化和註銷方法。它們也有相應的註解(@PostConstruct和@PreDestroy)。

19.什麼是Spring的內部bean?

當一個bean僅被用作另一個bean的屬性時,它能被聲明爲一個內部bean,爲了定義inner bean,在Spring 的基於XML的配置元數據中,可以在或元素內使用元素,內部bean通常是匿名的,它們的Scope一般是prototype。

20.在Spring中如何注入一個java集合?

Spring提供以下幾種集合的配置元素:

類型用於注入一列值,允許有相同的值。

類型用於注入一組值,不允許有相同的值。

類型用於注入一組鍵值對,鍵和值都可以爲任意類型。

類型用於注入一組鍵值對,鍵和值都只能爲String類型。

package com.LHB.collection;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class Department {
     private String name;
     private String[] empName;
     private List<Employee> empList;    //List集合
     private Set<Employee> empSets;     //Set集合
     private Map<String,Employee> empMap; //map集合
     private Properties pp;    //Properties的使用
}
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:context="http://www.springframework.org/schema/context"
 5        xsi:schemaLocation="http://www.springframework.org/schema/beans
 6                 http://www.springframework.org/schema/beans/spring-beans.xsd
 7                 http://www.springframework.org/schema/context
 8                 http://www.springframework.org/schema/context/spring-context.xsd">
 9                 
10    <bean id="department" class="com.LHB.collection.Department">
11        <property name="name" value="財務部門" />
12        <!-- 給數組注入值 -->
13        <property name="empName">
14            <list>
15                <value>小米</value>
16                <value>小明</value>
17                <value>小四</value>
18            </list>
19        </property>
20        
21        <!-- 給list注入值 可以有相同的多個對象  -->
22        <property name="empList">
23            <list>
24                <ref bean="emp1" />
25                <ref bean="emp2"/>
26            </list>
27        </property>
28        <!-- 給set注入值 不能有相同的對象 -->
29        <property name="empSets">
30            <set>
31                <ref bean="emp1" />
32                <ref bean="emp2"/>
33            </set>
34        </property>
35        
36        <!-- 給map注入值 只要map中的key值不一樣就可以裝配value -->
37        <property name="empMap">
38            <map>
39                <entry key="1" value-ref="emp1" />
40                <entry key="2" value-ref="emp2" />
41            </map>
42        </property>
43        
44        <!-- 給屬性集合配置 -->
45        <property name="pp">
46            <props>
47                <prop key="pp1">hello</prop>
48                <prop key="pp2">world</prop>
49            </props>
50        </property>
51    </bean>

21.什麼是bean裝配?什麼是bean的自動裝配?解釋不同方式的自動裝配?

裝配,或bean裝配是指在Spring容器中把bean組裝到一起,前提是容器需要知道bean的依賴關係,如何通過依賴注入來把它們裝配到一起。

Spring容器能夠自動裝配相互合作的bean,這意味着容器不需要和配置,能通過Bean工廠自動處理bean之間的協作。

有五種自動裝配的方式,可以用來指導Spring容器用自動裝配方式來進行依賴注入:

**no:**默認的方式是不進行自動裝配,通過顯式設置ref 屬性來進行裝配。

**byName:**通過參數名自動裝配,Spring容器在配置文件中發現bean的autowire屬性被設置成byname,之後容器試圖匹配、裝配和該bean的屬性具有相同名字的bean。

**byType:**通過參數類型自動裝配,Spring容器在配置文件中發現bean的autowire屬性被設置成byType,之後容器試圖匹配、裝配和該bean的屬性具有相同類型的bean。如果有多個bean符合條件,則拋出錯誤。

**constructor:**這個方式類似於byType, 但是要提供給構造器參數,如果沒有確定的帶參數的構造器參數類型,將會拋出異常。

**autodetect:**首先嚐試使用constructor來自動裝配,如果無法工作,則使用byType方式。

22.自動裝配有哪些侷限性?

自動裝配的侷限性是:

重寫:你仍需用 和 配置來定義依賴,意味着總要重寫自動裝配。

基本數據類型:你不能自動裝配簡單的屬性,如基本數據類型,String字符串,和類。

模糊特性:自動裝配不如顯式裝配精確,如果有可能,建議使用顯式裝配。

23.你可以在Spring中注入一個null和一個空字符串嗎?

public class Boweifeng {
 
    private String email;
 
    public String getEmail() {
 
        return email;
 
    }
 
    public void setEmail(String email) {
 
        this.email = email;
 
    }
 
}

方式一注入:

<bean class="Boweifeng">
 
<property name="email"><value/></property>
 
</bean>

方式二注入:

<bean class="Boweifeng">
 
<property name="email" value=””/></property>
 
</bean>

方式三注入:

<bean class="Boweifeng">
 
<property name="email" value=”null”/></property>
 
</bean>

方式四注入:

<bean class="Boweifeng">
 
<property name="email" /><null/></property>
 
</bean>

方式一和二相當於執行了Java代碼: Boweifeng.setEmail(""),設置的是空字符串。

方式三相當於執行了Java代碼: Boweifeng.setEmail(“null”),設置的是”null”字符串。

方式四的配置等同於Java代碼:Boweifeng.setEmail(null)。用於處理null值。

24.什麼是基於Java的Spring註解配置? 給一些註解的例子?

基於Java的配置,允許你在少量的Java註解的幫助下,進行你的大部分Spring配置而非通過XML文件。

以@Configuration註解爲例,它用來標記類可以當做一個bean的定義,被Spring IOC容器使用。另一個例子是@Bean註解,它

表示此方法將要返回一個對象,作爲一個bean註冊進Spring應用上下文。

25.什麼是基於註解的容器配置?

相對於XML文件,註解型的配置依賴於通過字節碼元數據裝配組件,而非尖括號的聲明。

開發者通過在相應的類,方法或屬性上使用註解的方式,直接對組件類中進行配置,而不是使用xml表述bean的裝配關係。

26.DispatcherServlet?

Spring的MVC框架是圍繞DispatcherServlet來設計的,它用來處理所有的HTTP請求和響應。

27.什麼是Spring MVC框架的控制器?

控制器提供一個訪問應用程序的行爲,此行爲通常通過服務接口實現。控制器解析用戶輸入並將其轉換爲一個由視圖呈現給用戶的模型。Spring用一個非常抽象的方式實現了一個控制層,允許用戶創建多種用途的控制器。

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