Spring基本概念及其面試題

誠信通天下發表於2019-04-18

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包還提供了以下的功能

  1. MessageSource, 提供國際化的訊息訪問
  2. 資源訪問,如URL和檔案
  3. 事件傳播
  4. 載入多個(有繼承關係)上下文 ,使得每一個上下文都專注於一個特定的層次,比如應用的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框架使用了哪些設計模式

  1. 單例模式
  2. 原型模式
  3. 工廠模式
  4. 介面卡模式
  5. 包裝模式
  6. 代理模式
  7. 觀察者模式
  8. 策略模式
  9. 模板模式

請解釋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()方法。

相關文章