SpringBoot的高級特性

目錄

pringBoot 應用啓動入口

SpringBoot 自動配置原理

SpringBoot 配置文件

SpringBoot Actuator監控


pringBoot 應用啓動入口

在SpringBoot的入口類中,我們通常是通過調用SpringApplication的run方法(一個靜態方法),另外再加上@SpringBootApplication註解來啓動SpringBoot項目
通過調用SpringApplication的方法,調整應用的行爲
SpringApplicationBuilder提供了Fluent API,可以實現鏈式調用。我們可以用它來實現剛剛定義的功能,可以發現代碼層面在編寫上較爲方便
示例代碼

@SpringBootApplication
public class SpringBootStudyApplication {

    public static void main(String[] args) {

        // 1. 通過靜態 run 方法
        SpringApplication.run(SpringBootStudyApplication.class, args);

        // 2. 通過 api 調整應用行爲
        SpringApplication application =
                new SpringApplication(SpringBootStudyApplication.class);
        application.setBannerMode(Banner.Mode.OFF);
        application.setWebApplicationType(WebApplicationType.NONE);
        application.run(args);

        // 3. SpringApplicationBuilder Fluent Api, 鏈式調用
        new SpringApplicationBuilder(SpringBootStudyApplication.class)
                .bannerMode(Banner.Mode.OFF)
//                .web(WebApplicationType.NONE)
                .run(args);
    }
}

SpringBoot 自動配置原理

簡單的說,自動配置就是會根據在類路徑中的jar、類自動配置Bean。Spring Boot將所有的功能場景都抽取出來,做成一個個的starter(啓動器),只需要在項目裏面引入這些starter,相關場景的所有依賴都會導入進來。

自動配置就是基於三個重要的註解實現的(實際就是 @SpringBootApplication 註解)
// @SpringBootConfiguration:我們點進去以後可以發現底層是Configuration註解,其實就是支持JavaConfig的方式來進行配置(使用Configuration配置類等同於XML文件)
// @EnableAutoConfiguration:這個註解用來開啓自動配置,是自動配置實現的核心註解
// @ComponentScan:這個註解,學過Spring的同學應該對它不會陌生,就是掃描註解,默認是掃描當前類下的package。將@Controller/@Service/@Component/@Repository等註解加載到IOC容器中
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {
}
@EnableAutoConfiguration源碼
// @AutoConfigurationPackage:自動配置包
// @Import:給IOC容器導入組件
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}
@AutoConfigurationPackage 源碼
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage

public void registerBeanDefinitions(AnnotationMetadata metadata,
                BeanDefinitionRegistry registry) {
  register(registry, new PackageImport(metadata).getPackageName())
        }
// 很容易可以看到,它的作用就是將主配置類(@SpringBootApplication)的所在包及其子包裏邊的組件掃描到Spring容器中
@Import(AutoConfigurationImportSelector.class) 源碼
public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
                .loadMetadata(this.beanClassLoader);
        AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
                autoConfigurationMetadata, annotationMetadata);

// 可以得到了很多配置信息
protected AutoConfigurationEntry getAutoConfigurationEntry(...) {
    AnnotationAttributes attributes = getAttributes(annotationMetadata);
    List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);

// 配置信息從這裏來
protected List<String> getCandidateConfigurations(...) {
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(...);

// 配置加載的位置
public static List<String> loadFactoryNames(...) {
    String factoryClassName = factoryClass.getName();
    return loadSpringFactories(classLoader)...;
}

private static Map<String, List<String>> loadSpringFactories(...) {
    Enumeration<URL> urls = (classLoader != null ?
        classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
        Properties properties = PropertiesLoaderUtils.loadProperties(resource);
        for (Map.Entry<?, ?> entry : properties.entrySet()) {
            result.add(factoryClassName, factoryName.trim());

// 這個方法也就是自動配置的核心實現了,主要是三點內容:
// FACTORIES_RESOURCE_LOCATION的值是META-INF/spring.factories
// Spring啓動的時候會掃描所有jar路徑下的META-INF/spring.factories,將其文件包裝成Properties對象
// 從Properties對象獲取到key值爲EnableAutoConfiguration的數據,然後添加到容器裏邊


SpringBoot 配置文件

1、同一個目錄下的 application 和 bootstrap

  • bootstrap 優先級高於 application,優先被加載

  • bootstrap 用於應用程序上下文的引導階段,由父 ApplicationContext 加載

  • bootstrap 是系統級別的配置(不變的參數),application 是應用級別的配置

2、不同位置的配置文件加載順序(優先級)

  • file:./config/ - 優先級最高(項目根路徑下的 config)

  • file:./ - 優先級第二(項目根路徑下)

  • classpath:/config/ - 優先級第三(項目 resources/config 下)

  • classpath:/ - 優先級第四(項目 resources 目錄下)

  • 高優先級覆蓋低優先級相同配置、多個配置文件互補

SpringBoot Actuator監控

微服務的特點決定了功能模塊的部署是分佈式的,大部分功能模塊都是運行在不同的機器上,彼此通過服務調用進行交互,前後臺的業務流會經過很多個微服務的處理和傳遞,出現了異常如何快速定位是哪個環節出現了問題?
在這種框架下,微服務的監控顯得尤爲重要。SpringBoot給我們提供了一個用於監控的組件:Actuator,它也是一個starter,方便在日常的開發、運行中對我們的微服務進行監控治理。

  • Actuator監控分類
  • 應用配置類:可以查看應用在運行期的靜態信息:例如自動配置信息、加載的 springbean 信息、yml 文件配置信息、環境信息、請求映射信息

  • 度量指標類:主要是運行期的動態信息,例如堆棧、請求連、一些健康指標、metrics 信息等

  • 操作控制類:主要是指 shutdown,用戶可以發送一個請求將應用的監控功能關閉

配置注入的方式

  • 直接使用 @Value

  • 使用 @ConfigurationProperties + prefix 的方式

Jackson 的使用技巧 

通常在項目中處理JSON一般用的都是阿里巴巴的fastjson, 後來發現使用Spring Boot內置的Jackson來完成JSON的序列化和反序列化操作也是非常方便的。

  • @JsonProperty,作用在屬性上,用來爲JSON Key指定一個別名
  • @Jsonlgnore,作用在屬性上,用來忽略此屬性
  • @JsonIgnoreProperties,忽略一組屬性,作用於類上
  • @JsonFormat,用於日期格式化
  • Jackson通過使用ObjectMapper的writeValueAsString方法將Java對象序列化爲JSON格式字符串
  • 反序列化使用 ObjectMapper 的 readValue

定時任務

  • @EnableScheduling:允許當前的應用開啓定時任務

  • @Scheduled:指定定時任務的運行規則

異步任務

通常代碼都是順序執行(一行一行的執行),這也就是同步調用。但是異步編程卻沒有這樣的限制,代碼執行並不是阻塞的。可以直接調用不用等待返回,而是在某一個想要獲取結果的時間點再去獲取結果。

  • 引入spring-boot-starter-web依賴

  • 在SpringBoot入口類上加上 @EnableAsync 註解,開啓異步支持
  • 只需要在方法上加上 @Async 註解,則當前方法就是異步方法

默認情況下的異步線程池配置使得線程不能被重用,每次調用異步方法都會新建一個線程,我們可以自己定義異步線程池來優化。

單元測試

編寫單元測試可以幫助開發人員編寫高質量的代碼,提升代碼質量,減少Bug,便於重構。SpringBoot提供了一些實用程序和註解,用來幫助我們測試應用程序,在SpringBoot中開啓單元測試只需引入spring-boot-starter-test即可,其包含了一些主流的測試庫。

一個標準的SpringBoot測試用例應該包含兩個註解:

  • @SpringBootTest:意思是帶有 SpringBoot 支持的引導程序,其中提供了可以指定 Web 環境的參數

  • @RunWith(SpringRunner.class):告訴JUnit運行使用Spring的測試支持。SpringRunner是SpringJUnit4ClassRunner的新名字,這個名字只是讓名字看起來簡單些 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章