Spring基礎面試題(一)


  • Spring是什么
Spring是一個輕量級的IoC和AOP容器框架。是為Java應用程序提供基礎性服務的一套框架,目的是用於簡化企業應用程序的開發,它使得開發者只需要關心業務需求。
常見的配置方式有三種:基於XML的配置、基於注解的配置、基於Java的配置。

 

  •  使用Spring框架的好處是什么?
方便解耦,簡化開發
通過 Spring提供的 IoC容器,可以將對象間的依賴關系交由 Spring進行控制,避免硬編碼所造成的過度程序耦合。
spring屬於低侵入式設計,代碼的污染極低。
spring的DI機制將對象之間的依賴關系交由框架處理,減低組件的耦合性; AOP 編程的支持 通過 Spring的 AOP 功能,支持將一些通用任務,如安全、事務、日志、權限等進行集中式管理,從而提供更好的復用。
方便進行面向切面的編程,許多不容易用傳統OOP 實現的功能可以通過 AOP 輕松應付。 聲明式事務的支持 可以將我們從單調煩悶的事務管理代碼中解脫出來,通過聲明式方式靈活的進行事務的管理,提高開發效率和質量。
集成各種優秀框架
spring對於主流的應用框架提供了集成支持。

 

  •  Spring由哪些模塊組成?

 

Spring Core:核心類庫,提供IOC服務;

Spring Context:提供框架式的Bean訪問方式,以及企業級功能(JNDI、定時任務等);

Spring AOP:AOP服務;

Spring DAO:對JDBC的抽象,簡化了數據訪問異常的處理;

Spring ORM:對現有的ORM框架的支持;

Spring Web:提供了基本的面向Web的綜合特性,例如多方文件上傳;

Spring MVC:提供面向Web應用的Model-View-Controller實現。

 

  • 什么是耦合性?耦合性的分類有哪些?如何避免耦合性?
(1)耦合性(Coupling),也叫耦合度,是對模塊間關聯程度的度量。

(2)耦合有如下分類:
① 內容耦合:當一個模塊直接修改或操作另一個模塊的數據時,或一個模塊不通過正常入口而轉入另一個模塊時,這樣的耦合被稱為內容耦合。內容耦合是最高程度的耦合,應該避免使用之。
② 公共耦合:兩個或兩個以上的模塊共同引用一個全局數據項,這種耦合被稱為公共耦合。在具有大量公共耦合的結構中,確定究竟是哪個模塊給全局變量賦了一個特定的值是十分困難的。
③ 外部耦合:一組模塊都訪問同一全局簡單變量而不是同一全局數據結構,而且不是通過參數表傳遞該全局變量的信息,則稱之為外部耦合。
④ 控制耦合:一個模塊通過接口向另一個模塊傳遞一個控制信號,接受信號的模塊根據信號值而進行適當的動作,這種耦合被稱為控制耦合。
⑤ 標記耦合:若一個模塊 A 通過接口向兩個模塊 B 和 C 傳遞一個公共參數,那么稱模塊 B 和 C 之間存在一個標記耦合。
⑥ 數據耦合:模塊之間通過參數來傳遞數據,稱為數據耦合。數據耦合是最低的一種耦合形式,系統中一般都存在這種類型的耦合,因為某些模塊的輸出數據需要作為另一些模塊的輸入數據。
⑦ 非直接耦合:兩個模塊之間沒有直接關系,它們之間的聯系完全是通過主模塊的控制和調用來實現的。

(3)耦合是影響軟件復雜程度和設計質量的一個重要因素。
   在設計上我們應采用以下原則:如果模塊間必須存在耦合,就盡量使用數據耦合,少用控制耦合,限制公共耦合的范圍,盡量避免使用內容耦合。

 

  • Spring IOC 的理解,其初始化過程?

 

控制反轉是就是應用本身不負責依賴對象的創建和維護,依賴對象的創建及維護是由外部容器負責的,這樣控制權就有應用轉移到了外部容器,控制權的轉移就是控制反轉。

 

 


IOC 容器的初始化分為三個過程實現:
過程一:Resource資源定位,這個Resouce指的是BeanDefinition的資源定位,這個過程就是容器找數據的過程。
過程二:BeanDefinition的載入過程,這個載入過程是把用戶定義好的Bean表示成Ioc容器內部的數據結構,而這個容器內部的數據結構就是BeanDefition。
過程三:向IOC容器注冊這些BeanDefinition的過程,這個過程就是將前面的BeanDefition保存到HashMap中的過程。

Resource定位 IOC容器第一步就是需要定位Resource外部資源。Resource的定位其實就是BeanDefinition的資源定位,它是由ResourceLoader通過統一的Resource接口來完成的,這個Resource對各種形式的BeanDefinition的使用都提供了統一接口。 載入 第二個過程就是BeanDefinition的載入,BeanDefinitionReader讀取,解析Resource定位的資源。
也就是將用戶定義好的Bean表示成IOC容器的內部數據結構也就是BeanDefinition,在IOC容器內部維護着一個BeanDefinition Map的數據結構,通過這樣的數據結構,IOC容器能夠對Bean進行更好的管理。 在配置文件中每一個
<bean>都對應着一個BeanDefinition對象。 注冊 第三個過程則是注冊,即向IOC容器注冊這些BeanDefinition,這個過程是通過BeanDefinitionRegistery接口來實現的。 在IOC容器內部其實是將第二個過程解析得到的BeanDefinition注入到一個HashMap容器中,IOC容器就是通過這個HashMap來維護這些BeanDefinition的。 經過這 (Resource定位,載入,注冊)三個步驟,IOC容器的初始化過程就已經完成了。

 

  •  BeanFactory和ApplicationContext的區別?
BeanFactory和ApplicationContext是Spring的兩大核心接口,都可以當做Spring的容器。其中ApplicationContext是BeanFactory的子接口。

(1)BeanFactory:是Spring里面最底層的接口,包含了各種Bean的定義,讀取bean配置文檔,管理bean的加載、實例化,控制bean的生命周期,維護bean之間的依賴關系。
  
   ApplicationContext接口作為BeanFactory的派生,除了提供BeanFactory所具有的功能外,還提供了更完整的框架功能:   ①繼承MessageSource,因此支持國際化。   ②統一的資源文件訪問方式。   ③提供在監聽器中注冊bean的事件。   ④同時加載多個配置文件。   ⑤載入多個(有繼承關系)上下文 ,使得每一個上下文都專注於一個特定的層次,比如應用的web層。 (2)①BeanFactroy采用的是延遲加載形式來注入Bean的,即只有在使用到某個Bean時(調用getBean()),才對該Bean進行加載實例化。這樣,我們就不能發現一些存在的Spring的配置問題。如果Bean的某一個屬性沒有注入,BeanFacotry加載后,直至第一次使用調用getBean方法才會拋出異常。     ②ApplicationContext,它是在容器啟動時,一次性創建了所有的Bean。這樣,在容器啟動時,我們就可以發現Spring中存在的配置錯誤,這樣有利於檢查所依賴屬性是否注入。 ApplicationContext啟動后預載入所有的單實例Bean,通過預載入單實例bean ,確保當你需要的時候,你就不用等待,因為它們已經創建好了。     ③ApplicationContext 唯一的不足是占用內存空間。當應用程序配置Bean較多時,程序啟動較慢。 (3)BeanFactory通常以編程的方式被創建。
ApplicationContext還能以聲明的方式創建,如使用ContextLoader。 (4)BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但兩者之間的區別是:BeanFactory需要手動注冊,而ApplicationContext則是自動注冊。

 

  • Spring Bean 的生命周期?

首先說一下Servlet的生命周期:實例化,初始init,接收請求service,銷毀destroy;

 Spring上下文中的Bean生命周期也類似,如下:

(1)實例化Bean:

對於BeanFactory容器,當客戶向容器請求一個尚未初始化的bean時,或初始化bean的時候需要注入另一個尚未初始化的依賴時,容器就會調用createBean進行實例化。對於ApplicationContext容器,當容器啟動結束后,通過獲取BeanDefinition對象中的信息,實例化所有的bean。

(2)設置對象屬性(依賴注入):

實例化后的對象被封裝在BeanWrapper對象中,緊接着,Spring根據BeanDefinition中的信息 以及 通過BeanWrapper提供的設置屬性的接口完成依賴注入。

(3)處理Aware接口:

接着,Spring會檢測該對象是否實現了xxxAware接口,並將相關的xxxAware實例注入給Bean:

①如果這個Bean已經實現了BeanNameAware接口,會調用它實現的setBeanName(String beanId)方法,此處傳遞的就是Spring配置文件中Bean的id值;

②如果這個Bean已經實現了BeanFactoryAware接口,會調用它實現的setBeanFactory()方法,傳遞的是Spring工廠自身。

③如果這個Bean已經實現了ApplicationContextAware接口,會調用setApplicationContext(ApplicationContext)方法,傳入Spring上下文;

(4)BeanPostProcessor:

如果想對Bean進行一些自定義的處理,那么可以讓Bean實現了BeanPostProcessor接口,那將會調用postProcessBeforeInitialization(Object obj, String s)方法。由於這個方法是在Bean初始化結束時調用的,所以可以被應用於內存或緩存技術;

(5)InitializingBean 與 init-method:

如果Bean在Spring配置文件中配置了 init-method 屬性,則會自動調用其配置的初始化方法。

(6)如果這個Bean實現了BeanPostProcessor接口,將會調用postProcessAfterInitialization(Object obj, String s)方法;

以上幾個步驟完成后,Bean就已經被正確創建了,之后就可以使用這個Bean了。

(7)DisposableBean:

當Bean不再需要時,會經過清理階段,如果Bean實現了DisposableBean這個接口,會調用其實現的destroy()方法;

(8)destroy-method:

最后,如果這個Bean的Spring配置中配置了destroy-method屬性,會自動調用其配置的銷毀方法。
 

 


免責聲明!

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



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