SpringBoot高頻面試題

来源:https://www.cnblogs.com/tyson03/archive/2023/04/01/17277964.html
-Advertisement-
Play Games

Springboot的優點 內置servlet容器,不需要在伺服器部署 tomcat。只需要將項目打成 jar 包,使用 java -jar xxx.jar一鍵式啟動項目 SpringBoot提供了starter,把常用庫聚合在一起,簡化複雜的環境配置,快速搭建spring應用環境 可以快速創建獨立 ...


Springboot的優點

  • 內置servlet容器,不需要在伺服器部署 tomcat。只需要將項目打成 jar 包,使用 java -jar xxx.jar一鍵式啟動項目
  • SpringBoot提供了starter,把常用庫聚合在一起,簡化複雜的環境配置,快速搭建spring應用環境
  • 可以快速創建獨立運行的spring項目,集成主流框架
  • 準生產環境的運行應用監控

SpringBoot 中的 starter 到底是什麼 ?

starter提供了一個自動化配置類,一般命名為 XXXAutoConfiguration ,在這個配置類中通過條件註解來決定一個配置是否生效(條件註解就是 Spring 中原本就有的),然後它還會提供一系列的預設配置,也允許開發者根據實際情況自定義相關配置,然後通過類型安全的屬性註入將這些配置屬性註入進來,新註入的屬性會代替掉預設屬性。正因為如此,很多第三方框架,我們只需要引入依賴就可以直接使用了。

運行 SpringBoot 有哪幾種方式?

  1. 打包用命令或者者放到容器中運行
  2. 用 Maven/Gradle 插件運行
  3. 直接執行 main 方法運行

SpringBoot 常用的 Starter 有哪些?

  1. spring-boot-starter-web :提供 Spring MVC + 內嵌的 Tomcat 。
  2. spring-boot-starter-data-jpa :提供 Spring JPA + Hibernate 。
  3. spring-boot-starter-data-Redis :提供 Redis 。
  4. mybatis-spring-boot-starter :提供 MyBatis 。

Spring Boot 的核心註解是哪個?

啟動類上面的註解是@SpringBootApplication,它也是 Spring Boot 的核心註解,主要組合包含了以下 3 個註解:

  • @SpringBootConfiguration:組合了 @Configuration 註解,實現配置文件的功能。
  • @EnableAutoConfiguration:打開自動配置的功能,也可以關閉某個自動配置的選項,如關閉數據源自動配置功能: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。
  • @ComponentScan:Spring組件掃描。

本文已經收錄到Github倉庫,該倉庫包含電腦基礎、Java基礎、多線程、JVM、資料庫、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分散式、微服務、設計模式、架構、校招社招分享等核心知識點,歡迎star~

Github地址

如果訪問不了Github,可以訪問gitee地址。

gitee地址

自動配置原理

SpringBoot實現自動配置原理圖解:

在 application.properties 中設置屬性 debug=true,可以在控制台查看已啟用和未啟用的自動配置。

@SpringBootApplication是@Configuration、@EnableAutoConfiguration和@ComponentScan的組合。

@Configuration表示該類是Java配置類。

@ComponentScan開啟自動掃描符合條件的bean(添加了@Controller、@Service等註解)。

@EnableAutoConfiguration會根據類路徑中的jar依賴為項目進行自動配置,比如添加了spring-boot-starter-web依賴,會自動添加Tomcat和Spring MVC的依賴,然後Spring Boot會對Tomcat和Spring MVC進行自動配置(spring.factories EnableAutoConfiguration配置了WebMvcAutoConfiguration)。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}

EnableAutoConfiguration主要由 @AutoConfigurationPackage,@Import(EnableAutoConfigurationImportSelector.class)這兩個註解組成的。

@AutoConfigurationPackage用於將啟動類所在的包裡面的所有組件註冊到spring容器。

@Import 將EnableAutoConfigurationImportSelector註入到spring容器中,EnableAutoConfigurationImportSelector通過SpringFactoriesLoader從類路徑下去讀取META-INF/spring.factories文件信息,此文件中有一個key為org.springframework.boot.autoconfigure.EnableAutoConfiguration,定義了一組需要自動配置的bean。

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\

這些配置類不是都會被載入,會根據xxxAutoConfiguration上的@ConditionalOnClass等條件判斷是否載入,符合條件才會將相應的組件被載入到spring容器。(比如mybatis-spring-boot-starter,會自動配置sqlSessionFactory、sqlSessionTemplate、dataSource等mybatis所需的組件)

最全面的Java面試網站

@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class,
		AnnotatedElement.class }) //類路徑存在EnableAspectJAutoProxy等類文件,才會載入此配置類
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {

	@Configuration
	@EnableAspectJAutoProxy(proxyTargetClass = false)
	@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false)
	public static class JdkDynamicAutoProxyConfiguration {

	}

	@Configuration
	@EnableAspectJAutoProxy(proxyTargetClass = true)
	@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
	public static class CglibAutoProxyConfiguration {

	}

}

全局配置文件中的屬性如何生效,比如:server.port=8081,是如何生效的?

@ConfigurationProperties的作用就是將配置文件的屬性綁定到對應的bean上。全局配置的屬性如:server.port等,通過@ConfigurationProperties註解,綁定到對應的XxxxProperties bean,通過這個 bean 獲取相應的屬性(serverProperties.getPort())。

//server.port = 8080
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
	private Integer port;
	private InetAddress address;

	@NestedConfigurationProperty
	private final ErrorProperties error = new ErrorProperties();
	private Boolean useForwardHeaders;
	private String serverHeader;
    //...
}

實現自動配置

實現當某個類存在時,自動配置這個類的bean,並且可以在application.properties中配置bean的屬性。

(1)新建Maven項目spring-boot-starter-hello,修改pom.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.tyson</groupId>
    <artifactId>spring-boot-starter-hello</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>1.3.0.M1</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
        </dependency>
    </dependencies>

</project>

(2)屬性配置

public class HelloService {
    private String msg;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String sayHello() {
        return "hello" + msg;

    }
}


import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix="hello")
public class HelloServiceProperties {
    private static final String MSG = "world";
    private String msg = MSG;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

(3)自動配置類

import com.tyson.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties(HelloServiceProperties.class) //1
@ConditionalOnClass(HelloService.class) //2
@ConditionalOnProperty(prefix="hello", value = "enabled", matchIfMissing = true) //3
public class HelloServiceAutoConfiguration {

    @Autowired
    private HelloServiceProperties helloServiceProperties;

    @Bean
    @ConditionalOnMissingBean(HelloService.class) //4
    public HelloService helloService() {
        HelloService helloService = new HelloService();
        helloService.setMsg(helloServiceProperties.getMsg());
        return helloService;
    }
}
  1. @EnableConfigurationProperties 註解開啟屬性註入,將帶有@ConfigurationProperties 註解的類註入為Spring 容器的 Bean。

  2. 當 HelloService 在類路徑的條件下。

  3. 當設置 hello=enabled 的情況下,如果沒有設置則預設為 true,即條件符合。

  4. 當容器沒有這個 Bean 的時候。

(4)註冊配置

想要自動配置生效,需要註冊自動配置類。在 src/main/resources 下新建 META-INF/spring.factories。添加以下內容:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.tyson.config.HelloServiceAutoConfiguration

"\"是為了換行後仍然能讀到屬性。若有多個自動配置,則用逗號隔開。

(5)使用starter

在 Spring Boot 項目的 pom.xml 中添加:

<dependency>
    <groupId>com.tyson</groupId>
    <artifactId>spring-boot-starter-hello</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

運行類如下:

import com.tyson.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
public class SpringbootDemoApplication {

    @Autowired
    public HelloService helloService;

    @RequestMapping("/")
    public String index() {
        return helloService.getMsg();
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringbootDemoApplication.class, args);
    }

}

在項目中沒有配置 HelloService bean,但是我們可以註入這個bean,這是通過自動配置實現的。

在 application.properties 中添加 debug 屬性,運行配置類,在控制台可以看到:

   HelloServiceAutoConfiguration matched:
      - @ConditionalOnClass found required class 'com.tyson.service.HelloService' (OnClassCondition)
      - @ConditionalOnProperty (hello.enabled) matched (OnPropertyCondition)

   HelloServiceAutoConfiguration#helloService matched:
      - @ConditionalOnMissingBean (types: com.tyson.service.HelloService; SearchStrategy: all) did not find any beans (OnBeanCondition)

可以在 application.properties 中配置 msg 的內容:

hello.msg=大彬

@Value註解的原理

@Value的解析就是在bean初始化階段。BeanPostProcessor定義了bean初始化前後用戶可以對bean進行操作的介面方法,它的一個重要實現類AutowiredAnnotationBeanPostProcessor為bean中的@Autowired和@Value註解的註入功能提供支持。

Spring Boot 需要獨立的容器運行嗎?

不需要,內置了 Tomcat/ Jetty 等容器。

Spring Boot 支持哪些日誌框架?

Spring Boot 支持 Java Util Logging, Log4j2, Lockback 作為日誌框架,如果你使用 Starters 啟動器,Spring Boot 將使用 Logback 作為預設日誌框架,但是不管是那種日誌框架他都支持將配置文件輸出到控制台或者文件中。

YAML 配置的優勢在哪裡 ?

YAML 配置和傳統的 properties 配置相比之下,有這些優勢:

  • 配置有序
  • 簡潔明瞭,支持數組,數組中的元素可以是基本數據類型也可以是對象

缺點就是不支持 @PropertySource 註解導入自定義的 YAML 配置。

什麼是 Spring Profiles?

在項目的開發中,有些配置文件在開發、測試或者生產等不同環境中可能是不同的,例如資料庫連接、redis的配置等等。那我們如何在不同環境中自動實現配置的切換呢?Spring給我們提供了profiles機制給我們提供的就是來回切換配置文件的功能

Spring Profiles 允許用戶根據配置文件(dev,test,prod 等)來註冊 bean。因此,當應用程式在開發中運行時,只有某些 bean 可以載入,而在 PRODUCTION中,某些其他 bean 可以載入。假設我們的要求是 Swagger 文檔僅適用於 QA 環境,並且禁用所有其他文檔。這可以使用配置文件來完成。Spring Boot 使得使用配置文件非常簡單。

SpringBoot多數據源事務如何管理

第一種方式是在service層的@TransactionManager中使用transactionManager指定DataSourceConfig中配置的事務。

第二種是使用jta-atomikos實現分散式事務管理。

spring-boot-starter-parent 有什麼用 ?

新創建一個 Spring Boot 項目,預設都是有 parent 的,這個 parent 就是 spring-boot-starter-parent ,spring-boot-starter-parent 主要有如下作用:

  1. 定義了 Java 編譯版本。
  2. 使用 UTF-8 格式編碼。
  3. 執行打包操作的配置。
  4. 自動化的資源過濾。
  5. 自動化的插件配置。
  6. 針對 application.properties 和 application.yml 的資源過濾,包括通過 profile 定義的不同環境的配置文件,例如 application-dev.properties 和 application-dev.yml。

Spring Boot 打成的 jar 和普通的 jar 有什麼區別 ?

  • Spring Boot 項目最終打包成的 jar 是可執行 jar ,這種 jar 可以直接通過 java -jar xxx.jar 命令來運行,這種 jar 不可以作為普通的 jar 被其他項目依賴,即使依賴了也無法使用其中的類。
  • Spring Boot 的 jar 無法被其他項目依賴,主要還是他和普通 jar 的結構不同。普通的 jar 包,解壓後直接就是包名,包里就是我們的代碼,而 Spring Boot 打包成的可執行 jar 解壓後,在 \BOOT-INF\classes 目錄下才是我們的代碼,因此無法被直接引用。如果非要引用,可以在 pom.xml 文件中增加配置,將 Spring Boot 項目打包成兩個 jar ,一個可執行,一個可引用。

SpringBoot多數據源拆分的思路

先在properties配置文件中配置兩個數據源,創建分包mapper,使用@ConfigurationProperties讀取properties中的配置,使用@MapperScan註冊到對應的mapper包中 。

最後給大家分享一個Github倉庫,上面有大彬整理的300多本經典的電腦書籍PDF,包括C語言、C++、Java、Python、前端、資料庫、操作系統、電腦網路、數據結構和演算法、機器學習、編程人生等,可以star一下,下次找書直接在上面搜索,倉庫持續更新中~

Github地址


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 代碼的簡潔、美感、可讀性等等也許不影響程式的執行,但是卻對人(開發者)的影響非常之大,甚至可以說是影響開發者幸福感的重要因素之一; 瞭解一些有美感的代碼,不僅可以在一定程度上提高程式員們的開發效率,有些還能提高代碼的性能,可謂是一舉 ...
  • react三大屬性 一.狀態 類組件1. state 是組件的屬性,值是對象。state中的數據是可讀可寫的,通過更新state來更新對應的頁面顯示(重新渲染組件),通過setState來更新state數據且更新是一種合併 ,在類組件中使用.組件自定義的方法中this為undefined(1)強制綁 ...
  • 創建 Vue3 項目的步驟如下: 安裝 Node.js Vue3 需要依賴 Node.js 環境,因此需要先安裝 Node.js。可以從官網下載 Node.js 的安裝包並安裝,也可以使用包管理器安裝,例如在 Ubuntu 上可以使用以下命令安裝: sudo apt-get update sudo ...
  • 拖放排序列表是一種廣泛使用的 UI 元素,允許用戶通過將項目拖放到所需位置來重新排序。這個功能可以在許多網路應用程式中找到,比如任務管理器和電子商務網站。 在這篇博文中,您將學習如何使用 HTML、CSS 和 JavaScript 創建拖放可排序列表。不使用任何外部 JavaScript 庫來創建這 ...
  • 之前,整個《現代圖片性能優化及體驗優化指南》分了 5 篇來發,本文是系列合集,方便大家收藏及連貫閱讀。 圖片資源,在我們的業務中可謂是占據了非常大頭的一環,尤其是其對帶寬的消耗是十分巨大的。 對圖片的性能優化及體驗優化在今天就顯得尤為重要。本文,就將從各個方面闡述,在各種新特性滿頭飛的今天,我們可以 ...
  • 當今世界,雲計算技術在快速發展,不斷為我們帶來新的應用場景和解決方案。作為一名前端開發者,瞭解雲技術並掌握如何在前端中應用它們是必不可少的。本篇文章將介紹雲計算技術的基本概念,並從前端角度探討如何使用雲技術提高應用的可擴展性、安全性、性能和用戶體驗。 ...
  • 使用vue3+ts開發的工具網頁 手機PC都能訪問 http://in-git.gitee.io/in-nav/#/ 有多源網址,可隨心所欲的切換 內置瀏覽器支持拖拽多開 ...
  • 前一篇我們聊了聊ChatGPT API接入微信公眾號的數據流。 現在稍微介紹詳細點,僅供參考。這是個通用的解決方案,並不僅限於ChatGPT API的調用。 本文有以下內容: 數據流詳細介紹 一點筆記 與AI對話怎樣問問題 法律條文 演示截圖 1. 數據流詳細介紹 之前我們已經知道,在公眾號中與AI ...
一周排行
    -Advertisement-
    Play Games
  • 下麵是一個標準的IDistributedCache用例: public class SomeService(IDistributedCache cache) { public async Task<SomeInformation> GetSomeInformationAsync (string na ...
  • 這個庫提供了在啟動期間實例化已註冊的單例,而不是在首次使用它時實例化。 單例通常在首次使用時創建,這可能會導致響應傳入請求的延遲高於平時。在註冊時創建實例有助於防止第一次Request請求的SLA 以往我們要在註冊的時候實例單例可能會這樣寫: //註冊: services.AddSingleton< ...
  • 最近公司的很多項目都要改單點登錄了,不過大部分都還沒敲定,目前立刻要做的就只有一個比較老的項目 先改一個試試手,主要目標就是最短最快實現功能 首先因為要保留原登錄方式,所以頁面上的改動就是在原來登錄頁面下加一個SSO登錄入口 用超鏈接寫的入口,頁面改造後如下圖: 其中超鏈接的 href="Staff ...
  • Like運算符很好用,特別是它所提供的其中*、?這兩種通配符,在Windows文件系統和各類項目中運用非常廣泛。 但Like運算符僅在VB中支持,在C#中,如何實現呢? 以下是關於LikeString的四種實現方式,其中第四種為Regex正則表達式實現,且在.NET Standard 2.0及以上平... ...
  • 一:背景 1. 講故事 前些天有位朋友找到我,說他們的程式記憶體會偶發性暴漲,自己分析了下是非托管記憶體問題,讓我幫忙看下怎麼回事?哈哈,看到這個dump我還是非常有興趣的,居然還有這種游戲幣自助機類型的程式,下次去大玩家看看他們出幣的機器後端是不是C#寫的?由於dump是linux上的程式,剛好win ...
  • 前言 大家好,我是老馬。很高興遇到你。 我們為 java 開發者實現了 java 版本的 nginx https://github.com/houbb/nginx4j 如果你想知道 servlet 如何處理的,可以參考我的另一個項目: 手寫從零實現簡易版 tomcat minicat 手寫 ngin ...
  • 上一次的介紹,主要圍繞如何統一去捕獲異常,以及為每一種異常添加自己的Mapper實現,並且我們知道,當在ExceptionMapper中返回非200的Response,不支持application/json的響應類型,而是寫死的text/plain類型。 Filter為二方包異常手動捕獲 參考:ht ...
  • 大家好,我是R哥。 今天分享一個爽飛了的面試輔導 case: 這個杭州兄弟空窗期 1 個月+,面試了 6 家公司 0 Offer,不知道問題出在哪,難道是杭州的 IT 崩盤了麽? 報名面試輔導後,經過一個多月的輔導打磨,現在成功入職某上市公司,漲薪 30%+,955 工作制,不咋加班,還不捲。 其他 ...
  • 引入依賴 <!--Freemarker wls--> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.30</version> </dependency> ...
  • 你應如何運行程式 互動式命令模式 開始一個互動式會話 一般是在操作系統命令行下輸入python,且不帶任何參數 系統路徑 如果沒有設置系統的PATH環境變數來包括Python的安裝路徑,可能需要機器上Python可執行文件的完整路徑來代替python 運行的位置:代碼位置 不要輸入的內容:提示符和註 ...