Spring面試題
什麼是Spring框架?Spring有哪些核心模組
Spring框架是一個為Java應用程式的開發提供了綜合、廣泛的基礎性支援的Java平臺。Spring幫助開發者解決了開發中基礎性的問題,使得開發人員可以專注於應用程式的開發。Spring框架本身亦是按照設計模式精心打造,這使得我們可以在開發環境中安心的整合Spring框架,不必擔心Spring是如何在後臺進行工作的。 Spring框架至今已整合了20多個模組。這些模組主要被分如下圖所示的核心容器、資料訪問/整合,、Web、AOP(面向切面程式設計)、工具、訊息和測試模組。
核心模組 | 說明 |
---|---|
Spring Core | 核心容器:核心容器提供Spring框架的基本功能。Spring以bean的方式組織和管理Java應用中的各個元件及其關係。Spring使用BeanFactory來產生和管理Bean,它是工廠模式的實現。BeanFactory使用控制反轉(IoC)模式將應用的配置和依賴性規範與實際的應用程式程式碼分開 |
Spring Context | 應用上下文: 是一個配置檔案,向Spring框架提供上下文資訊。Spring上下文包括企業服務,如JNDI、EJB、電子郵件、國際化、校驗和排程功能 |
Spring AOP | 面向切面程式設計: 是物件導向程式設計的有效補充和完善,Spring的AOP是基於動態代理實現的,實現的方式有兩種分別是Schema和AspectJ這兩種方式 |
Spring Dao | JDBC和Dao模組: JDBC、DAO的抽象層提供了有意義的異常層次結構,可用該結構來管理異常處理,和不同資料庫供應商所丟擲的錯誤資訊。異常層次結構簡化了錯誤處理,並且極大的降低了需要編寫的程式碼數量,比如開啟和關閉連結 |
Spring ORM | 物件實體對映: Spring框架插入了若干個ORM框架,從而提供了ORM物件的關係工具,其中包括了Hibernate、JDO和 IBatis SQL Map等,所有這些都遵從Spring的通用事物和DAO異常層次結構。 |
Spring Web | Web模組: Web上下文模組建立在應用程式上下文模組之上,為基於web的應用程式提供了上下文。所以Spring框架支援與Struts整合,web模組還簡化了處理多部分請求以及將請求引數繫結到域物件的工作 |
Spring Web MVC | **MVC模組:**MVC框架是一個全功能的構建Web應用程式的MVC實現。通過策略介面,MVC框架變成為高度可配置的。MVC容納了大量檢視技術,其中包括JSP、POI等,模型由JavaBean構成,存放於m當中,而檢視是一個介面,負責實現模型,控制器表示邏輯程式碼,由c的事情。Spring框架的功能可以用在任何J2EE伺服器當中,大多數功能也適用於不受管理的環境。Spring的核心要點就是支援不繫結到特定J2EE服務的可重用業務和資料的訪問的物件,毫無疑問這樣的物件可以在不同的J2EE環境,獨立應用程式和測試環境之間重用。 |
使用Spring框架的好處有哪些?
序號 | 好處 | 說明 |
---|---|---|
1 | 輕量 | Spring 是輕量的,基本的版本大約2MB。 |
2 | 控制反轉 | Spring通過控制反轉實現了鬆散耦合,物件們給出它們的依賴,而不是建立或查詢依賴的物件們。 |
3 | 面向切面程式設計(AOP) | Spring支援面向切面的程式設計,並且把應用業務邏輯和系統服務分開。 |
4 | 容器 | Spring 包含並管理應用中物件的生命週期和配置。 |
5 | MVC框架 | Spring的WEB框架是個精心設計的框架,是Web框架的一個很好的替代品。 |
6 | 事務管理 | Spring 提供一個持續的事務管理介面,可以擴充套件到上至本地事務下至全域性事務(JTA)。 |
7 | 異常處理 | Spring 提供方便的API把具體技術相關的異常(比如由JDBC,Hibernate or JDO丟擲的)轉化為一致的unchecked 異常。 |
8 | 最重要的 | 用的人多!!! |
BeanFactory和ApplicationContext有什麼區別?
在類圖關係上BeanFactory是ApplicationContext介面的父介面
BeanFactory
是spring中比較原始的Factory。如XMLBeanFactory就是一種典型的BeanFactory。原始的BeanFactory無法支援spring的許多外掛,如AOP功能、Web應用等。
ApplicationContext
ApplicationContext介面是由BeanFactory介面派生而來,因而具有BeanFactory所有的功能。ApplicationContext以一種更向面向框架的方式工作以及對上下文進行分層和實現繼承,ApplicationContext包還提供了以下的功能
- MessageSource, 提供國際化的訊息訪問
- 資源訪問,如URL和檔案
- 事件傳播
- 載入多個(有繼承關係)上下文 ,使得每一個上下文都專注於一個特定的層次,比如應用的web層,其實通過上面的類圖大家應該也能看的出來BeanFactory和ApplicationContext的區別的。
Spring有幾種配置方式?
序號 | 配置方式 |
---|---|
1 | 基於XML的配置 |
2 | 基於註解的配置 |
3 | 基於Java的配置 |
怎樣用XML方式配置Spring?
1.建立xml配置檔案
在專案資源目錄下建立applicationContext.xml檔案,如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
複製程式碼
2.載入容器
如果是web專案的話,在web.xml檔案新增如下配置:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
複製程式碼
如果是java專案可以通過BeanFactory或ApplicationContext來直接載入Spring容器
BeanFactory bf =
new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
// 或者
ApplicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml");
複製程式碼
怎樣用註解的方式配置Spring?
1.配置檔案中開啟掃描
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 開啟註解 配置掃描路徑 -->
<context:component-scan base-package="com.dpb.javabean"/>
<!-- 如果有多個路徑 ,號隔開
<context:component-scan base-package="com.dpb.javabean,com.dpb.factory"/>
-->
</beans>
複製程式碼
2.載入容器
如果是web專案的話,在web.xml檔案新增如下配置:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
複製程式碼
如果是java專案可以通過BeanFactory或ApplicationContext來直接載入Spring容器
BeanFactory bf =
new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
// 或者
ApplicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml");
複製程式碼
如何用基於Java配置的方式配置Spring?
Spring對Java配置的支援是由@Configuration註解和@Bean註解來實現的。
註解 | 說明 |
---|---|
@Bean | 由@Bean註解的方法將會例項化、配置和初始化一個新物件,這個物件將由Spring的IoC容器來管理 ,@Bean宣告所起到的作用與 元素類似 |
@Configuration | 表示該類是一個配置類。用來定義bean資源 |
1.建立配置類
@Configuration
public class AppConfig
{
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
複製程式碼
2.載入容器
如果是web專案的話,在web.xml檔案新增如下配置:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
複製程式碼
如果是java專案可以通過ApplicationContext來載入
public static void main(String[] args) {
ApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
複製程式碼
ApplicationContext通常的實現是什麼?
實現方式 | 說明 |
---|---|
FileSystemXmlApplicationContext | 此容器從一個XML檔案中載入beans的定義,XML Bean 配置檔案的全路徑名必須提供給它的建構函式 |
ClassPathXmlApplicationContext | 此容器也從一個XML檔案中載入beans的定義,這裡,你需要正確設定classpath因為這個容器將在classpath裡找bean配置 |
WebXmlApplicationContext | 此容器載入一個XML檔案,此檔案定義了一個WEB應用的所有bean |
解釋Spring支援的幾種bean的作用域
Spring容器中的bean可以分為5個範圍。:
作用域 | 說明 |
---|---|
singleton | 這種bean範圍是預設的,這種範圍確保不管接受到多少個請求,每個容器中只有一個bean的例項,單例的模式由bean factory自身來維護 |
prototype | 原型範圍與單例範圍相反,為每一個bean請求提供一個例項,原型模式 |
request | 在請求bean範圍內會每一個來自客戶端的網路請求建立一個例項,在請求完成以後,bean會失效並被垃圾回收器回收 |
Session | 與請求範圍類似,確保每個session中有一個bean的例項,在session過期後,bean會隨之失效 |
global-session | global-session和Portlet應用相關。當你的應用部署在Portlet容器中工作時,它包含很多portlet。如果你想要宣告讓所有的portlet共用全域性的儲存變數的話,那麼這全域性變數需要儲存在global-session中。全域性作用域與Servlet中的session作用域效果相同。 |
Spring框架中的單例bean是執行緒安全的嗎?
肯定不是執行緒安全的,當多使用者同時請求一個服務時,容器會給每一個請求分配一個執行緒,這是多個執行緒會併發執行該請求多對應的業務邏輯(成員方法),此時就要注意了,如果該處理邏輯中有對該單列狀態的修改(體現為該單列的成員屬性),則必須考慮執行緒同步問題.
什麼是Spring的內部bean?
當一個bean僅被用作另一個bean的屬性時,它能被宣告為一個內部bean,為了定義inner bean,在Spring 的 基於XML的 配置後設資料中,可以在 或\ 元素內使用 元素,內部bean通常是匿名的,它們的Scope一般是prototype。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="CustomerBean" class="com.dpb.common.Customer">
<property name="person" ref="PersonBean"/>
</bean>
<bean id="PersonBean" class="com.dpb.common.Person">
<property name="name" value="波波烤鴨"/>
<property name="address" value="深圳"/>
<property name="age" value="17"/>
</bean>
</beans>
複製程式碼
改為內部bean的方式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="CustomerBean" class="com.dpb.common.Customer">
<property name="person">
<bean class="com.dpb.common.Person">
<property name="name" value="波波烤鴨"/>
<property name="address" value="湖南"/>
<property name="age" value="17"/>
</bean>
</property>
</bean>
</beans>
複製程式碼
內部 bean 也支援構造器注入
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="CustomerBean" class="com.dpb.common.Customer">
<constructor-arg >
<bean class="com.dpb.common.Person">
<property name="name" value="波波烤鴨"/>
<property name="address" value="湖南"/>
<property name="age" value="17"/>
</bean>
</constructor-arg>
</bean>
</beans>
複製程式碼
id 或 name 值在bean類是沒有必要以一個內部 bean 呈現
在 Spring中如何注入一個java集合?
Spring提供以下幾種集合的配置元素:
元素 | 說明 |
---|---|
list | 型別用於注入一列值,允許有相同的值。 |
set | 型別用於注入一組值,不允許有相同的值。 |
map | 型別用於注入一組鍵值對,鍵和值都可以為任意型別。 |
props | 型別用於注入一組鍵值對,鍵和值都只能為String型別。 |
<!-- 配置 student物件 -->
<bean class="com.dpb.javabean.Student">
<property name="id" value="10"/>
<property name="name" value="波波烤鴨"/>
<!-- 物件注入 -->
<property name="cat" ref="catId"></property>
<!-- List集合注入 -->
<property name="games">
<list>
<value>LOL</value>
<value>DNF</value>
<value>CS</value>
</list>
</property>
<property name="score">
<map>
<entry key="數學" value="99"/>
<entry key="英語" value="78"/>
<entry key="化學" value="84"/>
</map>
</property>
<property name="props">
<props>
<prop key="userName">admin</prop>
<prop key="password">123</prop>
</props>
</property>
複製程式碼
解釋不同方式的自動裝配
有五種自動裝配的方式,可以用來指導Spring容器用自動裝配方式來進行依賴注入。
裝配型別 | 說明 |
---|---|
no | 預設的方式是不進行自動裝配,通過顯式設定ref 屬性來進行裝配 |
byName | 通過引數名 自動裝配,Spring容器在配置檔案中發現bean的autowire屬性被設定成byname,之後容器試圖匹配、裝配和該bean的屬性具有相同名字的bean。 |
byType | 通過引數型別自動裝配,Spring容器在配置檔案中發現bean的autowire屬性被設定成byType,之後容器試圖匹配、裝配和該bean的屬性具有相同型別的bean。如果有多個bean符合條件,則丟擲錯誤。 |
constructor | 這個方式類似於byType, 但是要提供給構造器引數,如果沒有確定的帶引數的構造器引數型別,將會丟擲異常。 |
autodetect | 首先嚐試使用constructor來自動裝配,如果無法工作,則使用byType方式。 |
@Autowired 註解解釋
emsp;通過型別來實現自動注入bean。和@Qualifier註解配合使用可以實現根據name注入bean。
@Qualifier 註解解釋
emsp;和@Autowired一塊使用,在同一型別的bean有多個的情況下可以實現根據name注入的需求
@Resource 註解解釋
emsp;預設是根據name注入bean的,可以通過設定型別來實現通過型別來注入
Spring支援的事務管理型別
Spring支援兩種型別的事務管理:
程式設計式事務管理:這意味你通過程式設計的方式管理事務,給你帶來極大的靈活性,但是難維護。 宣告式事務管理:這意味著你可以將業務程式碼和事務管理分離,你只需用註解和XML配置來管理事務。
Spring框架的事務管理有哪些優點?
它為不同的事務API 如 JTA,JDBC,Hibernate,JPA 和JDO,提供一個不變的程式設計模式。 它為程式設計式事務管理提供了一套簡單的API而不是一些複雜的事務API如它為程式設計式事務管理提供了一套簡單的API而不是一些複雜的事務API如 它支援宣告式事務管理。它支援宣告式事務管理。 它和Spring各種資料訪問抽象層很好得整合。它和Spring各種資料訪問抽象層很好得整合。
你更傾向用哪種事務管理型別?
大多數Spring框架的使用者選擇宣告式事務管理,因為它對應用程式碼的影響最小,因此更符合一個無侵入的輕量級容器的思想。宣告式事務管理要優於程式設計式事務管理,雖然比程式設計式事務管理(這種方式允許你通過程式碼控制事務)少了一點靈活性。
Spring框架使用了哪些設計模式
- 單例模式
- 原型模式
- 工廠模式
- 介面卡模式
- 包裝模式
- 代理模式
- 觀察者模式
- 策略模式
- 模板模式
請解釋Spring Bean的生命週期?
Spring容器 從XML 檔案中讀取bean的定義,並例項化bean。 Spring根據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()方法。