前言
文章內容有點小長,希望你能耐心閱讀,更多Java面試題以及學習資料獲取方式:加Qun:1017-599-436免費獲取。
?還有更多包括電子書,PDF文檔以及視頻精講可以分享給大家,內容覆蓋很廣,分布式緩存、RPC 調用、Zookeeper、消息隊列、分布式搜索引擎、分布式 session、分庫分表等。
話不多說,進入正文!
以下為 spring 常見面試問題:
1、什么是 Spring 框架?Spring 框架有哪些主要模塊?
Spring 框架是一個為 Java 應用程序的開發提供了綜合、廣泛的基礎性支持的 Java 平臺。
Spring 幫助開發者解決了開發中基礎性的問題,使得開發人員可以專注于應用程序的開發。
Spring 框架本身亦是按照設計模式精心打造,這使得我們可以在開發環境中安心的集成 Spring 框
架,不必擔心 Spring 是如何在后臺進行工作的。
Spring 框架至今已集成了 20 多個模塊。這些模塊主要被分如下圖所示的核心容器、數據訪問/集
成,、Web、AOP(面向切面編程)、工具、消息和測試模塊。
2、使用 Spring 框架能帶來哪些好處?
下面列舉了一些使用 Spring 框架帶來的主要好處:
? Dependency Injection(DI) 方法使得構造器和 JavaBean properties 文件中的依賴關系一
目了然。
? 與 EJB 容器相比較,IoC 容器更加趨向于輕量級。這樣一來 IoC 容器在有限的內存和 CPU 資
源的情況下進行應用程序的開發和發布就變得十分有利。
? Spring 并沒有閉門造車,Spring 利用了已有的技術比如 ORM 框架、logging 框架、J2EE、Q
uartz 和 JDK Timer,以及其他視圖技術。
? Spring 框架是按照模塊的形式來組織的。由包和類的編號就可以看出其所屬的模塊,開發者僅
僅需要選用他們需要的模塊即可。
? 要測試一項用 Spring 開發的應用程序十分簡單,因為測試相關的環境代碼都已經囊括在框架中
了。更加簡單的是,利用 JavaBean 形式的 POJO 類,可以很方便的利用依賴注入來寫入測試
數據。
? Spring 的 Web 框架亦是一個精心設計的 Web MVC 框架,為開發者們在 web 框架的選擇上
提供了一個除了主流框架比如 Struts、過度設計的、不流行 web 框架的以外的有力選項。
? Spring 提供了一個便捷的事務管理接口,適用于小型的本地事物處理(比如在單 DB 的環境
下)和復雜的共同事物處理(比如利用 JTA 的復雜 DB 環境)。
3、什么是控制反轉(IOC)?什么是依賴注入?
控制反轉是應用于軟件工程領域中的,在運行時被裝配器對象來綁定耦合對象的一種編程技巧,對
象之間耦合關系在編譯時通常是未知的。在傳統的編程方式中,業 務邏輯的流程是由應用程序中的
早已被設定好關聯關系的對象來決定的。在使用控制反轉的情況下,業務邏輯的流程是由對象關系圖來決定的,該對象關系圖由裝配 器負責實例化,這種實現方式還可以將對象之間的關聯關系的定
義抽象化。而綁定的過程是通過“依賴注入”實現的。
控制反轉是一種以給予應用程序中目標組件更多控制為目的設計范式,并在我們的實際工作中起到
了有效的作用。
依賴注入是在編譯階段尚未知所需的功能是來自哪個的類的情況下,將其他對象所依賴的功能對象
實例化的模式。這就需要一種機制用來激活相應的組件以提供特定的功能,所以依賴注入是控制反
轉的基礎。否則如果在組件不受框架控制的情況下,框架又怎么知道要創建哪個組件?
在 Java 中依然注入有以下三種實現方式:
1. 構造器注入
2. Setter 方法注入
3. 接口注入
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 容器的具體實現,
用來包裝和管理前面提到的各種 bean。BeanFactory 接口是 Spring IoC 容器的核心接口。
IOC:把對象的創建、初始化、銷毀交給 spring 來管理,而不是由開發者控制,實現控制反轉。
5、BeanFactory 和 ApplicationContext 有什么區別?
BeanFactory 可以理解為含有 bean 集合的工廠類。BeanFactory 包含了種 bean 的定義,以便
在接收到客戶端請求時將對應的 bean 實例化。
BeanFactory 還能在實例化對象的時生成協作類之間的關系。此舉將 bean 自身與 bean 客戶端的
配置中解放出來。BeanFactory 還包含 了 bean 生命周期的控制,調用客戶端的初始化方法
(initialization methods)和銷毀方法(destruction methods)。
從表面上看,application context 如同 bean factory 一樣具有 bean 定義、bean 關聯關系的設
置,根據請求分發 bean 的功能。但 applicationcontext 在此基礎上還提供了其他的功能。
1. 提供了支持國際化的文本消息
2. 統一的資源文件讀取方式
3. 已在監聽器中注冊的 bean 的事件以下是三種較常見的 ApplicationContext 實現方式:
1、ClassPathXmlApplicationContext:從 classpath 的 XML 配置文件中讀取上下文,并生成上
下文定義。應用程序上下文從程序環境變量中
ApplicationContext context = new
ClassPathXmlApplicationContext(“bean.xml”);
2、FileSystemXmlApplicationContext :由文件系統中的 XML 配置文件讀取上下文。
ApplicationContext context = new
FileSystemXmlApplicationContext(“bean.xml”);
3、XmlWebApplicationContext:由 Web 應用的 XML 文件讀取上下文。
4.AnnotationConfigApplicationContext(基于 Java 配置啟動容器)
6、Spring 有幾種配置方式?
將 Spring 配置到應用開發中有以下三種方式:
1. 基于 XML 的配置
2. 基于注解的配置
3. 基于 Java 的配置
7、如何用基于 XML 配置的方式配置 Spring?
在 Spring 框架中,依賴和服務需要在專門的配置文件來實現,我常用的 XML 格式的配置文件。這
些配置文件的格式通常用<beans>開頭,然后一系列的 bean 定義和專門的應用配置
選項組成。
SpringXML 配置的主要目的時候是使所有的 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.MappingJackson2JsonV
iew"/>
<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>
8、如何用基于 Java 配置的方式配置 Spring?
Spring 對 Java 配置的支持是由@Configuration 注解和@Bean 注解來實現的。由@Bean 注解
的方法將會實例化、配置和初始化一個 新對象,這個對象將由 Spring 的 IoC 容器來管理。
@Bean 聲明所起到的作用與<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.somnus.services.MyServiceImpl"/>
</beans>
上述配置方式的實例化方式如下:利用 AnnotationConfigApplicationContext 類進行實例化
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.somnus")
public class AppConfig {
...
}
在上面的例子中,com.acme 包首先會被掃到,然后再容器內查找被@Component 聲明的類,找
到后將這些類按照 Sring bean 定義進行注冊。
如果你要在你的 web 應用開發中選用上述的配置的方式的話,需要用
AnnotationConfigWebApplicationContext 類來讀 取配置文件,可以用來配置 Spring 的
Servlet 監聽器 ContextLoaderListener 或者 Spring MVC 的 DispatcherServlet。
<web-app>
<!-- Configure ContextLoaderListener to use
AnnotationConfigWebApplicationContext
instead of the default XmlWebApplicationContext -->
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicatio
nContext
</param-value>
</context-param>
<!-- Configuration locations must consist of one or more comma- or
space-delimited
fully-qualified @Configuration classes. Fully-qualified
packages may also be
specified for component-scanning -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.howtodoinjava.AppConfig</param-value>
</context-param>
<!-- Bootstrap the root application context as usual using
ContextLoaderListener --><listener>
<listener
class>org.springframework.web.context.ContextLoaderListener</listener
-class>
</listener>
<!-- Declare a Spring MVC DispatcherServlet as usual -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet
class>org.springframework.web.servlet.DispatcherServlet</servlet
class>
<!-- Configure DispatcherServlet to use
AnnotationConfigWebApplicationContext
instead of the default XmlWebApplicationContext -->
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicatio
nContext
</param-value>
</init-param>
<!-- Again, config locations must consist of one or more comma
or space-delimited
and fully-qualified @Configuration classes -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.howtodoinjava.web.MvcConfig</param
value>
</init-param>
</servlet>
<!-- map all requests for /app/* to the dispatcher servlet -->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
</web-app
9、怎樣用注解的方式配置 Spring?
Spring 在 2.5 版本以后開始支持用注解的方式來配置依賴注入。可以用注解的方式來替代 XML 方
式的 bean 描述,可以將 bean 描述轉移到組件類的 內部,只需要在相關類上、方法上或者字段聲
明上使用注解即可。注解注入將會被容器在 XML 注入之前被處理,所以后者會覆蓋掉前者對于同一
個屬性的處理結 果。
注解裝配在 Spring 中是默認關閉的。所以需要在 Spring 文件中配置一下才能使用基于注解的裝配
模式。如果你想要在你的應用程序中使用關于注解的方法的話,請參考如下的配置。
<beans>
<context:annotation-config/>
<!-- bean definitions go here -->
</beans>
在 <context:annotation-config/>標簽配置完成以后,就可以用注解的方式在 Spring 中向屬
性、方法和構造方法中自動裝配變量。
下面是幾種比較重要的注解類型:
1. @Required:該注解應用于設值方法。
2. @Autowired:該注解應用于有值設值方法、非設值方法、構造方法和變量。
3. @Qualifier:該注解和@Autowired 注解搭配使用,用于消除特定 bean 自動裝配的歧義。
4. JSR-250 Annotations:Spring 支持基于 JSR-250 注解的以下注解,@Resource、
@PostConstruct 和 @PreDestroy。
10、請解釋 Spring Bean 的生命周期?
Spring Bean 的生命周期簡單易懂。在一個 bean 實例被初始化時,需要執行一系列的初始化操作
以達到可用的狀態。同樣的,當一個 bean 不在被調用時需要進行相關的析構操作,并從 bean 容
器中移除。
Spring bean factory 負責管理在 spring 容器中被創建的 bean 的生命周期。Bean 的生命周期
由兩組回調(call back)方法組成。
1. 初始化之后調用的回調方法。
2. 銷毀之前調用的回調方法。
Spring 框架提供了以下四種方式來管理 bean 的生命周期事件:
? InitializingBean 和 DisposableBean 回調接口
? 針對特殊行為的其他 Aware 接口
? Bean 配置文件中的 Custom init()方法和 destroy()方法? @PostConstruct 和@PreDestroy 注解方式
使用 customInit()和 customDestroy()方法管理 bean 生命周期的代碼樣例如
下:
<beans>
<bean id="demoBean" class="com.somnus.task.DemoBean" init
method="customInit" destroy-method="customDestroy"></bean>
</beans>
11、Spring Bean 的作用域之間有什么區別?
Spring 容器中的 bean 可以分為 5 個范圍。所有范圍的名稱都是自說明的,但是為了避免混淆,還
是讓我們來解釋一下:
1. singleton:這種 bean 范圍是默認的,這種范圍確保不管接受到多少個請求,每個容器中只有一個
bean 的實例,單例的模式由 bean factory 自身來維護。
2. prototype:原形范圍與單例范圍相反,為每一個 bean 請求提供一個實例。
3. request:在請求 bean 范圍內會每一個來自客戶端的網絡請求創建一個實例,在請求完成以后,
bean 會失效并被垃圾回收器回收。
4. Session:與請求范圍類似,確保每個 session 中有一個 bean 的實例,在 session 過期后,bean
會隨之失效。
5. global- session:global-session 和 Portlet 應用相關。當你的應用部署在 Portlet 容器中工作
時,它包含很多 portlet。如果 你想要聲明讓所有的 portlet 共用全局的存儲變量的話,那么這全
局變量需要存儲在 global-session 中。
全局作用域與 Servlet 中的 session 作用域效果相同。
12、什么是 Spring inner beans?
在 Spring 框架中,無論何時 bean 被使用時,當僅被調用了一個屬性。一個明智的做法是將這個
bean 聲明為內部 bean。內部 bean 可以用 setter 注入“屬性”和構造方法注入“構造參數”的方式來
實現。
比如,在我們的應用程序中,一個 Customer 類引用了一個 Person 類,我們的要做的是創建一個
Person 的實例,然后在 Customer 內部使用。
public class Customer{
private Person person;
//Setters and Getters}
public class Person{
private String name;
private String address;
private int age;
//Setters and Getters
}
內部 bean 的聲明方式如下:
<bean id="CustomerBean" class="com.somnus.common.Customer">
<property name="person">
<!-- This is inner bean -->
<bean class="com.howtodoinjava.common.Person">
<property name="name" value="lokesh" />
<property name="address" value="India" />
<property name="age" value="34" />
</bean>
</property>
</bean>
13、Spring 框架中的單例 Beans 是線程安全的么?
Spring 框架并沒有對單例 bean 進行任何多線程的封裝處理。關于單例 bean 的線程安全和并發問
題需要開發者自行去搞定。但實際上,大部分的 Spring bean 并沒有可變的狀態(比如 Serview 類
和 DAO 類),所以在某種程度上說 Spring 的單例 bean 是線程安全的。如果你的 bean 有多種狀
態的話(比如 View Model 對象),就需要自行保證線程安全。
最淺顯的解決辦法就是將多態 bean 的作用域由“singleton”變更為“prototype”。
14、請舉例說明如何在 Spring 中注入一個 Java Collection?
Spring 提供了以下四種集合類的配置元素:
? <list> : 該標簽用來裝配可重復的 list 值。
? <set> : 該標簽用來裝配沒有重復的 set 值。
? <map>: 該標簽可用來注入鍵和值可以為任何類型的鍵值對。
? <props> : 該標簽支持注入鍵和值都是字符串類型的鍵值對。
下面看一下具體的例子:
<beans>
<!-- Definition for javaCollection -->
<bean id="javaCollection" class="com.howtodoinjava.JavaCollection">
<!-- java.util.List -->
<property name="customList">
<list>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>UK</value>
</list>
</property>
<!-- java.util.Set -->
<property name="customSet">
<set>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>UK</value>
</set>
</property>
<!-- java.util.Map -->
<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>
<!-- java.util.Properties -->
<property name="customProperies">
<props>
<prop key="admin">admin@nospam.com</prop>
<prop key="support">support@nospam.com</prop>
</props>
</property>
</bean>
</beans>
15、如何向 Spring Bean 中注入一個 Java.util.Properties?
第一種方法是使用如下面代碼所示的<props> 標簽:
<bean id="adminUser" class="com.somnus.common.Customer">
<!-- java.util.Properties -->
<property name="emails">
<props>
<prop key="admin">admin@nospam.com</prop>
<prop key="support">support@nospam.com</prop>
</props>
</property>
</bean>
也可用”util:”命名空間來從 properties 文件中創建出一個 propertiesbean,然后利用 setter 方
法注入 bean 的引用。
16、請解釋 Spring Bean 的自動裝配?
在 Spring 框架中,在配置文件中設定 bean 的依賴關系是一個很好的機制,Spring 容器還可以自
動裝配合作關系 bean 之間的關聯關系。這意味著 Spring 可以通過向 Bean Factory 中注入的方
式自動搞定 bean 之間的依賴關系。自動裝配可以設置在每個 bean 上,也可以設定在特定的 bean
上。
下面的 XML 配置文件表明了如何根據名稱將一個 bean 設置為自動裝配:
<bean id="employeeDAO" class="com.howtodoinjava.EmployeeDAOImpl"
autowire="byName" />
除了 bean 配置文件中提供的自動裝配模式,還可以使用@Autowired 注解來自動裝配指定
的 bean。在使用@Autowired 注解之前需要在按照如下的配置方式在 Spring 配
置文件進行配置才可以使用。
<context:annotation-config />
也可以通過在配置文件中配置 AutowiredAnnotationBeanPostProcessor 達到相同的效
果。
<bean class
="org.springframework.beans.factory.annotation.AutowiredAnnotationBea
nPostProcessor"/>
配置好以后就可以使用@Autowired 來標注了。
@Autowired
public EmployeeDAOImpl ( EmployeeManager manager ) {
this.manager = manager;
}
17、請解釋自動裝配模式的區別?
在 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:該模式自動探測使用構造器自動裝配或者 byType 自動裝配。首先,首先會嘗試找合
適的帶參數的構造器,如果找到的話就是用構造器自動裝配,如果在 bean 內部沒有找到相應的構
造器或者是無參構造器,容器就會自動選擇 byTpe 的自動裝配方式。
18、如何開啟基于注解的自動裝配?
要使用 @Autowired,需要注冊 AutowiredAnnotationBeanPostProcessor,可以
有以下兩種方式來實現:
1、引入配置文件中的<bean>下引入 <context:annotation-config>
<beans>
<context:annotation-config />
</beans>
2、在 bean 配置文件中直接引入 AutowiredAnnotationBeanPostProcessor
<beans>
<bean
class="org.springframework.beans.factory.annotation.AutowiredAnnotati
onBeanPostProcessor"/>
</beans>
19、請舉例解釋@Required 注解?
在產品級別的應用中,IoC 容器可能聲明了數十萬了 bean,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;
}
//more code here
}
RequiredAnnotationBeanPostProcessor 是 Spring 中的后置處理用來驗證被
@Required 注解的 bean 屬性是否被正確的設置了。在使用
RequiredAnnotationBeanPostProcesso 來驗證 bean 屬性之前,首先要在 IoC 容器中對
其進行注冊:
<bean
class="org.springframework.beans.factory.annotation.RequiredAnnotatio
nBeanPostProcessor" />但是如果沒有屬性被用 @Required 注解過的話,后置處理器會拋出一個
BeanInitializationException 異常。
20、請舉例解釋@Autowired 注解?
@Autowired 注解對自動裝配何時何處被實現提供了更多細粒度的控制。@Autowired 注解可
以像@Required 注解、構造器一樣被用于在 bean 的設值方法上自動裝配 bean
的屬性,一個參數或者帶有任意名稱或帶有多個參數的方法。
比如,可以在設值方法上使用@Autowired 注解來替代配置文件中的 <property>元
素。當 Spring 容器在 setter 方法上找到@Autowired 注解時,會嘗試用 byType
自動裝配。
當然我們也可以在構造方法上使用@Autowired 注解。帶有@Autowired 注解的構造方法意味著
在創建一個 bean 時將會被自動裝配,即便在配置文件中使用<constructor-arg> 元素。
public class TextEditor {
private SpellChecker spellChecker;
@Autowired
public TextEditor(SpellChecker spellChecker){
System.out.println("Inside TextEditor constructor." );
this.spellChecker = spellChecker;
}
public void spellCheck(){
spellChecker.checkSpelling();
}
}
下面是沒有構造參數的配置方式:
<beans>
<context:annotation-config/>
<!-- Definition for textEditor bean without constructor-arg -->
<bean id="textEditor" class="com.howtodoinjava.TextEditor"/>
<!-- Definition for spellChecker bean -->
<bean id="spellChecker" class="com.howtodoinjava.SpellChecker"/></beans>
21、請舉例說明@Qualifier 注解?
@Qualifier 注解意味著可以在被標注 bean 的字段上可以自動裝配。Qualifier 注
解可以用來取消 Spring 不能取消的 bean 應用。
下面的示例將會在 Customer 的 person 屬性中自動裝配 person 的值。
public class Customer{
@Autowired
private Person person;
}
下面我們要在配置文件中來配置 Person 類。
<bean id="customer" class="com.somnus.common.Customer" />
<bean id="personA" class="com.somnus.common.Person" >
<property name="name" value="lokesh" />
</bean>
<bean id="personB" class="com.somnus.common.Person" >
<property name="name" value="alex" />
</bean>Spring 會知道要自動裝配哪個 person bean 么?不會的,但是運行上面的示例
時,會拋出下面的異常:
Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No unique bean of type [com.howtodoinjava.common.Person] is defined:
expected single matching bean but found 2: [personA, personB]
要解決上面的問題,需要使用 @Quanlifier 注解來告訴 Spring 容器要裝配哪個 bean:
public class Customer{
@Autowired
@Qualifier("personA")
private Person person;
}
22、構造方法注入和設值注入有什么區別?
請注意以下明顯的區別:
1. 在設值注入方法支持大部分的依賴注入,如果我們僅需 要注入 int、string 和 long 型的變量,我
們不要用設值的方法注入。對于基本類型,如果我們沒有注入的話,可以為基本類型設置默認值。
在構造方法 注入不支持大部分的依賴注入,因為在調用構造方法中必須傳入正確的構造參數,否則
的話為報錯。
2. 設值注入不會重寫構造方法的值。如果我們對同一個變量同時使用了構造方法注入又使用了設置方
法注入的話,那么構造方法將不能覆蓋由設值方法注入的值。很明顯,因為構造方法盡在對象被創
建時調用。
3. 在使用設值注入時有可能還不能保證某種依賴是否已經被注入,也就是說這時對象的依賴關系有可
能是不完整的。而在另一種情況下,構造器注入則不允許生成依賴關系不完整的對象。
4. 在設值注入時如果對象 A 和對象 B 互相依賴,在創建對象 A 時 Spring 會拋出
sObjectCurrentlyInCreationException 異常,因為在 B 對象被創建之前 A 對
象是不能被創建的,反之亦然。所以 Spring 用設值注入的方法解決了循環依賴
的問題,因對象的設值方法是在對象被創建之前被調用的。
23、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) {
//handle event
}
}
之后通過 applicationContext 接口的 publishEvent()方法來發布自定義事件。
CustomApplicationEvent customEvent = new
CustomApplicationEvent(applicationContext, "Test message");
applicationContext.publishEvent(customEvent);
24、FileSystemResource 和 ClassPathResource 有何區別?
在 FileSystemResource 中需要給出 spring-config.xml 文件在你項目中的相對路徑或者
絕對路徑。在 ClassPathResource 中 spring 會在 ClassPath 中自動搜尋配置文件,所以要把
ClassPathResource 文件放在 ClassPath 下。
如果將 spring-config.xml 保存在了 src 文件夾下的話,只需給出配置文件的名稱即可,因為
src 文件夾是默認。
簡而言之,ClassPathResource 在環境變量中讀取配置文件,FileSystemResource 在配置文件
中讀取配置文件。
25、Spring 框架中都用到了哪些設計模式?
Spring 框架中使用到了大量的設計模式,下面列舉了比較有代表性的:
o 代理模式—在 AOP 和 remoting 中被用的比較多。
o 單例模式—在 spring 配置文件中定義的 bean 默認為單例模式。o 模板方法—用來解決代碼重復的問題。比如. RestTemplate, JmsTemplate, JpaTempl
ate。
o 前端控制器—Spring 提供了 DispatcherServlet 來對請求進行分發。
o 視圖幫助(View Helper )—Spring 提供了一系列的 JSP 標簽,高效宏來輔助將分散的代碼
整合在視圖里。
o 依賴注入—貫穿于 BeanFactory / ApplicationContext 接口的核心理念。
o 工廠模式—BeanFactory 用來創建對象的實例
1. 開發中主要使用 Spring 的什么技術 ?
①. IOC 容器管理各層的組件
②. 使用 AOP 配置聲明式事務
③. 整合其他框架.
2. 簡述 AOP 和 IOC 概念 AOP:
Aspect Oriented Program, 面向(方面)切面的編程;Filter(過濾器) 也是一種 AOP. AOP 是一種
新的方法論, 是對傳統 OOP(Object-Oriented Programming, 面向對象編程) 的補充. AOP 的
主要編程對象是切面(aspect), 而切面模塊化橫切關注點.可以舉例通過事務說明.
IOC: Invert Of Control, 控制反轉. 也成為 DI(依賴注入)其思想是反轉 資源獲取的方向. 傳統
的資源查找方式要求組件向容器發起請求查找資源.作為 回應, 容器適時的返回資源. 而應用了
IOC 之后, 則是容器主動地將資源推送 給它所管理的組件,組件所要做的僅是選擇一種合適的方式
來接受資源. 這種行 為也被稱為查找的被動形式
3. 在 Spring 中如何配置 Bean ?
Bean 的配置方式: 通過全類名(反射)、通過工廠方法(靜態工廠方法 & 實 例工廠方法)、
FactoryBean
4. IOC 容器對 Bean 的生命周期:
①. 通過構造器或工廠方法創建 Bean 實例
②. 為 Bean 的屬性設置值和對其他 Bean 的引用
③ . 將 Bean 實 例 傳 遞 給 Bean 后 置 處 理 器 的 postProcessBeforeInitialization 方
法
④. 調用 Bean 的初始化方法(init-method)⑤ . 將 Bean 實 例 傳 遞 給 Bean 后 置 處 理 器 的 postProcessAfterInitialization 方法
⑦. Bean 可以使用了
⑧. 當容器關閉時, 調用 Bean 的銷毀方法(destroy-method)
更多Java面試題以及學習資料獲取方式:加Qun:1017-599-436免費獲取。
?還有更多包括電子書,PDF文檔以及視頻精講可以分享給大家,內容覆蓋很廣,分布式緩存、RPC 調用、Zookeeper、消息隊列、分布式搜索引擎、分布式 session、分庫分表等.