主頁 > 前端設計 > 面試官問我憑什么敢來面試?我用Spring把他懟了。

面試官問我憑什么敢來面試?我用Spring把他懟了。

2020-10-25 13:29:21 前端設計

前言

Spring在面試中真的是經常被問到,所以今天也給大家總結了一下Spring知識點!

我變禿了,也變強了

PDF過大放不下,完整PDF戳這里免費領取,暗號:CSDN

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

Spring 框架是一個為 Java 應用程式的開發提供了綜合、廣泛的基礎性支持的 Java 平臺,幫助開發者解決了開發中基礎性的問題,使得開發人員可以專注于應用程式的開發,

Spring 框架本身亦是按照設計模式精心打造,這使得我們可以在開發環境中安心的集成 Spring 框架,不必擔心 Spring 是如何在后臺進行作業的,

Spring 框架至今已集成了 20 多個模塊,這些模塊主要被分如下圖所示的核心容器、資料訪問/集成,、Web、AOP(面向切面編程)、工具、訊息和測驗模塊,

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

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

  • Dependency Injection(DI) 方法使得構造器和 JavaBean properties 檔案中的依賴關系一目了然,
  • 與 EJB 容器相比較,IoC 容器更加趨向于輕量級,這樣一來 IoC 容器在有限的記憶體和 CPU 資源的情況下進行應用程式的開發和發布就變得十分有利,
  • Spring 并沒有閉門造車,Spring 利用了已有的技術比如 ORM 框架、logging 框架、J2EE、Quartz 和 JDK Timer,以及其他視圖技術,
  • Spring 框架是按照模塊的形式來組織的,由包和類的編號就可以看出其所屬的模塊,開發者僅僅需要選用他們需要的模塊即可,
  • 要測驗一項用 Spring 開發的應用程式十分簡單,因為測驗相關的環境代碼都已經囊括在框架中了,更加簡單的是,利用 JavaBean 形式的 POJO 類,可以很方便的利用依賴注入來寫入測驗資料,
  • Spring 的 Web 框架亦是一個精心設計的 Web MVC 框架,為開發者們在 web 框架的選擇上提供了一個除了主流框架比如 Struts、過度設計的、不流行 web 框架的以外的有力選項,
  • Spring 提供了一個便捷的事務管理介面,適用于小型的本地事物處理(比如在單 DB 的環境下)和復雜的共同事物處理(比如利用 JTA 的復雜 DB 環境),

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

控制反轉是應用于軟體工程領域中的,在運行時被裝配器物件來系結耦合物件的一種編程技巧,物件之間耦合關系在編譯時通常是未知的,

在傳統的編程方式中,業務邏輯的流程是由應用程式中的早已被設定好關聯關系的物件來決定的,在使用控制反轉的情況下,業務邏輯的流程是由物件關系圖來決定的,該物件關系圖由裝配 器負責實體化,這種實作方式還可以將物件之間的關聯關系的定義抽象化,而系結的程序是通過“依賴注入”實作的,

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

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

在 Java 中依賴注入有以下三種實作方式:

  • 構造器注入
  • 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 容器的具體實作,用來包裝和管理前面提到的各種 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 在此基礎上還提供了其他的功能

  • 提供了支持國際化的文本訊息
  • 統一的資源檔案讀取方式
  • 已在監聽器中注冊的 bean 的事件

以下是三種較常見的 ApplicationContext 實作方式:
1、ClassPathXmlApplicationContext:從 classpath 的 XML 組態檔中讀取背景關系,并生成背景關系定義,應用程式背景關系從程式環境變數中

ApplicationContext context = newClassPathXmlApplicationContext(“bean.xml”);

2、FileSystemXmlApplicationContext :由檔案系統中的 XML 組態檔讀取背景關系,

ApplicationContext context = newFileSystemXmlApplicationContext(“bean.xml”);

3、XmlWebApplicationContext:由 Web 應用的 XML 檔案讀取背景關系,

4、AnnotationConfigApplicationContext(基于 Java 配置啟動容器)

6 、Spring 有幾種配置方式?

將 Spring 配置到應用開發中有以下三種方式(方法詳解在后三題):

  • 基于 XML 的配置
  • 基于注解的配置
  • 基于 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.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 宣告的類可以通過在同一個類的 內部呼叫@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 = newAnnotationConfigApplicationContext(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.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 檔案中配置一下才能使用基于注解的裝配
模式,如果你想要在你的應用程式中使用關于注解的方法的話,請參考如下的配置

<beans>
   <context:annotation-config/>
   <!-- bean definitions go here -->
</beans>

在 <context:annotation-config/>標簽配置完成以后,就可以用注解的方式在Spring 中向屬性、方法和構造方法中自動裝配變數,

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

  • @Required:該注解應用于設值方法,
  • @Autowired:該注解應用于有值設值方法、非設值方法、構造方法和變數,
  • @Qualifier:該注解和@Autowired 注解搭配使用,用于消除特定 bean 自動裝配的歧義,
  • 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)方法組成,

  • 初始化之后呼叫的回呼方法,
  • 銷毀之前呼叫的回呼方法,

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. 2prototype:原形范圍與單例范圍相反,為每一個 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.AutowiredAnnotationBeanPostProcessor"/>

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

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

17 、請解釋自動裝配模式的區別?

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

  1. no:這是 Spring 框架的默認設定,在該設定下自動裝配是關閉的,開發者需要自行在 bean 定義中用標簽明確的設定依賴關系,
  2. 2byName:該選項可以根據 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.AutowiredAnnotationBeanPostProcessor"/>
</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.RequiredAnnotationBeanPostProcessor" />

但是如果沒有屬性被用@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 框架中使用到了大量的設計模式,下面列舉了比較有代表性的:

  • 代理模式—在 AOP 和 remoting 中被用的比較多,
  • 單例模式—在 spring 組態檔中定義的 bean 默認為單例模式,
  • 模板方法—用來解決代碼重復的問題,比如. RestTemplate, JmsTemplate , JpaTemplate,
  • 前端控制器—Spring 提供了 DispatcherServlet 來對請求進行分發,
  • 視圖幫助(View Helper )—Spring 提供了一系列的 JSP 標簽,高效宏來輔助將分散的代碼整合在視圖里,
  • 依賴注入—貫穿于 BeanFactory / ApplicationContext 介面的核心理念,
  • 工廠模式—BeanFactory 用來創建物件的實體

26.最后

平常用的的技術點也不止Spring,也不好全部寫出來了,所以全部都總結成了PDF,都是免費給大家的,幫大家一起成為大佬

免費資料領取:戳這里免費領取,暗號:CSDN

愛編程,愛分享,聽說點贊+關注的都進大廠了哦!!!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/190232.html

標籤:其他

上一篇:都是“MySQL在搞鬼”差點倒在阿里三面,后面真是虛心一場

下一篇:MySQL索引的使用實體

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • vue移動端上拉加載

    可能做得過于簡單或者比較low,請各位大佬留情,一起探討技術 ......

    uj5u.com 2020-09-10 04:38:07 more
  • 優美網站首頁,頂部多層導航

    一個個人用的瀏覽器首頁,可以把一下常用的網站放在這里,平常打開會比較方便。 第一步,HTML代碼 <script src=https://www.cnblogs.com/szharf/p/"js/jquery-3.4.1.min.js"></script> <div id="navigate"> <ul> <li class="labels labels_1"> ......

    uj5u.com 2020-09-10 04:38:47 more
  • 頁面為要加<!DOCTYPE html>

    最近因為寫一個js函式,需要用到$(window).height(); 由于手寫demo的時候,過于自信,其實對前端方面的認識也不夠體系,用文本檔案直接敲出來的html代碼,第一行沒有加上<!DOCTYPE html> 導致了$(window).height();的結果直接是整個document的高 ......

    uj5u.com 2020-09-10 04:38:52 more
  • WordPress網站程式手動升級要做好資料備份

    WordPress博客網站程式在進行升級前,必須要做好網站資料的備份,這個問題良家佐言是遇見過的;在剛開始接觸WordPress博客程式的時候,因為升級問題和博客網站的修改的一些嘗試,良家佐言是吃盡了苦頭。因為購買的是西部數碼的空間和域名,每當佐言把自己的WordPress博客網站搞到一塌糊涂的時候 ......

    uj5u.com 2020-09-10 04:39:30 more
  • WordPress程式不能升級為5.4.2版本的原因

    WordPress是一款個人博客系統,受到英文博客愛好者和中文博客愛好者的追捧,并逐步演化成一款內容管理系統軟體;它是使用PHP語言和MySQL資料庫開發的,用戶可以在支持PHP和MySQL資料庫的服務器上使用自己的博客。每一次WordPress程式的更新,就會牽動無數WordPress愛好者的心, ......

    uj5u.com 2020-09-10 04:39:49 more
  • 使用CSS3的偽元素進行首字母下沉和首行改變樣式

    網頁中常見的一種效果,首字改變樣式或者首行改變樣式,效果如下圖。 代碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, ......

    uj5u.com 2020-09-10 04:40:09 more
  • 關于a標簽的講解

    什么是a標簽? <a> 標簽定義超鏈接,用于從一個頁面鏈接到另一個頁面。 <a> 元素最重要的屬性是 href 屬性,它指定鏈接的目標。 a標簽的語法格式:<a href=https://www.cnblogs.com/summerxbc/p/"指定要跳轉的目標界面的鏈接">需要展示給用戶看見的內容</a> a標簽 在所有瀏覽器中,鏈接的默認外觀如下: 未被訪問的鏈接帶 ......

    uj5u.com 2020-09-10 04:40:11 more
  • 前端輪播圖

    在需要輪播的頁面是引入swiper.min.js和swiper.min.css swiper.min.js地址: 鏈接:https://pan.baidu.com/s/15Uh516YHa4CV3X-RyjEIWw 提取碼:4aks swiper.min.css地址 鏈接:https://pan.b ......

    uj5u.com 2020-09-10 04:40:13 more
  • 如何設定html中的背景圖片(全屏顯示,且不拉伸)

    1 <style>2 body{background-image:url(https://uploadbeta.com/api/pictures/random/?key=BingEverydayWallpaperPicture); 3 background-size:cover;background ......

    uj5u.com 2020-09-10 04:40:16 more
  • Java學習——HTML詳解(上)

    HTML詳解 初識HTML Hyper Text Markup Language(超文本標記語言) 1 <!--DOCTYPE:告訴瀏覽器我們要使用什么規范--> 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <!--meta 描述性的標簽,描述一些 ......

    uj5u.com 2020-09-10 04:40:33 more
最新发布
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 07:59:23 more
  • 生產事故-走近科學之消失的JWT

    入職多年,面對生產環境,盡管都是小心翼翼,慎之又慎,還是難免捅出簍子。輕則滿頭大汗,面紅耳赤。重則系統停擺,損失資金。每一個生產事故的背后,都是寶貴的經驗和教訓,都是專案成員的血淚史。為了更好地防范和遏制今后的各類事故,特開此專題,長期更新和記錄大大小小的各類事故。有些是親身經歷,有些是經人耳傳口授 ......

    uj5u.com 2023-04-18 07:55:04 more
  • 記錄--Canvas實作打飛字游戲

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 打開游戲界面,看到一個畫面簡潔、卻又富有挑戰性的游戲。螢屏上,有一個白色的矩形框,里面不斷下落著各種單詞,而我需要迅速地輸入這些單詞。如果我輸入的單詞與螢屏上的單詞匹配,那么我就可以獲得得分;如果我輸入的單詞錯誤或者時間過長,那么我就會輸 ......

    uj5u.com 2023-04-04 08:35:30 more
  • 了解 HTTP 看這一篇就夠

    在學習網路之前,了解它的歷史能夠幫助我們明白為何它會發展為如今這個樣子,引發探究網路的興趣。下面的這張圖片就展示了“互聯網”誕生至今的發展歷程。 ......

    uj5u.com 2023-03-16 11:00:15 more
  • 藍牙-低功耗中心設備

    //11.開啟藍牙配接器 openBluetoothAdapter //21.開始搜索藍牙設備 startBluetoothDevicesDiscovery //31.開啟監聽搜索藍牙設備 onBluetoothDeviceFound //30.停止監聽搜索藍牙設備 offBluetoothDevi ......

    uj5u.com 2023-03-15 09:06:45 more
  • canvas畫板(滑鼠和觸摸)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>canves</title> <style> #canvas { cursor:url(../images/pen.png),crosshair; } #canvasdiv{ bo ......

    uj5u.com 2023-02-15 08:56:31 more
  • 手機端H5 實作自定義拍照界面

    手機端 H5 實作自定義拍照界面也可以使用 MediaDevices API 和 <video> 標簽來實作,和在桌面端做法基本一致。 首先,使用 MediaDevices.getUserMedia() 方法獲取攝像頭媒體流,并將其傳遞給 <video> 標簽進行渲染。 接著,使用 HTML 的 < ......

    uj5u.com 2023-01-12 07:58:22 more
  • 記錄--短視頻滑動播放在 H5 下的實作

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 短視頻已經無數不在了,但是主體還是使用 app 來承載的。本文講述 H5 如何實作 app 的視頻滑動體驗。 無聲勝有聲,一圖頂百辯,且看下圖: 網址鏈接(需在微信或者手Q中瀏覽) 從上圖可以看到,我們主要實作的功能也是本文要講解的有: ......

    uj5u.com 2023-01-04 07:29:05 more
  • 一文讀懂 HTTP/1 HTTP/2 HTTP/3

    從 1989 年萬維網(www)誕生,HTTP(HyperText Transfer Protocol)經歷了眾多版本迭代,WebSocket 也在期間萌芽。1991 年 HTTP0.9 被發明。1996 年出現了 HTTP1.0。2015 年 HTTP2 正式發布。2020 年 HTTP3 或能正... ......

    uj5u.com 2022-12-24 06:56:02 more
  • 【HTML基礎篇002】HTML之form表單超詳解

    ??一、form表單是什么

    ??二、form表單的屬性

    ??三、input中的各種Type屬性值

    ??四、標簽 ......

    uj5u.com 2022-12-18 07:17:06 more