spring面試問題與答案集錦

我收集了一些spring面試的問題,這些問題可能會在下一次技術面試中遇到。對於其餘spring模塊,我將單獨分享面試問題和答案。前端

若是你能將在之前面試中碰到的,且你認爲這些應該是一個有spring經驗的人可能被問到的問題發給我,我將不勝感激!java

我將把它們添加到這個列表中。這將對其餘學習者也會有很大的幫助。web

1. 什麼是Spring框架?它的主要模塊有哪些?面試

2. 使用Spring框架的好處是什麼?spring

3.什麼是控制反轉(IoC)和依賴注入?數據庫

4. 在Spring框架中的IoC是怎麼樣子的 ?編程

5. BeanFactory和ApplicationContext之間的區別?json

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(支持和類加載器的實現來在特定的應用服務器上使用)、消息、和測試,以下列圖所示。

spring模塊

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中,依賴注入可能發生三種方法:

  1. 構造方法注入
  2. setter方法注入
  3. 接口注入

4. Spring框架的IOC是怎麼樣的?

  org.springframework.beansorg.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還提供:

  1. 一種解析消息的手段,包括對國際化的支持。
  2. 一個更通用的加載文件資源的方法。
  3. bean事件註冊爲監聽器。

三個經常使用的ApplicationContext實現是:

  1. ClassPathXmlApplicationContext:它從classpath路徑下的一個XML文件加載context的,將Context做爲classpath下的資源。加載應用程序classpath下的context使用的代碼以下:
    ApplicationContext context = new ClassPathXmlApplicationContext(「bean.xml」);
  2. FileSystemXmlApplicationContext:它從文件系統的一個XML文件加載上下文定義的。從文件系統加載應用程序上下文經過以下代碼實現。
    ApplicationContext context = new FileSystemXmlApplicationContext(「bean.xml」);
  3. XmlWebApplicationContext:它從一個web應用程序中包含的XML文件加載context。

6. 將Spring配置應用程序的方式有哪些呢?

配置spring到您的應用程序有三種方式:

  1. 基於XML的配置
  2. 基於註解的配置
  3. 基於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中您能夠開始使用屬性,方法和構造函數的自動注入。

一些重要的註解:

  1. @required: @ required註解適用於bean屬性setter方法。
  2. @autowired: @ autowired註解能夠適用於bean屬性setter方法,non-setter方法、構造函數和屬性。
  3. @qualifier: @ qualifier註解加上@ autowired能夠用來消除多個bean混亂來保證惟一的bean注入。
  4. jsr - 250註釋:Spring支持基於jsr - 250的註解如@Resource、@PostConstruct和@PreDestroy。

10.請解釋一下Spring Bean的生命週期?

一個Spring bean的生命週期很容易理解。當一個bean實例化時可能須要執行一些初始化動做進入使bean達到一個可用的狀態。一樣,當再也不須要bean時,將bean從容器中移除,可能須要銷燬。

Spring beanFactory經過Spring容器負責管理bean的生命週期。bean的生命週期包括能夠大致分類爲兩類的回調方法

  1. 初始化後的回調方法
  2. 銷燬前的回調方法

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,分別是:

  1. 單例singleton:默認狀況下都是單例的,它要求在每一個spring 容器內不論你請求多少次這個實例,都只有一個實例。單例特性是由beanfactory自己維護的。
  2. 原型prototype:這個bean的實例和單例相反,一個新的請求產生一個新的bean實例。
  3. 請求request:在一個請求內,將會爲每一個web請求的客戶端建立一個新的bean實例。一旦請求完成後,bean將失效,而後被垃圾收集器回收掉。
  4. 會話session:就像請求範圍,這樣能夠確保每一個用戶會話bean的一個實例。當用戶結束其會話,bean失效。
  5. 全局會話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 />

也能夠經過在配置文件使用AutowiredAnnotationBeanPostProcessorbean來完成。

<bean class ="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

如今,當註釋配置已經啓用,您能夠自由使用@Autowired來自動注入bean依賴關係,以你喜歡的方式。

 
@Autowired
public EmployeeDAOImpl ( EmployeeManager manager ) {
    this.manager = manager;
}

17. 請解釋一下不一樣的bean自動注入模式?

在Spring有五個自動注入模式。讓咱們逐個討論。

  1. no:默認狀況下,spring框架的自動注入選項,即默認狀況不開啓自動注入。這意味着你必須使用標籤在bean定義中顯式地設置依賴項。
  2. byName:這個選項使基於bean的名稱的依賴項注入。當自動裝配在bean屬性,用屬性名搜索匹配的bean定義配置文件。若是找到這樣的bean,注入屬性。若是沒有找到這樣的bean,就會產生一個錯誤。
  3. byType:該選項容許基於bean的類型的依賴項注入。當在bean屬性須要自動注入時,使用屬性類的類型來搜索匹配的bean定義配置文件。若是找到這樣的bean,注入屬性。若是沒有找到這樣的bean,就會產生一個錯誤。
  4. constructor:構造方法相似於byType自動注入,但適用於構造方法的參數。在自動注入bean時,它在全部構造函數參數類型中尋找匹配的構造函數的類類型參數,而後進行自動注入,。請注意,若是在容器中沒有一個bean構造函數參數類型知足,會拋出一個致命錯誤。
  5. 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注入之間的區別嗎?

有如下幾點明顯的差別:

  1. 在Setter注入,能夠將依賴項部分注入,構造方法注入不能部分注入,由於調用構造方法若是傳入全部的參數就會報錯。
  2. 若是咱們爲同一屬性提供Setter和構造方法注入,Setter注入將覆蓋構造方法注入。可是構造方法注入不能覆蓋setter注入值。顯然,構造方法注入被稱爲建立實例的第一選項。
  3. 使用setter注入你不能保證全部的依賴都被注入,這意味着你能夠有一個對象依賴沒有被注入。在另外一方面構造方法注入直到你全部的依賴都注入後纔開始建立實例。
  4. 在構造函數注入,若是A和B對象相互依賴:A依賴於B,B也依賴於A,此時在建立對象的A或者B時,Spring拋出ObjectCurrentlyInCreationException。因此Spring能夠經過setter注入,從而解決循環依賴的問題。

23. spring框架的事件類型有哪些?

Spring的ApplicationContext具備代碼層上支持事件和監聽器的功能。咱們能夠建立bean監聽經過ApplicationContext發佈的事件。ApplicationContext裏的事件處理經過提供ApplicationEvent類和ApplicationListener接口來完成。因此若是一個bean實現了ApplicationListener接口,當一個ApplicationEvent發佈到ApplicationContext時,該bean將接到通知。

public class AllApplicationEventListener implements ApplicationListener < ApplicationEvent >
{
    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent)
    {
        //process event
    }
}

Spring提供瞭如下5標準事件:

  1. ContextRefreshedEvent:當ApplicationContext初始化或刷新時發佈這個事件。這個事件也能夠經過ConfigurableApplicationContext接口的refresh()方法來觸發。
  2. ContextStartedEvent:當ApplicationContext被ConfigurableApplicationContext接口的start()方法啓動時發佈這個事件。你能夠在收到這一事件後查詢你的數據庫或重啓/啓動任何中止的應用程序。
  3. ContextStoppedEvent:當ApplicationContext被ConfigurableApplicationContext接口的stop()方法關閉時發佈這個事件。你能夠在收到這一事件後作一些清理工做。
  4. ContextClosedEvent:當ApplicationContext時被ConfigurableApplicationContext接口的close()方法關閉時發佈這個事件。一個終結的上下文達到生命週期結束;它不能刷新或重啓。
  5. 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/

相關文章
相關標籤/搜索