爆肝30天,肝出來史上最透徹Spring原理和27道高頻面試題總結

語言: CN / TW / HK

在閱讀面試題之前,小夥伴們可以先看看我之前釋出的系列文章,Spring核心原理包括原始碼分析和用30個類手寫。面試刷題固然很重要,但是知其然知其所以然更重要。

1 Spring環境預熱篇

標題 備註
Tom彈架構:Spring 5系統架構 2021/12/01已更新
Tom彈架構:Spring版本命名規則 2021/12/02已更新
Tom彈架構:基於Gradle的Spring原始碼下載及構建技巧 2021/12/03已更新

2 30個類手寫實戰篇

標題 備註
Tom彈架構:用300行程式碼手寫1個Spring框架,麻雀雖小五臟俱全 2021/12/04已更新
Tom彈架構:30個類手寫Spring核心原理之環境準備(1) 2021/12/09已更新
Tom彈架構:30個類手寫Spring核心原理之Ioc頂層架構設計(2) 2021/12/10已更新
Tom彈架構:30個類手寫Spring核心原理之依賴注入功能(3) 2021/12/12已更新
Tom彈架構:30個類手寫Spring核心原理之MVC對映功能(4) 2021/12/13已更新
Tom彈架構:30個類手寫Spring核心原理之AOP程式碼織入(5) 2021/12/14已更新
Tom彈架構:30個類手寫Spring核心原理之自定義ORM(上)(6) 2021/12/16已更新
Tom彈架構:30個類手寫Spring核心原理之自定義ORM(下)(7) 2021/12/17已更新
Tom彈架構:30個類手寫Spring核心原理之動態資料來源切換(8) 2021/12/21已更新

3 Spring核心原理篇

標題 備註
Tom彈架構:Spring核心原理分析之MVC九大元件(1) 2021/12/22已更新
Tom彈架構:Spring核心原理之IoC容器初體驗(2) 2021/12/05已更新
Tom彈架構:Spring核心原理之 IoC容器中那些鮮為人知的細節(3) 2021/12/25已更新
Tom彈架構:大廠高頻面試題Spring Bean生命週期最詳解 2021/12/06已更新
Tom彈架構:一張圖徹底搞懂Spring迴圈依賴 2021/12/07已更新

4 經典高頻面試題

4.1 什麼是Spring框架,Spring框架有哪些主要模組

Spring框架是一個為Java應用程式開發提供綜合、廣泛的基礎性支援的Java平臺。Spring幫助開發者解決了開發中基礎性的問題,使得開發人員可以專注於應用程式的開發。Spring框架本身也是按照設計模式精心打造的,這使得我們可以在開發環境中安心地整合Spring框架,不必擔心Spring是如何在後臺工作的。主要模組內容介紹可以參考之前章節的介紹。

4.2 使用Spring框架能帶來哪些好處

下面列舉了一些使用Spring框架帶來的主要好處。

(1)Dependency Injection(DI)使得構造器和JavaBean properties檔案中的依賴關係一目瞭然。

(2)與EJB容器相比較,IoC容器更加趨向於輕量級。這樣一來使用IoC容器在有限的記憶體和CPU資源的情況下進行應用程式的開發和釋出就變得十分有利。

(3)Spring並沒有閉門造車,Spring利用了已有的技術,比如ORM框架、logging框架、J2EE、Quartz和JDK Timer,以及其他檢視技術。

(4)Spring框架是按照模組的形式來組織的。由包和類的編號就可以看出其所屬的模組,開發者只需選用需要的模組即可。

(5)要測試一個用Spring開發的應用程式十分簡單,因為測試相關的環境程式碼都已經囊括在框架中了。更加簡單的是,利用JavaBean形式的POJO類,可以很方便地利用依賴注入來寫入測試資料。

(6)Spring的Web框架也是一個精心設計的Web MVC框架,為開發者在Web框架的選擇上提供了一個除主流框架(比如Struts)和過度設計的、不流行Web框架以外的選擇。

(7)Spring提供了一個便捷的事務管理介面,適用於小型的本地事務處理(比如在單DB的環境下)和複雜的共同事務處理(比如利用JTA的複雜DB環境)。

4.3 什麼是控制反轉(IoC),什麼是依賴注入

(1)控制反轉是應用於軟體工程領域的,在執行時被裝配器物件用來繫結耦合物件的一種程式設計技巧,物件之間的耦合關係在編譯時通常是未知的。在傳統的程式設計方式中,業務邏輯的流程是由應用程式中早已被設定好關聯關係的物件來決定的。在使用控制反轉的情況下,業務邏輯的流程是由物件關係圖來決定的,該物件關係圖由裝配器負責例項化,這種實現方式還可以將物件之間的關聯關係的定義抽象化。繫結的過程是通過“依賴注入”實現的。

(2)控制反轉是一種以給予應用程式中目標元件更多控制為目的設計正規化,並在實際工作中起到了有效的作用。

(3)依賴注入是在編譯階段尚未知所需的功能是來自哪個的類的情況下,將其他物件所依賴的功能物件例項化的模式。這就需要一種機制來啟用相應的元件以提供特定的功能,所以依賴注入是控制反轉的基礎。否則如果在元件不受框架控制的情況下,框架又怎麼知道要建立哪個元件呢?

4.4 在Java中依賴注入有哪些方式

(1)構造器注入。

(2)Setter方法注入。

(3)介面注入。

4.5 BeanFactory和ApplicationContext有什麼區別

BeanFactory 可以理解為含有Bean集合的工廠類。BeanFactory 包含了Bean的定義,以便在接收到客戶端請求時將對應的Bean例項化。 BeanFactory還能在例項化物件時生成協作類之間的關係。此舉將Bean自身從Bean客戶端的配置中解放出來。BeanFactory還包含Bean生命週期的控制,呼叫客戶端的初始化方法(Initialization Method)和銷燬方法(Destruction Method)。 從表面上看,ApplicationContext如同BeanFactory一樣具有Bean定義、Bean關聯關係的設定及根據請求分發Bean的功能。但ApplicationContext在此基礎上還提供了其他功能。

(1)提供了支援國際化的文字訊息。

(2)統一的資原始檔讀取方式。

(3)已在監聽器中註冊的Bean的事件。

以下是三種較常見的 ApplicationContext 實現方式。

(1)ClassPathXmlApplicationContext:從ClassPath的XML配置檔案中讀取上下文,並生成上下文定義。應用程式上下文從程式環境變數中取得。 ApplicationContext context = new ClassPathXmlApplicationContext(“application.xml”);

(2)FileSystemXmlApplicationContext :由檔案系統中的XML配置檔案讀取上下文。 ApplicationContext context = new FileSystemXmlApplicationContext(“application.xml”);

(3)XmlWebApplicationContext:由Web應用的XML檔案讀取上下文。

4.6 Spring提供幾種配置方式來設定元資料

Spring提供以下三種配置方式來設定元資料:

(1)基於XML的配置。

(2)基於註解的配置。

(3)基於Java的配置。

4.7 如何使用XML配置方式配置Spring

在Spring框架中,依賴和服務需要專門的配置檔案實現,一般用XML格式的配置檔案。這些配置檔案的格式採用公共的模板,由一系列的Bean定義和專門的應用配置選項組成。 Spring XML配置的主要目的是使所有的Spring元件都可以用XML檔案的形式來進行配置。這意味著不會出現其他的Spring配置型別(比如宣告配置方式或基於Java Class的配置方式)。 Spring的XML配置方式是使用被Spring名稱空間所支援的一系列的XML標籤來實現的。Spring主要的名稱空間有context、beans、jdbc、tx、aop、mvc和aso。例如:


<beans>
   <!-- JSON Support -->
   <bean name="viewResolver"
        class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
   <bean name="jsonTemplate"
        class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
   <bean id="restTemplate" class="org.springframework.web.client.RestTemplate"/>
</beans>

下面這個web.xml僅配置了DispatcherServlet,最簡單的配置便能滿足應用程式配置執行時元件的需求。
<web-app>
   <display-name>Archetype Created Web Application</display-name>
   <servlet>
      <servlet-name>spring</servlet-name>
      <servlet-class>
         org.springframework.web.servlet.DispatcherServlet
      </servlet-class>
      <load-on-startup>1</load-on-startup>
   </servlet>
   <servlet-mapping>
      <servlet-name>spring</servlet-name>
      <url-pattern>/</url-pattern>
   </servlet-mapping>
</web-app>

4.8 Spring提供哪些配置形式

Spring對Java配置的支援是由@Configuration註解和@Bean註解來實現的。由@Bean註解的方法將會例項化、配置和初始化一個新物件,這個物件將由Spring的IoC容器來管理。@Bean宣告所起到的作用與元素類似。被@Configuration所註解的類則表示這個類的主要目的是作為Bean定義的資源。被@Configuration宣告的類可以通過在同一個類內部呼叫@bean方法來設定嵌入Bean的依賴關係。 最簡單的@Configuration 宣告類請參考下面的程式碼:


@Configuration
public class AppConfig{
   @Bean
   public MyService myService() {
      return new MyServiceImpl();
   }
}

與上面的@Beans配置檔案相同的XML配置檔案如下:


<beans>
   <bean id="myService" class="com.gupaoedu.services.MyServiceImpl"/>
</beans>

上述配置方式的例項化方式如下:


public static void main(String[] args) {
   ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
   MyService myService = ctx.getBean(MyService.class);
   myService.doStuff();
}

要使用元件掃描,僅需用@Configuration進行註解即可:


@Configuration
@ComponentScan(basePackages = "com.gupaoedu")
public class AppConfig  {
}

在上面的例子中,com.gupaoedu包首先會被掃描到,然後在容器內查詢被@Component 宣告的類,找到後將這些類按照Spring Bean定義進行註冊。 如果你要在Web應用開發中選用上述配置方式,需要用AnnotationConfigWebApplicationContext類來讀取配置檔案,可以用來配置Spring的Servlet監聽器ContrextLoaderListener或者Spring MVC的DispatcherServlet。 例如:


<web-app>
   <context-param>
      <param-name>contextClass</param-name>
      <param-value>
         org.springframework.web.context.support.AnnotationConfigWebApplicationContext
      </param-value>
   </context-param>
   <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>com.gupaoedu.AppConfig</param-value>
   </context-param>
   <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>
   <servlet>
      <servlet-name>dispatcher</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
         <param-name>contextClass</param-name>
         <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
         </param-value>
      </init-param>
      <init-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>com.gupaoedu.web.MVCConfig</param-value>
      </init-param>
   </servlet>
   <servlet-mapping>
      <servlet-name>dispatcher</servlet-name>
      <url-pattern>/web/*</url-pattern>
   </servlet-mapping>
</web-app>

4.9 怎樣用註解的方式配置Spring

Spring在2.5版本以後開始支援用註解的方式配置依賴注入。可以用註解的方式來替代XML方式的Bean描述,可以將Bean描述轉移到元件類的內部,只需要在相關類上、方法上或者欄位宣告上使用註解即可。註解注入將會被容器在XML注入之前處理,所以後者會覆蓋前者對於同一個屬性的處理結果。 註解裝配在Spring中是預設關閉的,需要在Spring檔案中進行配置才能使用基於註解的裝配模式。如果你想要在應用程式中使用註解的方式,請參考如下配置:


<beans>
   <context:annotation-config/>
</beans>

配置完成以後,就可以用註解的方式在Spring中向屬性、方法和構造方法中自動裝配變數。 下面是幾種比較重要的註解型別。

(1)@Required:該註解應用於設值方法。

(2)@Autowired:該註解應用於設值方法、非設值方法、構造方法和變數。

(3)@Qualifier:該註解和@Autowired註解搭配使用,用於消除特定Bean自動裝配的歧義。

(4)JSR-250 Annotations:Spring支援基於JSR-250 註解的註解,即@Resource、@PostConstruct和@PreDestroy。

4.10 請解釋Spring Bean的生命週期

Spring Bean的生命週期簡單易懂。在一個Bean例項被初始化時,需要執行一系列初始化操作以使其達到可用的狀態。同樣,當一個Bean不再被呼叫時需要進行相關的析構操作,並從Bean容器中移除。 Spring Bean Factory 負責管理在Spring容器中被建立的Bean的生命週期。Bean的生命週期由兩組回撥方法組成。

(1)初始化之後呼叫的回撥方法。

(2)銷燬之前呼叫的回撥方法。

Spring提供了以下4種方式來管理Bean的生命週期事件:

(1)InitializingBean和DisposableBean回撥介面。

(2)針對特殊行為的其他Aware介面。

(3)Bean配置檔案中的customInit()方法和customDestroy()方法。

(4)@PostConstruct和@PreDestroy註解方式。

使用customInit()和 customDestroy()方法管理Bean生命週期的程式碼樣例如下:


<beans>
   <bean id="demoBean" class="com.gupaoedu.task.DemoBean"
        init-Method="customInit" destroy-Method="customDestroy">
   </bean>
</beans>

4.11 Spring Bean作用域的區別是什麼

Spring容器中的Bean可以分為5個作用域。所有作用域的名稱都是自說明的,但是為了避免混淆,還是讓我們來解釋一下。

(1)singleton:這種Bean作用域是預設的,這種作用域確保不管接收到多少個請求,每個容器中只有一個Bean例項,單例模式由Bean Factory自身來維護。

(2)prototype:prototype作用域與singleton作用域相反,為每一個Bean請求提供一個例項。

(3)request:在請求Bean作用域內為每一個來自客戶端的網路請求建立一個例項,在請求完成以後,Bean會失效並被垃圾回收器回收。

(4)Session:與request作用域類似,確保每個Session中有一個Bean例項,在Session過期後,Bean會隨之失效。

(5)global-session:global-session和Portlet應用相關。當應用部署在Portlet容器中時,它包含很多Portlet。如果想讓所有的Portlet共用全域性儲存變數,那麼這個全域性儲存變數需要儲存在global-session中。全域性作用域與Servlet中的Session作用域效果相同。

4.12 什麼是Spring Inner Bean

在Spring中,無論何時,當Bean僅被呼叫了一個屬性時,一個明智的做法是將這個Bean宣告為內部Bean。內部Bean可以用setter注入“屬性”和用構造方法注入“構造引數”的方式來實現。 比如,在應用程式中一個Customer類引用了一個Person類,我們要建立一個Person類的例項,然後在Customer內部使用。


public class Customer{
   private Person person;
}
public class Person{
   private String name;
   private String address;
   private int age;
}

內部Bean的宣告方式如下:


<bean id="CustomerBean" class="com.gupaoedu.common.Customer">
   <property name="person">
      <bean class="com.gupaoedu.common.Person">
         <property name="name" value="lokesh" />
         <property name="address" value="India" />
         <property name="age" value="34" />
      </bean>
   </property>
</bean>

4.13 Spring中的單例Bean是執行緒安全的嗎

Spring並沒有對單例Bean進行任何多執行緒的封裝處理。關於單例Bean的執行緒安全和併發問題需要開發者自行解決。但實際上,大部分Spring Bean並沒有可變的狀態(比如Serview類和DAO類),所以在某種程度上,Spring的單例Bean是執行緒安全的。如果你的Bean有多種狀態(比如View Model物件),就需要自行保證執行緒安全。 最容易的解決辦法就是將多型Bean的作用域由“singleton”變更為“prototype”。

4.14 請舉例說明如何在Spring中注入一個Java集合

Spring提供了以下4種集合類的配置元素:

(1)<list>標籤用來裝配可重複的list值。

(2)<set>標籤用來裝配沒有重複的set值。

(3)<map>標籤用來注入鍵和值,可以為任何型別的鍵值對。

(4)<props>標籤支援注入鍵和值都是字串型別的鍵值對。

下面看一個具體的例子:


<beans>
   <bean id="javaCollection" class="com.gupaoedu.JavaCollection">
      <property name="customList">
         <list>
            <value>INDIA</value>
            <value>Pakistan</value>
            <value>USA</value>
            <value>UK</value>
         </list>
      </property>
      <property name="customSet">
         <set>
            <value>INDIA</value>
            <value>Pakistan</value>
            <value>USA</value>
            <value>UK</value>
         </set>
      </property>
      <property name="customMap">
         <map>
            <entry key="1" value="INDIA"/>
            <entry key="2" value="Pakistan"/>
            <entry key="3" value="USA"/>
            <entry key="4" value="UK"/>
         </map>
      </property>
      <property name="customProperies">
         <props>
            <prop key="admin">[email protected]</prop>
            <prop key="support">[email protected]</prop>
         </props>
      </property>
   </bean>
</beans>

4.15 如何向Spring Bean中注入java.util.Properties

第一種方法是使用如下程式碼所示的標籤:


<bean id="adminUser" class="com.gupaoedu.common.Customer">
   <property name="emails">
      <props>
         <prop key="admin">[email protected]</prop>
         <prop key="support">[email protected]</prop>
      </props>
   </property>
</bean>

也可用“util:”名稱空間從Properties檔案中建立一個Properties Bean,然後利用setter方法注入Bean的引用。

4.16 請解釋Spring Bean的自動裝配

在Spring框架中,在配置檔案中設定Bean的依賴關係是一個很好的機制,Spring容器還可以自動裝配合作關係Bean之間的關聯關係。這意味著Spring可以通過向BeanFactory中注入的方式自動搞定Bean之間的依賴關係。自動裝配可以設定在每個Bean上,也可以設定在特定的Bean上。 下面的XML配置檔案表明瞭如何根據名稱將一個Bean設定為自動裝配模式:


<bean id="employeeDAO" class="com.gupaoedu.EmployeeDAOImpl" autowire="byName" />

除了Bean配置檔案中提供的自動裝配模式,還可以使用@Autowired註解來自動裝配指定的Bean。在使用@Autowired註解之前需要按照如下的配置方式在Spring配置檔案中進行配置:


<context:annotation-config />

也可以通過在配置檔案中配置AutowiredAnnotationBeanPostProcessor 達到相同的效果:


<bean class ="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

配置好以後就可以使用@Autowired來標註了:


@Autowired
public EmployeeDAOImpl ( EmployeeManager manager ) {
      this.manager = manager;
}

4.17 自動裝配有哪些侷限性

自動裝配有如下侷限性。 重寫:你仍然需要使用< property>設定指明依賴,這意味著總要重寫自動裝配。 原生資料型別:你不能自動裝配簡單的屬性,如原生型別、字串和類。 模糊特性:自動裝配總是沒有自定義裝配精確,因此如果可能儘量使用自定義裝配。

4.18 請解釋各種自動裝配模式的區別

在Spring中一共有5種自動裝配模式,讓我們逐一分析。 (1)no:這是Spring的預設設定,在該設定下自動裝配是關閉的,開發者需要自行在Bean定義中用標籤明確地設定依賴關係。

(2)byName:該模式可以根據Bean名稱設定依賴關係。當向一個Bean中自動裝配一個屬性時,容器將根據Bean的名稱自動在配置檔案中查詢一個匹配的Bean。如果找到就裝配這個屬性,如果沒找到就報錯。

(3)byType:該模式可以根據Bean型別設定依賴關係。當向一個Bean中自動裝配一個屬性時,容器將根據Bean的型別自動在配置檔案中查詢一個匹配的Bean。如果找到就裝配這個屬性,如果沒找到就報錯。

(4)constructor:和byType模式類似,但是僅適用於有與構造器相同引數型別的Bean,如果在容器中沒有找到與構造器引數型別一致的Bean,那麼將會丟擲異常。

(5)autodetect:該模式自動探測使用constructor自動裝配或者byType自動裝配。首先會嘗試找合適的帶引數的構造器,如果找到就是用構造器自動裝配,如果在Bean內部沒有找到相應的構造器或者構造器是無參構造器,容器就會自動選擇byType模式。

4.19 請舉例解釋@Required註解

在產品級別的應用中,IoC容器可能聲明瞭數十萬個Bean,Bean與Bean之間有著複雜的依賴關係。設值註解方法的短板之一就是驗證所有的屬性是否被註解是一項十分困難的操作。可以通過設定“dependency-check”來解決這個問題。 在應用程式的生命週期中,你可能不大願意花時間驗證所有Bean的屬性是否按照上下文檔案正確配置,或者你寧可驗證某個Bean的特定屬性是否被正確設定。即使用“dependency-check”屬性也不能很好地解決這個問題,在這種情況下需要使用@Required 註解。 可用如下的方式來標明Bean的設值方法:


public class EmployeeFactoryBean extends AbstractFactoryBean<Object> {
   private String designation;
   public String getDesignation() {
      return designation;
   }
   @Required
   public void setDesignation(String designation) {
      this.designation = designation;
   }
}

RequiredAnnotationBeanPostProcessor是Spring中的後置處理器,用來驗證被@Required 註解的Bean屬性是否被正確設定了。在使用RequiredAnnotationBeanPostProcesso驗證Bean屬性之前,要在IoC容器中對其進行註冊:


<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor" />

但是如果沒有屬性被用@Required註解過,後置處理器會丟擲一個BeanInitializationException異常。

4.20 請舉例說明@Qualifier註解

@Qualifier註解意味著可以在被標註Bean的欄位上自動裝配。@Qualifier註解可以用來取消Spring不能取消的Bean應用。

4.21 構造方法注入和設值注入有什麼區別

請注意以下明顯的區別: (1)設值注入支援大部分依賴注入,如果我們僅需要注入int、string和long型的變數,不要用設值方法注入。對於基本型別,如果沒有注入,可以為基本型別設定預設值。構造方法注入不支援大部分依賴注入,因為在呼叫構造方法時必須傳入正確的構造引數,否則會報錯。

(2)設值注入不會重寫構造方法的值。如果我們對同一個變數同時使用了構造方法注入和設值注入,那麼構造方法將不能覆蓋設值注入的值。很明顯,因為構造方法只在物件被建立時被呼叫。

(3)在使用設值注入時還不能保證某種依賴是否已經被注入,也就是說,這時物件的依賴關係有可能是不完整的。而在另一種情況下,構造器注入則不允許生成依賴關係不完整的物件。

(4)在設值注入時如果物件A和物件B互相依賴,在建立物件A時Spring會丟擲ObjectCurrentlyInCreationException異常,因為在物件B被建立之前物件A是不能被建立的,反之亦然。Spring用設值注入解決了迴圈依賴問題,因為物件的設值方法是在物件被建立之前被呼叫的。

4.22 Spring中有哪些不同型別的事件

Spring的ApplicationContext 提供了支援事件和程式碼中監聽器的功能。 我們可以建立Bean來監聽在ApplicationContext 中釋出的事件。對於ApplicationEvent類和在ApplicationContext介面中處理的事件,如果一個Bean實現了ApplicationListener介面,當一個ApplicationEvent 被髮布以後,Bean會自動被通知。


public class AllApplicationEventListener implements ApplicationListener<ApplicationEvent> {
   @Override
   public void onApplicationEvent(ApplicationEvent applicationEvent) {
      //process event
   }
}

Spring 提供了以下5種標準的事件。 (1)上下文更新事件(ContextRefreshedEvent):該事件會在ApplicationContext被初始化或者更新時釋出。也可以在呼叫ConfigurableApplicationContext 介面中的refresh()方法時被觸發。

(2)上下文開始事件(ContextStartedEvent):當容器呼叫ConfigurableApplicationContext的Start()方法開始或重新開始容器時觸發該事件。

(3)上下文停止事件(ContextStoppedEvent):當容器呼叫ConfigurableApplicationContext的Stop()方法停止容器時觸發該事件。

(4)上下文關閉事件(ContextClosedEvent):當ApplicationContext被關閉時觸發該事件。容器被關閉時,其管理的所有單例Bean都被銷燬。

(5)請求處理事件(RequestHandledEvent):在Web應用中,當一個HTTP請求(Request)結束時觸發該事件。

除了上面介紹的事件,還可以通過擴充套件ApplicationEvent類來自定義事件:


public class CustomApplicationEvent extends ApplicationEvent {
   public CustomApplicationEvent ( Object source, final String msg ){
      super(source);
      System.out.println("Created a Custom event");
   }
}

為了監聽這個事件,還需要建立一個監聽器:


public class CustomEventListener implements ApplicationListener < CustomApplicationEvent >{
   @Override
   public void onApplicationEvent(CustomApplicationEvent applicationEvent) {
   }
}

之後通過ApplicationContext介面的publishEvent()方法來發布自定義事件: CustomApplicationEvent customEvent = new CustomApplicationEvent(applicationContext, “Test message”); applicationContext.publishEvent(customEvent);

4.23 FileSystemResource和ClassPathResource有什麼區別

在FileSystemResource 中需要給出spring-config.xml檔案在專案中的相對路徑或者絕對路徑。在ClassPathResource中Spring會在ClassPath中自動搜尋配置檔案,所以要把ClassPathResource 檔案放在ClassPath下。 如果將spring-config.xml儲存在了src目錄下,只需給出配置檔案的名稱即可,因為src是預設的路徑。 簡而言之,ClassPathResource在環境變數中讀取配置檔案,FileSystemResource在配置檔案中讀取配置檔案。

4.24 Spring中用到了哪些設計模式

Spring中使用了大量的設計模式,下面列舉了一些比較有代表性的設計模式。

(1)代理模式:在AOP和remoting中被用得比較多。

(2)單例模式:在Spring配置檔案中定義的Bean預設為單例模式。

(3)模板模式:用來解決程式碼重複問題,比如RestTemplate、JmsTemplate、JpaTemplate。

(4)委派模式:Spring提供了DispatcherServlet來對請求進行分發。

(5)工廠模式:BeanFactory用來建立物件的例項,貫穿於BeanFactory和ApplicationContext介面。

(6)代理模式:代理模式AOP思想的底層實現技術,Spring中採用JDK Proxy和CGLib類庫。

4.25 在Spring中如何更有效地使用JDBC

使用Spring JDBC可以使得資源管理及錯誤處理的代價減小。開發人員只需通過statements和queries語句從資料庫中存取資料。Spring通過模板類能更有效地使用JDBC,也就是所謂的JdbcTemplate。

4.26 請解釋Spring中的IoC容器

Spring中的org.springframework.beans包和org.springframework.context包構成了Spring IoC容器的基礎。 BeanFactory介面提供了一個先進的配置機制,使得任何型別的物件的配置都成為可能。ApplicationContex介面對BeanFactory(是一個子介面)進行了擴充套件,在BeanFactory的基礎上添加了其他功能,比如與Spring的AOP更容易整合,也提供了處理Message Resource的機制(用於國際化),以及事件傳播及應用層的特別配置,比如針對Web應用的WebApplicationContext。

4.27 在Spring中可以注入null或空字串嗎

完全可以。

關注微信公眾號『 Tom彈架構 』回覆“Spring”可獲取完整原始碼。

本文為“Tom彈架構”原創,轉載請註明出處。技術在於分享,我分享我快樂!如果您有任何建議也可留言評論或私信,您的支援是我堅持創作的動力。關注微信公眾號『 Tom彈架構 』可獲取更多技術乾貨!

原創不易,堅持很酷,都看到這裡了,小夥伴記得點贊、收藏、在看,一鍵三連加關注!如果你覺得內容太乾,可以分享轉發給朋友滋潤滋潤!