盤點近年來面試常見的spring面試真題

前言:

金九銀十過去了,相信很多朋友都拿到了自己心儀的offer,今天我總結了一下各個大廠的面試題,復盤下大廠面試問到的一些問題,今天給大家分享的是進年來面試經常被問到的spring面試真題。

1 、什么是 Spring 框架?Spring 框架有哪些主要模塊?

Spring 框架是一個為 Java 應用程序的開發(fā)提供了綜合、廣泛的基礎性支持的 Java 平 臺。Spring 幫助開發(fā)者解決了開發(fā)中基礎性的問題,使得開發(fā)人員可以專注于應用程序 的開發(fā)。 Spring 框架本身亦是按照設計模式精心打造,這使得我們可以在開發(fā)環(huán)境中安心的集成 Spring 框架,不必擔心 Spring 是如何在后臺進行工作的。 Spring 框架至今已集成了 20 多個模塊。這些模塊主要被分如下圖所示的核心容器、數(shù) 據(jù)訪問/集成,、Web、AOP(面向切面編程)、工具、消息和測試模塊。

2 、使用 Spring 框架能帶來哪些好處?

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

Dependency Injection(DI) 方法使得構造器和 JavaBean properties 文件中的依賴關系 一目了然

與 EJB 容器相比較,IoC 容器更加趨向于輕量級。這樣一來 IoC 容器在有限的內存和 CPU 資源的情況下進行應用程序的開發(fā)和發(fā)布就變得十分有利。

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

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

要測試一項用 Spring 開發(fā)的應用程序十分簡單,因為測試相關的環(huán)境代碼都已經囊括 在框架中了。更加簡單的是,利用 JavaBean 形式的 POJO 類,可以很方便的利用依賴 注入來寫入測試數(shù)據(jù)。

Spring 的 Web 框架亦是一個精心設計的 Web MVC 框架,為開發(fā)者們在 web 框架的 選擇上提供了一個除了主流框架比如 Struts、過度設計的、不流行 web 框架的以外的有 力選項。

Spring 提供了一個便捷的事務管理接口,適用于小型的本地事物處理(比如在單 DB 的環(huán)境下)和復雜的共同事物處理(比如利用 JTA 的復雜 DB 環(huán)境)。

3 、什么是控制反轉(IOC) ?什么是依賴注入?

控制反轉是應用于軟件工程領域中的,在運行時被裝配器對象來綁定耦合對象的一種編程 技巧,對象之間耦合關系在編譯時通常是未知的。在傳統(tǒng)的編程方式中,業(yè)務邏輯的流程 是由應用程序中的早已被設定好關聯(lián)關系的對象來決定的。在使用控制反轉的情況下,業(yè)務邏輯的流程是由對象關系圖來決定的,該對象關系圖由裝配器負責 實例化,這種實現(xiàn)方式還可以將對象之間的關聯(lián)關系的定義抽象化。而綁定的過程是通過 “依賴注入”實現(xiàn)的。

控制反轉是一種以給予應用程序中目標組件更多控制為目的設計范式,并在我們的實際工 作中起到了有效的作用。

依賴注入是在編譯階段尚未知所需的功能是來自哪個的類的情況下,將其他對象所依賴的 功能對象實例化的模式。這就需要一種機制用來激活相應的組件以提供特定的功能,所以 依賴注入是控制反轉的基礎。否則如果在組件不受框架控制的情況下,框架又怎么知道要 創(chuàng)建哪個組件?

在 Java 中依然注入有以下三種實現(xiàn)方式:

?構造器注入?

Setter 方法注入

接口注入

4 、請解釋下 Spring 的 框架中的 IoC

Spring 中的 org.springframework.beans 包和 org.springframework.context 包構成了 Spring 框架 IoC 容器的基礎

BeanFactory 接口提供了一個先進的配置機制,使得任何類型的對象的配置成為可能。 ApplicationContex 接口對 BeanFactory(是一個子接口)進行了擴展,在 BeanFactory 的基礎上添加了其他功能,比如與 Spring 的 AOP 更容易集 成,也提供了處理 message resource 的機制(用于國際 化 ) 、 事 件 傳 播 以 及 應 用 層 的 特 別 配 置 , 比 如 針 對 Web 應 用 的 WebApplicationContext。

org.springframework.beans.factory.BeanFactory 是 Spring IoC 容器的具體實現(xiàn),用來包裝和管理前面提到的各種 bean。BeanFactory 接口 是 Spring IoC 容器的核心接口。

5 、BeanFactory 和 和 ApplicationContext 有什么區(qū)別?

BeanFactory 可以理解為含有 bean 集合的工廠類。 BeanFactory 包含了種 bean 的定義,以便在接收到客戶端請求時將對應的 bean 實例 化。

BeanFactory 還能在實例化對象的時生成協(xié)作類之間的關系。此舉將 bean 自身與 bean 客戶端的配置中解放出來。 BeanFactory 還包含了 bean 生命周期的控制,調用客戶端 的初始化方法(initialization(destruction methods)。

從表面上看,application context 如同 bean factory 一樣具有 bean 定義、bean 關 聯(lián)關系的設置,根據(jù)請求分發(fā) bean 的功能。但 application context 在此基礎上還提供 了其他的功能。

提供了支持國際化的文本消息

統(tǒng)一的資源文件讀取方式?

已在監(jiān)聽器中注冊的 bean 的事件 以下是三種較常見的 ApplicationContext 實現(xiàn)方式:

1、ClassPathXmlApplicationContext:從 classpath 的 XML 配置文件中讀取上下 文,并生成上下文定義。應用程序上下文從程序環(huán)境變量中取得。

1.?ApplicationContext?context?=?new

ClassPathXmlApplicationContext(“bean.xml”);

復制代碼

2、FileSystemXmlApplicationContext :由文件系統(tǒng)中的 XML 配置文件讀取上下 文。

1.?ApplicationContext?context?=?new

FileSystemXmlApplicationContext(“bean.xml”);

復制代碼

3、XmlWebApplicationContext:由 Web 應用的 XML 文件讀取上下文。

6 、Spring 有幾種配置方式?

將 Spring 配置到應用開發(fā)中有以下三種方式:

基于 XML 的配置?

基于注解的配置?

基于 Java 的配置

7 、如何用基于 XML 置 配置的方式配置 Spring ?

在 Spring 框架中,依賴和服務需要在專門的配置文件來實現(xiàn),我常用的 XML 格式的 配置文件。這些配置文件的格式通常用開頭,然后一系列的 bean 定義和專門的應用配 置選項組成。

SpringXML 配置的主要目的時候是使所有的 Spring 組件都可以用 xml 文件的形式來 進行配置。這意味著不會出現(xiàn)其他的Spring 配置類型(比如聲明的方式或基于 Java Class 的配置方式)

Spring 的 XML 配置方式是使用被 Spring 命名空間的所支持的一系列的 XML 標簽 來實現(xiàn)的。Spring 有以下主要的命名空 間:context、beans、jdbc、tx、aop、mvc 和 aso。

1. 2. 3. 4. 5. 6. 7. 8. 9.

下面這個 web.xml 僅僅配置了 DispatcherServlet,這件最簡單的配置便能滿足應用程 序配置運行時組件的需求。

1.<web-app>

2.?<display-name>Archetype?Created?Web

Application</display-name>

3.

4.?<servlet>

5.?<servlet-name>spring</servlet-name>

6.?<servlet-class>

7.

org.springframework.web.servlet.DispatcherServlet

8.?</servlet-class>

9.?<load-on-startup>1</load-on-startup>

10.?</servlet>

11.

12.?<servlet-mapping>

13.?<servlet-name>spring</servlet-name>

14.?<url-pattern>/</url-pattern>

15.?</servlet-mapping>

16.

17.?</web-app>

復制代碼

8? 、如何用基于 Java 置 配置的方式配置 Spring ?

Spring 對 Java 配置的支持是由@Configuration 注解和 @Bean 注解來實現(xiàn)的。由 @Bean 注解的方法將會實例化、配置和初始化一個新對象,這個對象將由 Spring 的 IoC 容器來管理。@Bean 聲明所起到的作用與元素類似。被 @Configuration 所注解的類則 表示這個類的主要目的是作為 bean 定義的資源。被@Configuration 聲明的類可以通過 在同一個類的內部調用@bean 方法來設置嵌入 bean 的依賴關系。

最簡單的@Configuration 聲明類請參考下面的代碼:

1.?@Configuration

2.?public?class?AppConfig

3.?{

4.?@Bean

5.?public?MyService?myService()?{

6.?return?new?MyServiceImpl();

7.?}

8.?}

復制代碼

對于上面的@Beans 配置文件相同的 XML 配置文件如下:

1.?<beans>

2.?<bean?id="myService"

class="com.howtodoinjava.services.MyServiceImpl"/>

3.?</beans>

復制代碼

上述配置方式的實例化方式如下:利用 AnnotationConfigApplicationContext 類進行實例化

1.?public?static?void?main(String[]?args)?{

2.?ApplicationContext?ctx?=?new

AnnotationConfigApplicationContext(AppConfig.class);

3.?MyService?myService?=?ctx.getBean(MyService.class);

4.?myService.doStuff();

5.?}

復制代碼

要使用組件組建掃描,僅需用@Configuration 進行注解即可:

1.?@Configuration

2.?@ComponentScan(basePackages?=?"com.howtodoinjava")

3.?public?class?AppConfig?{

4.?...

5.?}

復制代碼

在上面的例子中,com.acme 包首先會被掃到,然后再容器內查找被@Component 聲 明的類,找到后將這些類按照 Sring bean 定義進行注冊。

如 果 你 要 在 你 的 web 應 用 開 發(fā) 中 選 用 上 述 的 配 置 的 方 式 的 話 , 需 要 用 AnnotationConfigWebApplicationContext 類 來 讀 取 配 置 文 件 , 可 以 用 來 配 置 Spring 的 Servlet 監(jiān) 聽 器 ContrextLoaderListener 或 者 Spring MVC 的 DispatcherServlet。

1.?<web-app>

2.?<!--?Configure?ContextLoaderListener?to?use

AnnotationConfigWebApplicationContext

3.?instead?of?the?default?XmlWebApplicationContext

-->

4.?<context-param>

5.?<param-name>contextClass</param-name>

6.?<param-value>

7.

org.springframework.web.context.support.AnnotationConf?igWebApplicationContext

8.?</param-value>

9.?</context-param>

10.

11.?<!--?Configuration?locations?must?consist?of?one?or?more?comma-?or?space-delimited

12.?fully-qualified?@Configuration?classes.?Fully-qualified?packages?may?also?be

13.?specified?for?component-scanning?-->

14.?<context-param>

15.?<param-

name>contextConfigLocation</param-name>

16.?<param-

value>com.howtodoinjava.AppConfig</param-value>

17.?</context-param>

18.

19.?<!--?Bootstrap?the?root?application?context?as?usual?using?ContextLoaderListener

-->

20.?<listener>

21.?<listener-

class>org.springframework.web.context.ContextLoaderLis

tener</listener-class>

22.?</listener>

23.

24.?<!--?Declare?a?Spring?MVC?DispatcherServlet?as

usual?-->

25.?<servlet>

26.?<servlet-name>dispatcher</servlet-name>

27.?<servlet-

class>org.springframework.web.servlet.DispatcherServle

t</servlet-class>

28.?<!--?Configure?DispatcherServlet?to?use

AnnotationConfigWebApplicationContext

29.?instead?of?the?default

XmlWebApplicationContext?-->

30.?<init-param>

31.?<param-name>contextClass</param-

name>

32.?<param-value>

33.

org.springframework.web.context.support.AnnotationConf?igWebApplicationContext

34.?</param-value>

35.?</init-param>

36.?<!--?Again,?config?locations?must?consist

of?one?or?more?comma-?or?space-delimited

37.?and?fully-qualified?@Configuration

classes?-->

38.?<init-param>

39.?<param-

name>contextConfigLocation</param-name>

40.?<param-

value>com.howtodoinjava.web.MvcConfig</param-value>

41.?</init-param>

42.?</servlet>

43.

44.?<!--?map?all?requests?for?/app/*?to?the

dispatcher?servlet?-->

45.?<servlet-mapping>

46.?<servlet-name>dispatcher</servlet-name>

47.?<url-pattern>/app/*</url-pattern>

48.?</servlet-mapping>

49.?</web-app>

復制代碼

9 、怎樣用注解的方式配置 Spring ?

Spring 在 2.5 版本以后開始支持用注解的方式來配置依賴注入。可以用注解的方式來替代 XML 方式的 bean 描述,可以將 bean 描述轉移到組件類的內部,只需要在相關類上、方法上或者字段聲明上使用注解即可。注解注入將會被容器在 XML 注入之前被處理,所以 后者會覆蓋掉前者對于同一個屬性的處理結果。

注解裝配在 Spring 中是默認關閉的。所以需要在 Spring 文件中配置一下才能使用基于 注解的裝配模式。如果你想要在你的應用程序中使用關于注解的方法的話,請參考如下的 配置。

1.?<beans>

2.

3.?<context:annotation-config/>

4.?<!--?bean?definitions?go?here?-->

5.

6.?</beans>

復制代碼

在標簽配置完成以后,就可以用注解的方式在 Spring 中向屬性、方法和構造方法中自 動裝配變量。

下面是幾種比較重要的注解類型:

@Required:該注解應用于設值方法。

@Autowired:該注解應用于有值設值方法、非設值方法、構造方法和變量。

@Qualifier:該注解和@Autowired 注解搭配使用,用于消除特定 bean 自動裝配的歧 義。

JSR-250 Annotations:Spring 支持基于 JSR-250 注解的以 下注解,@Resource、@PostConstruct 和@PreDestroy。

10 ,請解釋 Spring Bean 的生命周期?

Spring Bean 的生命周期簡單易懂。在一個 bean 實例被初始化時,需要執(zhí)行一系列的 初始化操作以達到可用的狀態(tài)。同樣的,當一個 bean 不在被調用時需要進行相關的析構 操作,并從 bean 容器中移除。

Spring bean factory 負責管理在 spring 容器中被創(chuàng)建的 bean 的生命周期。 Bean 的生命周期由兩組回調(call back)方法組成。

初始化之后調用的回調方法。?

銷毀之前調用的回調方法。

Spring 框架提供了以下四種方式來管理 bean 的生命周期事件:

InitializingBean 和 DisposableBean 回調接口?

針對特殊行為的其他 Aware 接口

Bean 配置文件中的 Custom init()方法和 destroy()方法

@PostConstruct 和@PreDestroy 注解方式?

使用 customInit()和

customDestroy()方法管理 bean 生命周期的代碼樣例如下:

1.?<beans>

2.?<bean?id="demoBean"

class="com.howtodoinjava.task.DemoBean"

3.?init-method="customInit"?destroy-method="customDestroy"></bean>

4.?</beans>

復制代碼

更多內容請參考:Spring 生命周期 Spring Bean Life Cycle。

1.?https://howtodoinjava.com/spring-core/spring-bean-life-cycle/

復制代碼

11 、Spring Bean 的作用域之間有什么區(qū)別?

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

?singleton:這種 bean 范圍是默認的,這種范圍確保不管接受到多少個請求,每個容器中 只有一個 bean 的實例,單例的模式由 bean factory 自身來維護。

prototype:原形范圍與單例范圍相反,為每一個 bean 請求提供一個實例。

request:在請求 bean 范圍內會每一個來自客戶端的網絡請求創(chuàng)建一個實例,在請求 完成以后,bean 會失效并被垃圾回收器回收。

Session:與請求范圍類似,確保每個 session 中有一個 bean 的實例,在 session 過期后,bean 會隨之失效。

global-session:global-session 和 Portlet 應用相關。當你的應用部署在 Portlet 容器 中工作時,它包含很多 portlet。如果你想要聲明讓所有的 portlet 共用全局的存儲變量 的話,那么這全局變量需要存儲在 global-session 中。

全局作用域與 Servlet 中的 session 作用域效果相同。

更多內容請參考 : Spring Bean Scopes。

1.?https://howtodoinjava.com/spring-core/spring-bean-scopes/

復制代碼

12是 、什么是 Spring inner beans ?

在 Spring 框架中,無論何時 bean 被使用時,當僅被調用了一個屬性。一個明智的 做法是將這個 bean 聲明為內部bean。內部 bean 可以用 setter 注入“屬性”和構造方法注入“構造參數(shù)”的方式來 實現(xiàn)。

比如,在我們的應用程序中,一個 Customer 類引用了一個 Person 類,我們的要做的 是創(chuàng)建一個 Person 的實例,然后在 Customer 內部使用。

1.?public?class?Customer

2.?{

3.?private?Person?person;

4.

5.?//Setters?and?Getters

6.?}

1.?public?class?Person

2.?{

3.?private?String?name;

4.?private?String?address;

5.?private?int?age;

6.

7.?//Setters?and?Getters

8.?}

復制代碼

內部 bean 的聲明方式如下:

1.?<bean?id="CustomerBean"

class="com.howtodoinjava.common.Customer">

2.?<property?name="person">

3.?<!--?This?is?inner?bean?-->

4.?<bean?class="com.howtodoinjava.common.Person">

5.?<property?name="name"?value="lokesh"?/>

6.?<property?name="address"?value="India"?/>

7.?<property?name="age"?value="34"?/>

8.?</bean>

9.?</property>

10.?</bean>

復制代碼

13 、Spring 例 框架中的單例 Beans 是線程安全的么?

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

最淺顯的解決辦法就是將多態(tài) bean 的作用域由“singleton” 變更為“prototype”。

14在 、請舉例說明如何在 Spring 個 中注入一個 Java Collection

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

: 該標簽用來裝配可重復的 list 值。

: 該標簽用來裝配沒有重復的 set 值。

- : 該標簽支持注入鍵和值都是字符串類型的鍵值對。

下面看一下具體的例子:

1.?<beans>

2.

3.?<!--?Definition?for?javaCollection?-->

4.?<bean?id="javaCollection"

class="com.howtodoinjava.JavaCollection">

5.

6.?<!--?java.util.List?-->

7.?<property?name="customList">

8.?<list>

9.?<value>INDIA</value>

10.?<value>Pakistan</value>

11.?<value>USA</value>

12.?<value>UK</value>

13.?</list>

14.?</property>

15.

16.?<!--?java.util.Set?-->

17.?<property?name="customSet">

18.?<set>

19.?<value>INDIA</value>

20.?<value>Pakistan</value>

21.?<value>USA</value>

22.?<value>UK</value>

23.?</set>

24.?</property>

25.

26.?<!--?java.util.Map?-->

27.?<property?name="customMap">

28.?<map>

29.?<entry?key="1"?value="INDIA"/>

30.?<entry?key="2"?value="Pakistan"/>

31.?<entry?key="3"?value="USA"/>

32.?<entry?key="4"?value="UK"/>

33.?</map>

34.?</property>

35.

36.?<!--?java.util.Properties?-->

37.?<property?name="customProperies">

38.?<props>

39.?<prop

key="admin">admin@nospam.com</prop>

40.?<prop

key="support">support@nospam.com</prop>

41.?</props>

42.?</property>

43.

44.?</bean>

45.

46.?</beans>

復制代碼

15、如何向 Spring Bean 個 中注入一個 Java.util.Properties

第一種方法是使用如下面代碼所示的標簽:

1.?<bean?id="adminUser"

class="com.howtodoinjava.common.Customer">

2.

3.?<!--?java.util.Properties?-->

4.?<property?name="emails">

5.?<props>

6.?<prop?key="admin">admin@nospam.com</prop>

7.?<prop

key="support">support@nospam.com</prop>

8.?</props>

9.?</property>

10.

11.?</bean>

復制代碼

也可用”util:”命名空間來從 properties 文件中創(chuàng)建出一個 propertiesbean,然后利 用 setter 方法注入 bean 的引用。

16、請解釋 Spring Bean 的自動裝配?

在 Spring 框架中,在配置文件中設定 bean 的依賴關系是一個很好的機制,Spring 容 器還可以自動裝配合作關系 bean 之間的關聯(lián)關系。這意味著 Spring 可以通過向 Bean Factory 中注入的方式自動搞定 bean 之間的依賴關系。自動裝配可以設置在每個 bean 上,也可以設定在特定的 bean 上。

下面的 XML 配置文件表明了如何根據(jù)名稱將一個 bean 設置為自動裝配:

1.?<bean?id="employeeDAO"

class="com.howtodoinjava.EmployeeDAOImpl"?autowire="byName"

/>

復制代碼

除了 bean 配置文件中提供的自動裝配模式,還可以使用 @Autowired 注解來自動裝 配指定的 bean。在使用 @Autowired 注解之前需要在按照如下的配置方式在 Spring 配置文件進行配置才可以使用。

1.?<context:annotation-config?/>

復制代碼

也可以通過在配置文件中配置 AutowiredAnnotationBeanPostProcessor 達到相 同的效果。

1.?<bean?class

="org.springframework.beans.factory.annotation.Autowir

edAnnotationBeanPostProcessor"/>

復制代碼

配置好以后就可以使用@Autowired 來標注了。

1.?@Autowired

2.?public?EmployeeDAOImpl?(?EmployeeManager?manager?)?{

3.?this.manager?=?manager;

4.?}

復制代碼

17 、請解釋自動裝配模式的區(qū)別?

在 Spring 框架中共有 5 種自動裝配,讓我們逐一分析。

?no:這是 Spring 框架的默認設置,在該設置下自動裝配是關閉的,開發(fā)者需要自行在 bean 定義中用標簽明確的設置依賴關系。

byName:該選項可以根據(jù) bean 名稱設置依賴關系。當向一個 bean 中自動裝配一個 屬性時,容器將根據(jù) bean 的名稱自動在在配置文件中查詢一個匹配的 bean。如果找 到的話,就裝配這個屬性,如果沒找到的話就報錯。

byType:該選項可以根據(jù) bean 類型設置依賴關系。當向一個 bean 中自動裝配一個屬 性時,容器將根據(jù) bean 的類型自動在在配置文件中查詢一個匹配的 bean。如果找到的 話,就裝配這個屬性,如果沒找到的話就報錯。

constructor:造器的自動裝配和 byType 模式類似,但是僅僅適用于與有構造器相同 參數(shù)的 bean,如果在容器中沒有找到與構造器參數(shù)類型一致的 bean,那么將會拋出異 常。

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

18 、如何開啟基于注解的自動裝配?

要使用 @Autowired,需要注冊 AutowiredAnnotationBeanPostProcessor,可以有 以下兩種方式來實現(xiàn):

1、引入配置文件中的下引入

1.?<beans>

2.?<context:annotation-config?/>

3.?</beans>

復制代碼

2 、 在 bean 配 置 文 件 中 直 接 引 入 AutowiredAnnotationBeanPostProcessor

1.?<beans>

2.?<bean

class="org.springframework.beans.factory.annotation.Au

towiredAnnotationBeanPostProcessor"/>

3.?</beans>

復制代碼

19 、請舉例解釋@Required 注解?

在產品級別的應用中,IoC 容器可能聲明了數(shù)十萬了 bean, bean 與 bean 之間有 著復雜的依賴關系。設值注解方法的短板之一就是驗證所有的屬性是否被注解是一項十分困難的操作。可以通過在中設置 “dependency-check”來解決這個問題。

在應用程序的生命周期中,你可能不大愿意花時間在驗證所有 bean 的屬性是否按照上下 文文件正確配置。或者你寧可驗證某個 bean 的特定屬性是否被正確的設置。即使是用 “dependency-check”屬性也不能很好的解決這個問題,在這種情況下,你需要使用 @Required 注解。

需要用如下的方式使用來標明 bean 的設值方法。

1.?public?class?EmployeeFactoryBean?extends

AbstractFactoryBean<Object>

2.?{

3.?private?String?designation;

4.

5.?public?String?getDesignation()?{

6.?return?designation;

7.?}

8.

9.?@Required

10.?public?void?setDesignation(String

designation)?{

11.?this.designation?=?designation;

12.?}

13.

14.?//more?code?here

15.?}

復制代碼

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

1.?<bean

class="org.springframework.beans.factory.annotation.Re

quiredAnnotationBeanPostProcessor"?/>

復制代碼

但 是 如 果 沒 有 屬 性 被 用 @Required 注 解 過 的 話 , 后 置 處 理 器 會 拋 出 一 個 BeanInitializationException 異常。

20 、請舉例解釋@Autowired 注解?

@Autowired 注解對自動裝配何時何處被實現(xiàn)提供了更多細粒度的控制。@Autowired注解可以像@Required 注解、構造器一樣被用于在 bean 的設值方法上自動裝配 bean 的屬性,一個參數(shù)或者帶有任意名 稱或帶有多個參數(shù)的方法。

比如,可以在設值方法上使用@Autowired 注解來替代配置文件中的元素。當 Spring 容 器在 setter 方法上找到 @Autowired 注解時,會嘗試用 byType 自動裝配。

當然我們也可以在構造方法上使用@Autowired 注解。帶有 @Autowired 注解的構造方 法意味著在創(chuàng)建一個 bean 時將會被自動裝配,即便在配置文件中使用 元素。

1.?public?class?TextEditor?{

2.?private?SpellChecker?spellChecker;

3.

4.?@Autowired

5.?public?TextEditor(SpellChecker?spellChecker){

6.?System.out.println("Inside?TextEditor?constructor."?);

7.?this.spellChecker?=?spellChecker;

8.?}

9.

10.?public?void?spellCheck(){

11.?spellChecker.checkSpelling();

12.?}

13.?}

復制代碼

下面是沒有構造參數(shù)的配置方式:

1.?<beans>

2.

3.?<context:annotation-config/>

4.

5.?<!--?Definition?for?textEditor?bean?without?constructor-arg?-->

6.?<bean?id="textEditor"

class="com.howtodoinjava.TextEditor">

7.?</bean>

8.

9.?<!--?Definition?for?spellChecker?bean?-->

10.?<bean?id="spellChecker"

class="com.howtodoinjava.SpellChecker">

11.?</bean>

12.

13.?</beans>

復制代碼

21、請舉例說明@Qualifier 注解?

@Qualifier 注解意味著可以在被標注 bean 的字段上可以自動裝配。Qualifier 注解可以 用來取消 Spring 不能取消的 bean 應用。

下面的示例將會在 Customer 的 person 屬性中自動裝配 person 的值。

1.?public?class?Customer

2.?{

3.?@Autowired

4.?private?Person?person;

5.?}

復制代碼

下面我們要在配置文件中來配置 Person 類。

1.?<bean?id="customer"

class="com.howtodoinjava.common.Customer"?/>

2.

3.?<bean?id="personA"

class="com.howtodoinjava.common.Person"?>

4.?<property?name="name"?value="lokesh"?/>

5.?</bean>

6.

7.?<bean?id="personB"

class="com.howtodoinjava.common.Person"?>

8.?<property?name="name"?value="alex"?/>

9.?</bean>

復制代碼

Spring 會知道要自動裝配哪個 person bean 么?不會的,但是運行上面的示例時,會 拋出下面的異常:

1.?Caused?by:

org.springframework.beans.factory.NoSuchBeanDefinition?Exception:

2.?No?unique?bean?of?type

[com.howtodoinjava.common.Person]?is?defined:

3.?expected?single?matching?bean?but?found?2:

[personA,?personB]

復制代碼

要解決上面的問題,需要使用 @Quanlifier 注解來告訴 Spring 容器要裝配哪個 bean:

1.?public?class?Customer

2.?{

3.?@Autowired

4.?@Qualifier("personA")

5.?private?Person?person;

6.?}

復制代碼

22 、構造方法注入和設值注入有什么區(qū)別?

請注意以下明顯的區(qū)別:

1. 在設值注入方法支持大部分的依賴注入,如果我們僅需要注入 int、string 和 long 型的 變量,我們不要用設值的方法注入。對于基本類型,如果我們沒有注入的話,可以為基本 類型設置默認值。在構造方法注入不支持大部分的依賴注入,因為在調用構造方法中必須 傳入正確的構造參數(shù),否則的話為報錯。

2. 設值注入不會重寫構造方法的值。如果我們對同一個變量同時使用了構造方法注入又使用 了設置方法注入的話,那么構造方法將不能覆蓋由設值方法注入的值。很明顯,因為構造 方法盡在對象被創(chuàng)建時調用。

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

4. 在設值注入時如果對象 A 和對象 B 互相依賴,在創(chuàng)建對象 A 時 Spring 會拋出 sObjectCurrentlyInCreationException 異 常,因為在 B 對象被創(chuàng)建之前 A 對象是不能被創(chuàng)建的,反之亦然。所以 Spring 用設值注入的方法解決了循環(huán)依賴的問題,因對象的設值方法是在對 象被創(chuàng)建之前被調用的。

23 、Spring 框架中有哪些不同類型的事件?

Spring 的 ApplicationContext 提供了支持事件和代碼中監(jiān)聽器的功能。 我們可以創(chuàng)建 bean 用來監(jiān)聽在 ApplicationContext 中發(fā)布的事件。ApplicationEvent 類和在 ApplicationContext 接口中處理的事件,如果一個 bean 實現(xiàn)了 ApplicationListener 接口,當一個 ApplicationEvent 被發(fā)布以后,bean 會自動被通知。

1.?public?class?AllApplicationEventListener?implements?ApplicationListener?<

ApplicationEvent?>

2.?{

3.?@Override

4.?public?void?onApplicationEvent(ApplicationEvent?applicationEvent)

5.?{

6.?//process?event

7.?}

8.?}

復制代碼

Spring 提供了以下 5 中標準的事件:

上下文更新事件(ContextRefreshedEvent):該事件會在 ApplicationContext 被初始化或者更新時發(fā)布。也可以在調 用 ConfigurableApplicationContext 接口中的 refresh()方法時被觸發(fā)。

上下文開始事件(ContextStartedEvent):當容器調用 ConfigurableApplicationContext 的 Start()方法開始/重新開始容器時觸發(fā)該事件。

上 下 文 停 止 事 件 ( ContextStoppedEvent ) : 當 容 器 調 用 ConfigurableApplicationContext 的 Stop()方法停止容器時觸發(fā)該事件。

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

請求處理事件(RequestHandledEvent):在 Web 應用中,當一個 http 請求(request) 結束觸發(fā)該事件。

除了上面介紹的事件以外,還可以通過擴展 ApplicationEvent 類來開發(fā)自定義的事件。

1.?public?class?CustomApplicationEvent?extends?ApplicationEvent

2.?{

3.?public?CustomApplicationEvent?(?Object?source,?final?String?msg?)

4.?{

5.?super(source);

6.?System.out.println("Created?a?Custom?event");

7.?}

8.?}

復制代碼

為了監(jiān)聽這個事件,還需要創(chuàng)建一個監(jiān)聽器:

1.?public?class?CustomEventListener?implements?ApplicationListener?<

CustomApplicationEvent?>

2.?{

3.?@Override

4.?public?void

onApplicationEvent(CustomApplicationEvent?applicationEvent)

{

5.?//handle?event

6.?}

7.?}

復制代碼

之后通過 applicationContext 接口的 publishEvent()方法來發(fā)布自定義事件。

1.?CustomApplicationEvent?customEvent?=?new

CustomApplicationEvent(applicationContext,?"Test?message");

2.?applicationContext.publishEvent(customEvent);

復制代碼

24 、FileSystemResource 和 和 ClassPathResource 有何區(qū)別?

在 FileSystemResource 中需要給出 spring-config.xml 文件在你項目中的相對路徑或 者絕對路徑。在 ClassPathResource

中 spring 會在 ClassPath 中自動搜尋配置文件,所以要把 ClassPathResource 文件放在 ClassPath 下。

如果將 spring-config.xml 保存在了 src 文件夾下的話,只需給出配置文件的名稱即 可,因為 src 文件夾是默認。

簡而言之,ClassPathResource 在環(huán)境變量中讀取配置文件, FileSystemResource 在 配置文件中讀取配置文件。

25 、Spring 框架中都用到了哪些設計模式?

Spring 框架中使用到了大量的設計模式,下面列舉了比較有代表性的:

代理模式—在 AOP 和 remoting 中被用的比較多。

單例模式—在 spring 配置文件中定義的 bean 默認為單例模式。

模板方法—用來解決代碼重復的問題。比如. RestTemplate, JmsTemplate, JpaTemplate。

前端控制器—Spring 提供了 DispatcherServlet 來對請求進行分發(fā)。

視圖幫助(View Helper )—Spring 提供了一系列的 JSP 標簽,高效宏來輔助將分 散的代碼整合在視圖里。

依賴注入—貫穿于 BeanFactory / ApplicationContext 接口的核心理念。

工廠模式—BeanFactory 用來創(chuàng)建對象的實例。

最后

感謝大家看到這里,文章有不足,歡迎大家指出;如果你覺得寫得不錯,那就給我一個贊吧。

也歡迎大家關注我的公眾號:Java程序員聚集地,每天都會分享java相關技術文章或行業(yè)資訊,歡迎大家關注和轉發(fā)文章!

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,882評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,208評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,746評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,666評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,477評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,960評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,047評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,200評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 48,726評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,617評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,807評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,327評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,049評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,425評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,674評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,432評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,769評論 2 372

推薦閱讀更多精彩內容