黑木崖--SpringBoot系列之常見面試題
因為之前出了秒殺面試的博文,所以這裡小宋專門寫一篇部落格,講一講常見的SpringBoot面試題。直接進入主題。
文章目錄
SpringBoot面試題
什麼是 Spring Boot?
首先,重要的是要理解 Spring Boot 並不是一個框架,它是一種建立獨立應用程式的更簡單方法,只需要很少或沒有配置(相比於 Spring 來說)。Spring Boot最好的特性之一是它利用現有的 Spring 專案和第三方專案來開發適合生產的應用程式。
說出使用Spring Boot的主要優點?
- 開發基於 Spring 的應用程式很容易。
- Spring Boot 專案所需的開發或工程時間明顯減少,通常會提高整體生產力。
- Spring Boot不需要編寫大量樣板程式碼、XML配置和註釋。
- Spring Boot引導應用程式可以很容易地與Spring生態系統整合,如Spring JDBC、Spring ORM、Spring Data、Spring Security等。
- Spring Boot遵循“固執己見的預設配置”,以減少開發工作(預設配置可以修改)。
- Spring Boot 應用程式提供嵌入式HTTP伺服器,如Tomcat和Jetty,可以輕鬆地開發和測試web應用程式。(這點很贊!普通執行Java程式的方式就能執行基於Spring Boot web 專案,省事很多)
- Spring Boot提供命令列介面(CLI)工具,用於開發和測試Spring Boot應用程式,如Java或Groovy。
- Spring Boot提供了多種外掛,可以使用內建工具(如Maven和Gradle)開發和測試Spring Boot應用程式。
為什麼需要Spring Boot?
Spring Framework旨在簡化J2EE企業應用程式開發。Spring Boot Framework旨在簡化Spring開發。
什麼是 Spring Boot Starters?
Spring Boot Starters 是一系列依賴關係的集合,因為它的存在,專案的依賴之間的關係對我們來說變的更加簡單了。舉個例子:在沒有Spring Boot Starters之前,我們開發REST服務或Web應用程式時; 我們需要使用像Spring MVC,Tomcat和Jackson這樣的庫,這些依賴我們需要手動一個一個新增。但是,有了 Spring Boot Starters 我們只需要一個只需新增一個spring-boot-starter-web一個依賴就可以了,這個依賴包含的字依賴中包含了我們開發REST 服務需要的所有依賴。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
如何在Spring Boot應用程式中使用Jetty而不是Tomcat?
Spring Boot Web starter使用Tomcat作為預設的嵌入式servlet容器, 如果你想使用 Jetty 的話只需要修改pom.xml(Maven)或者build.gradle(Gradle)就可以了。
Maven:
<!--從Web啟動器依賴中排除Tomcat-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--新增Jetty依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
Gradle:
compile("org.springframework.boot:spring-boot-starter-web") {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
}
compile("org.springframework.boot:spring-boot-starter-jetty")
說個題外話,從上面可以看出使用 Gradle 更加簡潔明瞭,但是國內目前還是 Maven 使用的多一點。
介紹一下@SpringBootApplication註解
package org.springframework.boot.autoconfigure;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
......
}
package org.springframework.boot;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
可以看出大概可以把 @SpringBootApplication 看作是 @Configuration、@EnableAutoConfiguration、@ComponentScan 註解的集合。根據 SpringBoot官網,這三個註解的作用分別是:
- @EnableAutoConfiguration:啟用 SpringBoot 的自動配置機制
- @ComponentScan: 掃描被@Component (@Service,@Controller)註解的bean,註解預設會掃描該類所在的包下所有的類。
- @Configuration:允許在上下文中註冊額外的bean或匯入其他配置類
Spring Boot 的自動配置是如何實現的?(重要)
這個是因為@SpringBootApplication 註解的原因,在上一個問題中已經提到了這個註解。我們知道 @SpringBootApplication 看作是 @Configuration、@EnableAutoConfiguration、@ComponentScan 註解的集合。
- @EnableAutoConfiguration:啟用 SpringBoot 的自動配置機制
- @ComponentScan: 掃描被@Component (@Service,@Controller)註解的bean,註解預設會掃描該類所在的包下所有的類。
- @Configuration:允許在上下文中註冊額外的bean或匯入其他配置類
@EnableAutoConfiguration是啟動自動配置的關鍵,原始碼如下(建議自己打斷點除錯,走一遍基本的流程):
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
@EnableAutoConfiguration 註解通過Spring 提供的 @Import 註解匯入了AutoConfigurationImportSelector類(@Import 註解可以匯入配置類或者Bean到當前類中)。
AutoConfigurationImportSelector類中getCandidateConfigurations方法會將所有自動配置類的資訊以 List 的形式返回。這些配置資訊會被 Spring 容器作 bean 來管理。
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
自動配置資訊有了,那麼自動配置還差什麼呢?
@Conditional 註解。@ConditionalOnClass(指定的類必須存在於類路徑下),@ConditionalOnBean(容器中是否有指定的Bean)等等都是對@Conditional註解的擴充套件。拿 Spring Security 的自動配置舉個例子:
SecurityAutoConfiguration中匯入了WebSecurityEnablerConfiguration類,WebSecurityEnablerConfiguration原始碼如下:
@Configuration
@ConditionalOnBean(WebSecurityConfigurerAdapter.class)
@ConditionalOnMissingBean(name = BeanIds.SPRING_SECURITY_FILTER_CHAIN)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@EnableWebSecurity
public class WebSecurityEnablerConfiguration {
}
WebSecurityEnablerConfiguration類中使用@ConditionalOnBean指定了容器中必須還有WebSecurityConfigurerAdapter 類或其實現類。所以,一般情況下 Spring Security 配置類都會去實現 WebSecurityConfigurerAdapter,這樣自動將配置就完成了。
Spring Boot支援哪些嵌入式web容器?
Spring Boot支援以下嵌入式servlet容器:
Name | Servlet Version |
---|---|
Tomcat 9.0 | 4.0 |
Jetty 9.4 | 3.1 |
Undertow 2.0 | 4.0 |
您還可以將Spring boot引導應用程式部署到任何Servlet 3.1+相容的 Web 容器中。
這就是你為什麼可以通過直接像執行 普通 Java 專案一樣執行 SpringBoot 專案。這樣的確省事了很多,方便了我們進行開發,降低了學習難度。
什麼是Spring Security ?
Spring Security 應該屬於 Spring 全家桶中學習曲線比較陡峭的幾個模組之一,下面我將從起源和定義這兩個方面來簡單介紹一下它。
- 起源: Spring Security 實際上起源於 Acegi Security,這個框架能為基於 Spring 的企業應用提供強大而靈活安全訪問控制解決方案,並且框架這個充分利用 Spring 的 IoC 和 AOP 功能,提供宣告式安全訪問控制的功能。後面,隨著這個專案發展, Acegi Security 成為了Spring官方子專案,後來被命名為 “Spring Security”。
- 定義:Spring Security 是一個功能強大且可以高度定製的框架,側重於為Java 應用程式提供身份驗證和授權。——官方介紹。
相關文章
- 前端面試之webpack面試常見問題前端面試Web
- ES6之Promise常見面試題Promise面試題
- 常見 React 面試題React面試題
- mybatis常見面試題MyBatis面試題
- spring常見面試題Spring面試題
- SpringMVC常見面試題SpringMVC面試題
- Docker常見面試題Docker面試題
- vue 常見面試題Vue面試題
- Spring常見面試題!Spring面試題
- Dubbo常見面試題面試題
- 前端常見面試題前端面試題
- ajax常見面試題面試題
- String常見面試題面試題
- Hadoop常見面試題Hadoop面試題
- Golang常見面試題Golang面試題
- Mysql 常見面試題MySql面試題
- Redis 常見面試題Redis面試題
- Redis常見面試題Redis面試題
- 【面試】面試常見問題整理面試
- 【Java面試】JSP常見面試題!JavaJS面試題
- 【Java面試】Servlet常見面試題!JavaServlet面試題
- 【Java面試】 Javascript常見面試題!JavaScript面試題
- 效能測試常見面試題面試題
- 求職面試常見問題:Python常見面試題全解析附答案求職Python面試題
- 【Java面試】Java常見IO面試題!Java面試題
- Vue常見的面試題Vue面試題
- 常見面試題 - URL 解析面試題
- Vue常見面試題整理Vue面試題
- mysql面試常見題目MySql面試
- Redis面試常見問題Redis面試
- 集合常見的面試題面試題
- HashMap常見面試題整理HashMap面試題
- 【硬核】Dubbo常見面試題面試題
- 常見面試SQL問題面試SQL
- Java常見的面試題Java面試題
- Spring 常見面試問題Spring面試
- SSM框架常見面試題SSM框架面試題
- 常見的JVM 面試題JVM面試題