我收集了一些spring面試的問題,這些問題可能會在下一次技術面試中遇到。對於其他spring模塊,我將單獨分享面試問題和答案。
如果你能將在以前面試中碰到的,且你認為這些應該是一個有spring經驗的人可能被問到的問題發給我,我將不勝感激!
我將把它們添加到這個列表中。這將對其他學習者也會有很大的幫助。
1. 什么是Spring框架?它的主要模塊有哪些?
2. 使用Spring框架的好處是什么?
3.什么是控制反轉(IoC)和依賴注入?
4. 在Spring框架中的IoC是怎么樣子的 ?
5. BeanFactory和ApplicationContext之間的區別?
6. 將Spring配置到應用程序中的方式有哪些?
7. 基於xml的Spring配置是什么樣子的?
8. 基於Spring java的配置是什么樣子的?
9. 基於Spring注解的配置是什么樣子的?
10. 請解釋一下Spring Bean的生命周期?
11. Spring Bean作用域的有哪些?
12. Spring的內部Bean是什么?
13. 在Spring框架中,單例bean線程安全嗎?
14. 如何在Spring中注入Java集合?請給個例子好嗎?
15. 如何將一個java.util.屬性注入到Spring Bean?
16. 解釋一下Spring Bean的自動注入式什么樣的?
17. 請解釋一下不同的bean自動注入模式?
18. 怎么打開基於注釋的自動注入的?
19. 能否用例子解釋一下@ required注解嗎?
20.能否用例子解釋一下@ autowired注解嗎?
21. 能否用例子講解一下@qualifier注解嗎?
22. 構造方法注入和setter注入之間的區別嗎?
23. spring框架的事件類型有哪些?
24. FileSystemResource和ClassPathResource之間的區別嗎?
25. 列舉一些Spring框架中使用的設計模式?
1. Spring框架是什么?它的主要模塊有哪些?
Spring框架是一個Java平台,提供全面的基礎設施支持開發Java應用程序。Spring處理基礎設施部分,這樣你就可以專注於應用程序部分。Spring框架內,把一級對象通過設計模式封裝起來,您可以放心的集成到您自己的應用程序而不用關注他們如何在后台工作。
目前,Spring框架由功能組織成大約20個模塊。這些模塊分為核心容器、數據訪問/集成、Web,AOP(面向切面的編程)、instrument(支持和類加載器的實現來在特定的應用服務器上使用)、消息、和測試,如下列圖所示。
2. 使用Spring框架的好處是什么?
下面是一些使用Spring框架的好處的列表:
- 通過依賴注入(DI)方式,在構造方法或者java bean屬性上,依賴關系是明確的和明顯的。
- IoC容器往往是輕量級的,特別是與EJB容器相比。這是有利於在有限的內存和CPU資源的計算機上開發和部署應用程序。
- Spring不重新發明輪子,相反,它利用一些現有的技術如幾個ORM框架,日志框架,JEE,quartz和JDK計時器,其他視圖技術等。
- Spring是模塊化的。盡管包和類很重要,你只關心你需要的模塊,忽略其它模塊。
- 在Spring測試應用程序很簡單,因為依賴環境的代碼被移入到框架本身。此外,通過使用JavaBean-style pojo方式,使用依賴注入注入測試數據變得更容易。
- Spring的web框架是一個設計良好的web MVC框架,它可以很好的替代其它web框架如struts或者其它web框架。
- Spring提供了一致的事務管理界面,可以管理小到一個本地事務(例如,使用一個數據庫)和大到全局事務(例如,使用JTA)。
3. 什么是控制反轉(IoC)和依賴項注入?
依賴注入和控制反轉是對同一件事情的不同描述,從某個方面講,就是它們描述的角度不同。
依賴注入是從應用程序的角度在描述,可以把依賴注入描述完整點:應用程序依賴容器創建並注入它所需要的外部資源;
而控制反轉是從容器的角度在描述,描述完整點:容器控制應用程序,由容器反向的向應用程序注入應用程序所需要的外部資源。
在Java中,依賴注入可能發生三種方法:
- 構造方法注入
- setter方法注入
- 接口注入
4. Spring框架的IOC是怎么樣的?
org.springframework.beans
和org.springframework.context
包是Spring框架IoC容器的基礎。
BeanFactory
接口提供了一個高級的配置機制來管理任意屬性的對象。
ApplicationContext
接口基於BeanFactory構建的
(是一個子接口)並添加其他功能,如Spring的AOP功能,信息資源處理(用於國際化)、事件傳播和應用程序層的特定上下文如在web應用程序中使用WebApplicationContext
。
org.springframework.beans.factory.BeanFactory是
Spring IoC容器真是展現,負責管理上述bean。BeanFactory接口是Spring IoC容器接口的核心。
5. BeanFactory和ApplicationContext之間的區別?
一個BeanFactory
就像包含bean集合的工廠類。BeanFactory在內部
持有多個Bean的定義,當客戶端請求bean時,將bean進行實例化。
初始化時BeanFactory
能夠保持對象的依賴關系。這減輕了負擔從bean本身和bean客戶機的配置。 BeanFactory在
一個bean的生命周期也能其作用,它可以調用bean的自定義初始化和銷毀方法。
表面上看,applicationContext和BeanFactory是一樣。同樣加載bean定義,將bean連接在一起,分發bean。但applicationContext還提供:
- 一種解析消息的手段,包括對國際化的支持。
- 一個更通用的加載文件資源的方法。
- bean事件注冊為監聽器。
三個常用的ApplicationContext實現是:
- ClassPathXmlApplicationContext:它從classpath路徑下的一個XML文件加載context的,將Context作為classpath下的資源。加載應用程序classpath下的context使用的代碼如下:
ApplicationContext context = new ClassPathXmlApplicationContext(“bean.xml”);
FileSystemXmlApplicationContext
:它從文件系統的一個XML文件加載上下文定義的。從文件系統加載應用程序上下文通過如下代碼實現。ApplicationContext context = new FileSystemXmlApplicationContext(“bean.xml”);
XmlWebApplicationContext
:它從一個web應用程序中包含的XML文件加載context。
6. 將Spring配置應用程序的方式有哪些呢?
配置spring到您的應用程序有三種方式:
- 基於XML的配置
- 基於注解的配置
- 基於java的配置
7. 基於xml的Spring配置是什么樣子的?
在Spring框架中,bean所需的依賴和服務在定義在配置文件中,配置文件通常是XML格式。通常這些配置文件都以<beans>
標簽開始,含有大量的bean定義和特定於應用程序的配置選項。Spring XML配置的主要目標是讓所有spring組件通過使用XML配置文件。
這意味着不會出現任何其他類型的Spring配置(如通過Java類注釋或配置)。Spring XML配置中使用Spring命名空間提供的XML標記中使用的配置;Spring命名空間主要有:context、bean、jdbc、tx, aop, mvc等。
<beans> <!-- JSON Support --> <bean name="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver"/> <bean name="jsonTemplate" class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/> <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
類允許inter-bean定義通過簡單地調用實現依賴關系。最簡單的@Configuration
注解類如下:
@Configuration public class AppConfig { @Bean public MyService myService() { return new MyServiceImpl(); } }
上面注解類等價於基於XML配置文件如下:
<beans> <bean id="myService" class="com.howtodoinjava.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.howtodoinjava") public class AppConfig { ... }
在上面的示例中com.howtodoinjava包將被掃描,尋找任何帶注解@Component
的類,這些類將在容器內登記為Spring bean。
如果你使用以上的方式配置一個web應用程序,那么需要AnnotationConfigWebApplicationContext
類來使之生效。AnnotationConfigWebApplicationContext的使用可以通過配置Spring ContextLoaderListener的
servlet listener,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.AnnotationConfigWebApplicationContext </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.AnnotationConfigWebApplicationContext </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注解之前,我們需要在我們的Spring配置文件啟用它。如果你想在Spring應用程序中使用的自動注解,考慮配置文件上加上下面的配置。
<beans> <context:annotation-config/> <!-- bean definitions go here --> </beans>
一旦配置了<context:annotation-config/>
,表明在Spring中您可以開始使用屬性,方法和構造函數的自動注入。
一些重要的注解:
- @required: @ required注解適用於bean屬性setter方法。
- @autowired: @ autowired注解可以適用於bean屬性setter方法,non-setter方法、構造函數和屬性。
- @qualifier: @ qualifier注解加上@ autowired可以用來消除多個bean混亂來保證唯一的bean注入。
- jsr - 250注釋:Spring支持基於jsr - 250的注解如@Resource、@PostConstruct和@PreDestroy。
10.請解釋一下Spring Bean的生命周期?
一個Spring bean的生命周期很容易理解。當一個bean實例化時可能需要執行一些初始化動作進入使bean達到一個可用的狀態。同樣,當不再需要bean時,將bean從容器中移除,可能需要銷毀。
Spring beanFactory通過Spring容器負責管理bean的生命周期。bean的生命周期包括可以大體分類為兩類的回調方法
- 初始化后的回調方法
- 銷毀前的回調方法
Spring框架提供了以下四種方法控制bean的生命周期事件:
- InitializingBean和DisposableBean回調接口
- 其他知道接口為特定的行為
- 定制的init()和destroy()方法在bean配置文件
- @PostConstruct和@PreDestroy注解
例如, customInit()
和 customDestroy()
方法生命周期方法的例子。
<beans> <bean id="demoBean" class="com.howtodoinjava.task.DemoBean" init-method="customInit" destroy-method="customDestroy"></bean> </beans>
11. Spring Bean的作用域scope有哪些?
spring容器中的bean有5中scope,分別是:
- 單例singleton:默認情況下都是單例的,它要求在每個spring 容器內不論你請求多少次這個實例,都只有一個實例。單例特性是由beanfactory本身維護的。
- 原型prototype:這個bean的實例和單例相反,一個新的請求產生一個新的bean實例。
- 請求request:在一個請求內,將會為每個web請求的客戶端創建一個新的bean實例。一旦請求完成后,bean將失效,然后被垃圾收集器回收掉。
- 會話session:就像請求范圍,這樣可以確保每個用戶會話bean的一個實例。當用戶結束其會話,bean失效。
- 全局會話global-session:應用到Portlet應用程序。基於Servlet的應用程序和會話相同。
12. spring的內部Bean是什么?
在Spring框架中,當一個bean只用於一個特定屬性,建議將它聲明為一個內在的bean。內部bean同時支持setter注入屬性和構造函數注入“constructor-arg”。
例如,假設一個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.howtodoinjava.common.Customer"> <property name="person"> <!-- This is inner bean --> <bean class="com.howtodoinjava.common.Person"> <property name="name" value="adminis"></property> <property name="address" value="India"></property> <property name="age" value="34"></property> </bean> </property> </bean>
13. 在Spring框架中,單例bean是線程安全的嗎?
Spring框架不對單例的bean做任何多線程的處理。單例的bean的並發問題和線程安全是開發人員的責任。
而實際上,大多數spring bean沒有可變狀態(例如服務和DAO的類),這樣的話本身是線程安全的。但如果您的bean有可變狀態(例如視圖模型對象),這就需要你來確保線程安全。
這個問題最簡單和明顯的解決方案是改變bean Scope,可變的bean從“單例”到“原型”。
14. 如何在Spring里注入Java集合?請給個例子好嗎?
Spring提供了四種類型的配置元素集合,如下:
<list>:幫助注入一組值,允許重復。
<set>:幫助注入一組值,不允許重復。
< map>:幫助注入一個K-V的集合,名稱和值可以是任何類型的。
<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. 如何將一個java.util.屬性注入到Spring Bean ?
第一個方法是使用<props>標記如下。
<bean id="adminUser" class="com.howtodoinjava.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:“名稱空間創建bean的屬性文件,並使用bean的setter方法注入。
<util:properties id="emails" location="classpath:com/foo/emails.properties" />
16. 解釋一下Spring Bean的自動注入是怎么樣的?
在spring框架中,在配置文件中設置bean的依賴是一個很好的辦法,但spring容器也能夠自動注入不同bean之間的關系。這意味着,通過檢查BeanFactory的內容它可以為您的bean自動注入其他bean。
可以為每個bean指定是否自動注入,因此可以支持一些Bean支持自動注入,而一些bean不會自動注入。
下面從XML配置文件摘錄了自動根據名稱注入的bean。
<bean id="employeeDAO" class="com.howtodoinjava.EmployeeDAOImpl" autowire="byName" />
除了提供的自動裝配模式bean配置文件,也可以在bean類中指定自動裝配使用 @Autowired
注釋。
注意:在bean類使用@Autowired注解
,您必須在spring應用程序中先啟用下面的注解。
<context:annotation-config />
也可以通過在配置文件使用AutowiredAnnotationBeanPostProcessor
bean來完成。
<bean class ="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
現在,當注釋配置已經啟用,您可以自由使用@Autowired來
自動注入bean依賴關系,以你喜歡的方式。
@Autowired public EmployeeDAOImpl ( EmployeeManager manager ) { this.manager = manager; }
17. 請解釋一下不同的bean自動注入模式?
在Spring有五個自動注入模式。讓我們逐個討論。
- no:默認情況下,spring框架的自動注入選項,即默認情況不開啟自動注入。這意味着你必須使用標簽在bean定義中顯式地設置依賴項。
- byName:這個選項使基於bean的名稱的依賴項注入。當自動裝配在bean屬性,用屬性名搜索匹配的bean定義配置文件。如果找到這樣的bean,注入屬性。如果沒有找到這樣的bean,就會產生一個錯誤。
- byType:該選項允許基於bean的類型的依賴項注入。當在bean屬性需要自動注入時,使用屬性類的類型來搜索匹配的bean定義配置文件。如果找到這樣的bean,注入屬性。如果沒有找到這樣的bean,就會產生一個錯誤。
- constructor:構造方法類似於byType自動注入,但適用於構造方法的參數。在自動注入bean時,它在所有構造函數參數類型中尋找匹配的構造函數的類類型參數,然后進行自動注入,。請注意,如果在容器中沒有一個bean構造函數參數類型滿足,會拋出一個致命錯誤。
- autodetect:自動偵測使用兩種模式即構造函數或byType模式的自動注入。首先它將試圖尋找有效的構造方法參數,如果發現構造方法模式則選擇。如果沒有構造方法中定義bean,或者明確的默認無參構造方法,則選擇byType模式自動注入。
18. 怎么打開基於注釋的自動注入的?
要啟用@Autowired
,你必須注冊AutowiredAnnotationBeanPostProcessor
,你可以用兩種方式。
1. 在bean配置文件使用<context:annotation-config >
。
<beans> <context:annotation-config /> </beans>
2. 直接將AutowiredAnnotationBeanPostProcessor放到
bean配置文件。
<beans> <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/> </beans>
19. 能否用例子解釋一下@ required注解嗎?
在大規模的應用程序中,IoC容器中可能會有成百上千的bean聲明,以及它們之間的依賴關系通常是非常復雜的。
setter注入的缺點之一是,很難給你檢查出所需的所有屬性是否已經注入。
為了克服這個問題,您可以設置bean的“dependency-check”屬性,可以設置四個屬性的其中之一即 none, simple, objects or all (沒有一個是默認選項)。
在現實生活中應用程序中,您將不會感興趣檢查所有上下文中的bean屬性配置文件。而你想要檢查一些特定的bean是否已設置特定的屬性。在這種情況下,Spring的依賴項檢查功能將不再適用,。
為了解決這個問題,您可以使用@Required
注解。在bean屬性使用@Required
注解的setter方法類文件如下:
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 bean后置處理程序,檢查@Required注解的
所有的bean屬性是否已設置。使用這個bean屬性檢查后置處理程序,您必須注冊在Spring IoC容器中。
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor" />
如果@Required注解的任何屬性
沒有設置,這個bean的處理器會拋出一個BeanInitializationException
異常。
20.能否用例子解釋一下@ autowired注解嗎?
@Autowired
注解提供了更細粒度的控制,以及應該如何完成自動注入。@Autowired
注解和@Required注解
一樣,可用於bean的自動注入,它可以作用於構造方法,屬性或具有任意名稱和/或多個參數的方法。
例如,您可以使用@Autowired
注解的setter方法來代替在XML配置文件中的<property>
元素。當Spring找到一個@Autowired
注解的方法,它嘗試使用byType自動注入的方法。
您可以將@Autowired應用到
構造方法。一個構造方法使用@Autowired注解
表明,即使在XML文件沒有配置bean的<constructor-arg>
元素,當創建bean時,構造方法也會自動注入。
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"> </bean> <!-- Definition for spellChecker bean --> <bean id="spellChecker" class="com.howtodoinjava.SpellChecker"> </bean> </beans>
21. 能否用例子講解一下@qualifier注解嗎?
@Qualifier限定哪個bean應該被自動注入
。當Spring無法判斷出哪個bean應該被注入時,@Qualifier注解有助於消除歧義bean的自動注入。
參見下面的例子,
public class Customer
{
@Autowired
private Person person;
}
我們有兩個bean定義為Person
類的實例。
<bean id="customer" class="com.howtodoinjava.common.Customer" /> <bean id="personA" class="com.howtodoinjava.common.Person" > <property name="name" value="lokesh" /> </bean> <bean id="personB" class="com.howtodoinjava.common.Person" > <property name="name" value="alex" /> </bean>
Spring 知道哪個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應該被autowired的。
public class Customer { @Autowired @Qualifier("personA") private Person person; }
22. 構造方法注入和setter注入之間的區別嗎?
有以下幾點明顯的差異:
- 在Setter注入,可以將依賴項部分注入,構造方法注入不能部分注入,因為調用構造方法如果傳入所有的參數就會報錯。
- 如果我們為同一屬性提供Setter和構造方法注入,Setter注入將覆蓋構造方法注入。但是構造方法注入不能覆蓋setter注入值。顯然,構造方法注入被稱為創建實例的第一選項。
- 使用setter注入你不能保證所有的依賴都被注入,這意味着你可以有一個對象依賴沒有被注入。在另一方面構造方法注入直到你所有的依賴都注入后才開始創建實例。
- 在構造函數注入,如果A和B對象相互依賴:A依賴於B,B也依賴於A,此時在創建對象的A或者B時,Spring拋出
ObjectCurrentlyInCreationException
。所以Spring可以通過setter注入,從而解決循環依賴的問題。
23. spring框架的事件類型有哪些?
Spring的ApplicationContext具有代碼層上
支持事件和監聽器的功能。我們可以創建bean監聽通過ApplicationContext發布的事件。ApplicationContext里的事件處理通過提供ApplicationEven
t類和ApplicationListener
接口來完成。所以如果一個bean實現了ApplicationListener接口
,當一個ApplicationEvent
發布到ApplicationContext時,該bean將接到
通知。
public class AllApplicationEventListener implements ApplicationListener < ApplicationEvent > { @Override public void onApplicationEvent(ApplicationEvent applicationEvent) { //process event } }
Spring提供了以下5標准事件:
- ContextRefreshedEvent:當ApplicationContext初始化或刷新時發布這個事件。這個事件也可以通過
ConfigurableApplicationContext
接口的refresh()方法來觸發。 - ContextStartedEvent:當ApplicationContext被ConfigurableApplicationContext接口的start()方法啟動時發布這個事件。你可以在收到這一事件后查詢你的數據庫或重啟/啟動任何停止的應用程序。
- ContextStoppedEvent:當ApplicationContext被ConfigurableApplicationContext接口的stop()方法關閉時發布這個事件。你可以在收到這一事件后做一些清理工作。
- ContextClosedEvent:當ApplicationContext時被ConfigurableApplicationContext接口的close()方法關閉時發布這個事件。一個終結的上下文達到生命周期結束;它不能刷新或重啟。
- RequestHandledEvent:這是一個網絡自身的事件,告訴所有bean:HTTP請求服務已經處理完成。
除了上面的事件,您可以通過擴展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 } }
發布這個事件:
CustomApplicationEvent customEvent = new CustomApplicationEvent( applicationContext, "Test message" ); applicationContext.publishEvent ( customEvent );
24. FileSystemResource和ClassPathResource之間的區別嗎?
在FileSystemResource中
你需要給出spring-config.xml
(Spring配置)文件相對於您的項目的相對路徑或文件的絕對位置。
在ClassPathResource中Sping
查找文件使用ClassPath,因此
spring-config.xml
應該包含在類路徑下。
一句話,ClassPathResource在類路徑下搜索和FileSystemResource在文件系統下搜索。
25. 列舉一下Spring框架使用的一些設計模式?
有很多不同的設計模式,但有一些明顯的:
- 代理——在AOP大量使用,還有遠程模塊。
- 單例——spring配置文件中定義的bean默認是單例的。
- 模板方法——廣泛使用處理重復邏輯的代碼。例如RestTemplate,
JmsTemplate
,JpaTemplate
. - 前端控制器——Spring提供了
DispatcherServlet
,確保傳入請求被分派到你的控制器。 - 視圖助手——Spring有許多定制JSP標記,和velocity宏,協助在視圖層分離展示代碼。
- 依賴注入——
BeanFactory
/ApplicationContext的核心
概念。 - 工廠模式——BeanFactory創建一個對象的實例。
原文:https://howtodoinjava.com/interview-questions/top-spring-interview-questions-with-answers/