javascript
Spring 面试问题 TOP 50,你会哪些?
1. 一般問題
1.1. 不同版本的 Spring Framework 有哪些主要功能?
1.2. 什么是 Spring Framework?
-
Spring 是一個開源應用框架,旨在降低應用程序開發的復雜度。
-
它是輕量級、松散耦合的。
-
它具有分層體系結構,允許用戶選擇組件,同時還為 J2EE 應用程序開發提供了一個有凝聚力的框架。
-
它可以集成其他框架,如 Structs、Hibernate、EJB 等,所以又稱為框架的框架。
1.3. 列舉 Spring Framework 的優點。
-
由于 Spring Frameworks 的分層架構,用戶可以自由選擇自己需要的組件。
-
Spring Framework 支持 POJO(Plain Old Java Object) 編程,從而具備持續集成和可測試性。
-
由于依賴注入和控制反轉,JDBC 得以簡化。
-
它是開源免費的。
1.4. Spring Framework 有哪些不同的功能?
-
輕量級 - Spring 在代碼量和透明度方面都很輕便。
-
IOC - 控制反轉
-
AOP - 面向切面編程可以將應用業務邏輯和系統服務分離,以實現高內聚。
-
容器 - Spring 負責創建和管理對象(Bean)的生命周期和配置。
-
MVC - 對 web 應用提供了高度可配置性,其他框架的集成也十分方便。
-
事務管理 - 提供了用于事務管理的通用抽象層。Spring 的事務支持也可用于容器較少的環境。
-
JDBC 異常 - Spring 的 JDBC 抽象層提供了一個異常層次結構,簡化了錯誤處理策略。
1.5. Spring Framework 中有多少個模塊,它們分別是什么?
Spring 核心容器?– 該層基本上是 Spring Framework 的核心。它包含以下模塊:
-
Spring Core
-
Spring Bean
-
SpEL (Spring Expression Language)
-
Spring Context
數據訪問/集成?– 該層提供與數據庫交互的支持。它包含以下模塊:
-
JDBC (Java DataBase Connectivity)
-
ORM (Object Relational Mapping)
-
OXM (Object XML Mappers)
-
JMS (Java Messaging Service)
-
Transaction
Web?– 該層提供了創建 Web 應用程序的支持。它包含以下模塊:
-
Web
-
Web – Servlet
-
Web – Socket
-
Web – Portlet
AOP?– 該層支持面向切面編程
Instrumentation?– 該層為類檢測和類加載器實現提供支持。
Test?– 該層為使用 JUnit 和 TestNG 進行測試提供支持。
幾個雜項模塊:
-
Messaging – 該模塊為 STOMP 提供支持。它還支持注解編程模型,該模型用于從 WebSocket 客戶端路由和處理 STOMP 消息。
-
Aspects – 該模塊為與 AspectJ 的集成提供支持。
1.6. 什么是 Spring 配置文件?
Spring 配置文件是 XML 文件。該文件主要包含類信息。它描述了這些類是如何配置以及相互引入的。但是,XML 配置文件冗長且更加干凈。如果沒有正確規劃和編寫,那么在大項目中管理變得非常困難。
1.7. Spring 應用程序有哪些不同組件?
Spring 應用一般有以下組件:
-
接口 - 定義功能。
-
Bean 類 - 它包含屬性,setter 和 getter 方法,函數等。
-
Spring 面向切面編程(AOP) - 提供面向切面編程的功能。
-
Bean 配置文件 - 包含類的信息以及如何配置它們。
-
用戶程序 - 它使用接口。
1.8. 使用 Spring 有哪些方式?
使用 Spring 有以下方式:
-
作為一個成熟的 Spring Web 應用程序。
-
作為第三方 Web 框架,使用 Spring Frameworks 中間層。
-
用于遠程使用。
-
作為企業級 Java Bean,它可以包裝現有的 POJO(Plain Old Java Objects)。
?
2. 依賴注入(Ioc)
2.1. 什么是 Spring IOC 容器?
Spring 框架的核心是 Spring 容器。容器創建對象,將它們裝配在一起,配置它們并管理它們的完整生命周期。Spring 容器使用依賴注入來管理組成應用程序的組件。容器通過讀取提供的配置元數據來接收對象進行實例化,配置和組裝的指令。該元數據可以通過 XML,Java 注解或 Java 代碼提供。
2.2. 什么是依賴注入?
在依賴注入中,您不必創建對象,但必須描述如何創建它們。您不是直接在代碼中將組件和服務連接在一起,而是描述配置文件中哪些組件需要哪些服務。由 IoC 容器將它們裝配在一起。
2.3. 可以通過多少種方式完成依賴注入?
通常,依賴注入可以通過三種方式完成,即:
-
構造函數注入
-
setter 注入
-
接口注入
在 Spring Framework 中,僅使用構造函數和 setter 注入。
2.4. 區分構造函數注入和 setter 注入。
2.5. spring 中有多少種 IOC 容器?
-
BeanFactory - BeanFactory 就像一個包含 bean 集合的工廠類。它會在客戶端要求時實例化 bean。
-
ApplicationContext - ApplicationContext 接口擴展了 BeanFactory 接口。它在 BeanFactory 基礎上提供了一些額外的功能。
2.6. 區分 BeanFactory 和 ApplicationContext。
2.7. 列舉 IoC 的一些好處。
IoC 的一些好處是:
-
它將最小化應用程序中的代碼量。
-
它將使您的應用程序易于測試,因為它不需要單元測試用例中的任何單例或 JNDI 查找機制。
-
它以最小的影響和最少的侵入機制促進松耦合。
-
它支持即時的實例化和延遲加載服務。
2.8. Spring IoC 的實現機制。
Spring 中的 IoC 的實現原理就是工廠模式加反射機制。
示例:
interface Fruit {
? ? ?public abstract void eat();
}
class Apple implements Fruit {
? ? public void eat(){
? ? ? ? System.out.println("Apple");
? ? }
}
class Orange implements Fruit {
? ? public void eat(){
? ? ? ? System.out.println("Orange");
? ? }
}
class Factory {
? ? public static Fruit getInstance(String ClassName) {
? ? ? ? Fruit f=null;
? ? ? ? try {
? ? ? ? ? ? f=(Fruit)Class.forName(ClassName).newInstance();
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? ? ? return f;
? ? }
}
class Client {
? ? public static void main(String[] a) {
? ? ? ? Fruit f=Factory.getInstance("io.github.dunwu.spring.Apple");
? ? ? ? if(f!=null){
? ? ? ? ? ? f.eat();
? ? ? ? }
? ? }
}
?
3. Beans
3.1. 什么是 spring bean?
-
它們是構成用戶應用程序主干的對象。
-
Bean 由 Spring IoC 容器管理。
-
它們由 Spring IoC 容器實例化,配置,裝配和管理。
-
Bean 是基于用戶提供給容器的配置元數據創建。
3.2. spring 提供了哪些配置方式?
-
基于 xml 配置
bean 所需的依賴項和服務在 XML 格式的配置文件中指定。這些配置文件通常包含許多 bean 定義和特定于應用程序的配置選項。它們通常以 bean 標簽開頭。例如:
<bean id="studentbean" class="org.edureka.firstSpring.StudentBean">
?<property name="name" value="Edureka"></property>
</bean>
-
基于注解配置
您可以通過在相關的類,方法或字段聲明上使用注解,將 bean 配置為組件類本身,而不是使用 XML 來描述 bean 裝配。默認情況下,Spring 容器中未打開注解裝配。因此,您需要在使用它之前在 Spring 配置文件中啟用它。例如:
<beans>
<context:annotation-config/>
<!-- bean definitions go here -->
</beans>
-
基于 Java API 配置
Spring 的 Java 配置是通過使用 @Bean 和 @Configuration 來實現。
@Bean 注解扮演與 <bean /> 元素相同的角色。
@Configuration 類允許通過簡單地調用同一個類中的其他 @Bean 方法來定義 bean 間依賴關系。
例如:
@Configuration
public class StudentConfig {
? ? @Bean
? ? public StudentBean myStudent() {
? ? ? ? return new StudentBean();
? ? }
}
3.3. spring 支持集中 bean scope?
Spring bean 支持 5 種 scope:
-
Singleton - 每個 Spring IoC 容器僅有一個單實例。
-
Prototype - 每次請求都會產生一個新的實例。
-
Request - 每一次 HTTP 請求都會產生一個新的實例,并且該 bean 僅在當前 HTTP 請求內有效。
-
Session - 每一次 HTTP 請求都會產生一個新的 bean,同時該 bean 僅在當前 HTTP session 內有效。
-
Global-session - 類似于標準的 HTTP Session 作用域,不過它僅僅在基于 portlet 的 web 應用中才有意義。Portlet 規范定義了全局 Session 的概念,它被所有構成某個 portlet web 應用的各種不同的 portlet 所共享。在 global session 作用域中定義的 bean 被限定于全局 portlet Session 的生命周期范圍內。如果你在 web 中使用 global session 作用域來標識 bean,那么 web 會自動當成 session 類型來使用。
僅當用戶使用支持 Web 的 ApplicationContext 時,最后三個才可用。
3.4. spring bean 容器的生命周期是什么樣的?
spring bean 容器的生命周期流程如下:
Spring 容器根據配置中的 bean 定義中實例化 bean。
Spring 使用依賴注入填充所有屬性,如 bean 中所定義的配置。
如果 bean 實現 BeanNameAware 接口,則工廠通過傳遞 bean 的 ID 來調用 setBeanName()。
如果 bean 實現 BeanFactoryAware 接口,工廠通過傳遞自身的實例來調用 setBeanFactory()。
如果存在與 bean 關聯的任何 BeanPostProcessors,則調用 preProcessBeforeInitialization() 方法。
如果為 bean 指定了 init 方法(<bean> 的 init-method 屬性),那么將調用它。
最后,如果存在與 bean 關聯的任何 BeanPostProcessors,則將調用 postProcessAfterInitialization() 方法。
如果 bean 實現 DisposableBean 接口,當 spring 容器關閉時,會調用 destory()。
如果為 bean 指定了 destroy 方法(<bean> 的 destroy-method 屬性),那么將調用它。
3.5. 什么是 spring 的內部 bean?
只有將 bean 用作另一個 bean 的屬性時,才能將 bean 聲明為內部 bean。為了定義 bean,Spring 的基于 XML 的配置元數據在 <property> 或 <constructor-arg> 中提供了 <bean> 元素的使用。內部 bean 總是匿名的,它們總是作為原型。
例如,假設我們有一個 Student 類,其中引用了 Person 類。這里我們將只創建一個 Person 類實例并在 Student 中使用它。
Student.java
public class Student {
? ? private Person person;
? ? //Setters and Getters
}
public class Person {
? ? private String name;
? ? private String address;
? ? //Setters and Getters
}
bean.xml
<bean id=“StudentBean" class="com.edureka.Student">
? ? <property name="person">
? ? ? ? <!--This is inner bean -->
? ? ? ? <bean class="com.edureka.Person">
? ? ? ? ? ? <property name="name" value=“Scott"></property>
? ? ? ? ? ? <property name="address" value=“Bangalore"></property>
? ? ? ? </bean>
? ? </property>
</bean>
3.6. 什么是 spring 裝配
當 bean 在 Spring 容器中組合在一起時,它被稱為裝配或 bean 裝配。 Spring 容器需要知道需要什么 bean 以及容器應該如何使用依賴注入來將 bean 綁定在一起,同時裝配 bean。
3.7. 自動裝配有哪些方式?
Spring 容器能夠自動裝配 bean。也就是說,可以通過檢查 BeanFactory 的內容讓 Spring 自動解析 bean 的協作者。
自動裝配的不同模式:
-
no - 這是默認設置,表示沒有自動裝配。應使用顯式 bean 引用進行裝配。
-
byName - 它根據 bean 的名稱注入對象依賴項。它匹配并裝配其屬性與 XML 文件中由相同名稱定義的 bean。
-
byType - 它根據類型注入對象依賴項。如果屬性的類型與 XML 文件中的一個 bean 名稱匹配,則匹配并裝配屬性。
-
構造函數 - 它通過調用類的構造函數來注入依賴項。它有大量的參數。
-
autodetect - 首先容器嘗試通過構造函數使用 autowire 裝配,如果不能,則嘗試通過 byType 自動裝配。
3.8. 自動裝配有什么局限?
-
覆蓋的可能性 - 您始終可以使用 <constructor-arg> 和 <property> 設置指定依賴項,這將覆蓋自動裝配。
-
基本元數據類型 - 簡單屬性(如原數據類型,字符串和類)無法自動裝配。
-
令人困惑的性質 - 總是喜歡使用明確的裝配,因為自動裝配不太精確。
?
4. 注解
4.1. 什么是基于注解的容器配置
不使用 XML 來描述 bean 裝配,開發人員通過在相關的類,方法或字段聲明上使用注解將配置移動到組件類本身。它可以作為 XML 設置的替代方案。例如:
Spring 的 Java 配置是通過使用 @Bean 和 @Configuration 來實現。
-
@Bean 注解扮演與 元素相同的角色。
-
@Configuration 類允許通過簡單地調用同一個類中的其他 @Bean 方法來定義 bean 間依賴關系。
例如:
@Configuration
public class StudentConfig {
? ? @Bean
? ? public StudentBean myStudent() {
? ? ? ? return new StudentBean();
? ? }
}
4.2. 如何在 spring 中啟動注解裝配?
默認情況下,Spring 容器中未打開注解裝配。因此,要使用基于注解裝配,我們必須通過配置<context:annotation-config /> 元素在 Spring 配置文件中啟用它。
4.3. @Component, @Controller, @Repository, @Service 有何區別?
-
@Component:這將 java 類標記為 bean。它是任何 Spring 管理組件的通用構造型。spring 的組件掃描機制現在可以將其拾取并將其拉入應用程序環境中。
-
@Controller:這將一個類標記為 Spring Web MVC 控制器。標有它的 Bean 會自動導入到 IoC 容器中。
-
@Service:此注解是組件注解的特化。它不會對 @Component 注解提供任何其他行為。您可以在服務層類中使用 @Service 而不是 @Component,因為它以更好的方式指定了意圖。
-
@Repository:這個注解是具有類似用途和功能的 @Component 注解的特化。它為 DAO 提供了額外的好處。它將 DAO 導入 IoC 容器,并使未經檢查的異常有資格轉換為 Spring DataAccessException。
4.4. @Required 注解有什么用?
@Required 應用于 bean 屬性 setter 方法。此注解僅指示必須在配置時使用 bean 定義中的顯式屬性值或使用自動裝配填充受影響的 bean 屬性。如果尚未填充受影響的 bean 屬性,則容器將拋出 BeanInitializationException。
示例:
public class Employee {
? ? private String name;
? ? @Required
? ? public void setName(String name){
? ? ? ? this.name=name;
? ? }
? ? public string getName(){
? ? ? ? return name;
? ? }
}
4.5. @Autowired 注解有什么用?
@Autowired 可以更準確地控制應該在何處以及如何進行自動裝配。此注解用于在 setter 方法,構造函數,具有任意名稱或多個參數的屬性或方法上自動裝配 bean。默認情況下,它是類型驅動的注入。
public class Employee {
? ? private String name;
? ? @Autowired
? ? public void setName(String name) {
? ? ? ? this.name=name;
? ? }
? ? public string getName(){
? ? ? ? return name;
? ? }
}
4.6. @Qualifier 注解有什么用?
當您創建多個相同類型的 bean 并希望僅使用屬性裝配其中一個 bean 時,您可以使用@Qualifier 注解和 @Autowired 通過指定應該裝配哪個確切的 bean 來消除歧義。
例如,這里我們分別有兩個類,Employee 和 EmpAccount。在 EmpAccount 中,使用@Qualifier 指定了必須裝配 id 為 emp1 的 bean。
Employee.java
public class Employee {
? ? private String name;
? ? @Autowired
? ? public void setName(String name) {
? ? ? ? this.name=name;
? ? }
? ? public string getName() {
? ? ? ? return name;
? ? }
}
EmpAccount.java
public class EmpAccount {
? ? private Employee emp;
?
? ? @Autowired
? ? @Qualifier(emp1)
? ? public void showName() {
? ? ? ? System.out.println(“Employee name : ”+emp.getName);
? ? }
}
4.7. @RequestMapping 注解有什么用?
@RequestMapping 注解用于將特定 HTTP 請求方法映射到將處理相應請求的控制器中的特定類/方法。此注釋可應用于兩個級別:
-
類級別:映射請求的 URL
-
方法級別:映射 URL 以及 HTTP 請求方法
?
5. 數據訪問
5.1. spring DAO 有什么用?
Spring DAO 使得 JDBC,Hibernate 或 JDO 這樣的數據訪問技術更容易以一種統一的方式工作。這使得用戶容易在持久性技術之間切換。它還允許您在編寫代碼時,無需考慮捕獲每種技術不同的異常。
5.2. 列舉 Spring DAO 拋出的異常。
5.3. spring JDBC API 中存在哪些類?
-
JdbcTemplate
-
SimpleJdbcTemplate
-
NamedParameterJdbcTemplate
-
SimpleJdbcInsert
-
SimpleJdbcCall
5.4. 使用 Spring 訪問 Hibernate 的方法有哪些?
我們可以通過兩種方式使用 Spring 訪問 Hibernate:
使用 Hibernate 模板和回調進行控制反轉
擴展 HibernateDAOSupport 并應用 AOP 攔截器節點
5.5. 列舉 spring 支持的事務管理類型
Spring 支持兩種類型的事務管理:
程序化事務管理:在此過程中,在編程的幫助下管理事務。它為您提供極大的靈活性,但維護起來非常困難。
聲明式事務管理:在此,事務管理與業務代碼分離。僅使用注解或基于 XML 的配置來管理事務。
5.6. spring 支持哪些 ORM 框架
-
Hibernate
-
iBatis
-
JPA
-
JDO
-
OJB
?
6. AOP
6.1. 什么是 AOP?
AOP(Aspect-Oriented Programming), 即 面向切面編程, 它與 OOP( Object-Oriented Programming, 面向對象編程) 相輔相成, 提供了與 OOP 不同的抽象軟件結構的視角.
在 OOP 中, 我們以類(class)作為我們的基本單元, 而 AOP 中的基本單元是 Aspect(切面)
6.2. 什么是 Aspect?
aspect 由 pointcount 和 advice 組成, 它既包含了橫切邏輯的定義, 也包括了連接點的定義. Spring AOP 就是負責實施切面的框架, 它將切面所定義的橫切邏輯編織到切面所指定的連接點中.
AOP 的工作重心在于如何將增強編織目標對象的連接點上, 這里包含兩個工作:
如何通過 pointcut 和 advice 定位到特定的 joinpoint 上
如何在 advice 中編寫切面代碼.
可以簡單地認為, 使用 @Aspect 注解的類就是切面.
6.3. 什么是切點(JoinPoint)
程序運行中的一些時間點, 例如一個方法的執行, 或者是一個異常的處理.
在 Spring AOP 中, join point 總是方法的執行點。
6.4. 什么是通知(Advice)?
特定 JoinPoint 處的 Aspect 所采取的動作稱為 Advice。Spring AOP 使用一個 Advice 作為攔截器,在 JoinPoint “周圍”維護一系列的攔截器。
6.5. 有哪些類型的通知(Advice)?
-
Before - 這些類型的 Advice 在 joinpoint 方法之前執行,并使用 @Before 注解標記進行配置。
-
After Returning - 這些類型的 Advice 在連接點方法正常執行后執行,并使用@AfterReturning 注解標記進行配置。
-
After Throwing - 這些類型的 Advice 僅在 joinpoint 方法通過拋出異常退出并使用 @AfterThrowing 注解標記配置時執行。
-
After (finally) - 這些類型的 Advice 在連接點方法之后執行,無論方法退出是正常還是異常返回,并使用 @After 注解標記進行配置。
-
Around - 這些類型的 Advice 在連接點之前和之后執行,并使用 @Around 注解標記進行配置。
6.6. 指出在 spring aop 中 concern 和 cross-cutting concern 的不同之處。
concern 是我們想要在應用程序的特定模塊中定義的行為。它可以定義為我們想要實現的功能。
cross-cutting concern 是一個適用于整個應用的行為,這會影響整個應用程序。例如,日志記錄,安全性和數據傳輸是應用程序幾乎每個模塊都需要關注的問題,因此它們是跨領域的問題。
6.7. AOP 有哪些實現方式?
實現 AOP 的技術,主要分為兩大類:
靜態代理?- 指使用 AOP 框架提供的命令進行編譯,從而在編譯階段就可生成 AOP 代理類,因此也稱為編譯時增強;
-
編譯時編織(特殊編譯器實現)
-
類加載時編織(特殊的類加載器實現)。
動態代理?- 在運行時在內存中“臨時”生成 AOP 動態代理類,因此也被稱為運行時增強。
-
JDK 動態代理
-
CGLIB
6.8. Spring AOP and AspectJ AOP 有什么區別?
Spring AOP 基于動態代理方式實現;AspectJ 基于靜態代理方式實現。
Spring AOP 僅支持方法級別的 PointCut;提供了完全的 AOP 支持,它還支持屬性級別的 PointCut。
6.9. 如何理解 Spring 中的代理?
將 Advice 應用于目標對象后創建的對象稱為代理。在客戶端對象的情況下,目標對象和代理對象是相同的。
Advice + Target Object = Proxy
6.10. 什么是編織(Weaving)?
為了創建一個 advice 對象而鏈接一個 aspect 和其它應用類型或對象,稱為編織(Weaving)。在 Spring AOP 中,編織在運行時執行。請參考下圖:
?
7. MVC
7.1. Spring MVC 框架有什么用?
Spring Web MVC 框架提供 模型-視圖-控制器 架構和隨時可用的組件,用于開發靈活且松散耦合的 Web 應用程序。 MVC 模式有助于分離應用程序的不同方面,如輸入邏輯,業務邏輯和 UI 邏輯,同時在所有這些元素之間提供松散耦合。
7.2. 描述一下 DispatcherServlet 的工作流程
DispatcherServlet 的工作流程可以用一幅圖來說明:
1. 向服務器發送 HTTP 請求,請求被前端控制器 DispatcherServlet 捕獲。
2. DispatcherServlet 根據 -servlet.xml 中的配置對請求的 URL 進行解析,得到請求資源標識符(URI)。然后根據該 URI,調用 HandlerMapping 獲得該 Handler 配置的所有相關的對象(包括 Handler 對象以及 Handler 對象對應的攔截器),最后以HandlerExecutionChain 對象的形式返回。
3. DispatcherServlet 根據獲得的Handler,選擇一個合適的 HandlerAdapter。(附注:如果成功獲得HandlerAdapter后,此時將開始執行攔截器的 preHandler(...)方法)。
4. 提取Request中的模型數據,填充Handler入參,開始執行Handler(Controller)。 在填充Handler的入參過程中,根據你的配置,Spring 將幫你做一些額外的工作:
-
HttpMessageConveter: 將請求消息(如 Json、xml 等數據)轉換成一個對象,將對象轉換為指定的響應信息。
-
數據轉換:對請求消息進行數據轉換。如String轉換成Integer、Double等。
-
數據根式化:對請求消息進行數據格式化。 如將字符串轉換成格式化數字或格式化日期等。
-
數據驗證: 驗證數據的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中。
5. Handler(Controller)執行完成后,向 DispatcherServlet 返回一個 ModelAndView 對象;
6. 根據返回的ModelAndView,選擇一個適合的 ViewResolver(必須是已經注冊到 Spring 容器中的ViewResolver)返回給DispatcherServlet。
7. ViewResolver 結合Model和View,來渲染視圖。
8. 視圖負責將渲染結果返回給客戶端。
7.3. 介紹一下 WebApplicationContext
WebApplicationContext 是 ApplicationContext 的擴展。它具有 Web 應用程序所需的一些額外功能。它與普通的 ApplicationContext 在解析主題和決定與哪個 servlet 關聯的能力方面有所不同。
想學習更多 Spring 內容可以訪問我的 Spring 教程:spring-notes
?
8. 資料
-
Top 50 Spring Interview Questions You Must Prepare In 2018
https://www.edureka.co/blog/interview-questions/spring-interview-questions/
總結
以上是生活随笔為你收集整理的Spring 面试问题 TOP 50,你会哪些?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 烂代码长什么样?
- 下一篇: 再有人问 Java 中的注解就把这篇文章