欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于@SpringBootApplication與@SpringBootTest的區(qū)別及用法

 更新時(shí)間:2022年01月19日 08:48:03   作者:開(kāi)心小蝸牛  
這篇文章主要介紹了關(guān)于@SpringBootApplication與@SpringBootTest的區(qū)別及用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

@SpringBootApplication與@SpringBootTest區(qū)別用法

1 @SpringBootApplication 注解的應(yīng)用

一般情況我們使用 @SpringBootApplication 注解來(lái)啟動(dòng) SpringBoot 項(xiàng)目

它其實(shí)只相當(dāng)于 @Configuration、@EnableAutoConfiguration、@ComponentScan(包含了兩個(gè)filter)

@SpringBootApplication
public class FrameworkUnitRealTestApp {
? ? public static void main(String[] args) {
? ? ? ? SpringApplication.run(FrameworkUnitRealTestApp.class, args);
? ? }
}

2 @SpringBootTest 注解的應(yīng)用

一般情況我們使用 @SpringBootTest 和 @RunWith(SpringRunner.class) 注解來(lái)啟動(dòng) SpringBoot 測(cè)試項(xiàng)目

@RunWith(SpringRunner.class)?
@SpringBootTest
public class FrameworkUnitRealTestApp {
? ? @Test
? ? public void test() {}
}

3 @SpringBootApplication 和 @SpringBootTest 的區(qū)別

這兩個(gè)注解的區(qū)別的核心在于兩個(gè)注解:@EnableAutoConfiguration、@ComponentScan(包含了兩個(gè)filter)

@EnableAutoConfiguration 啟動(dòng)了所有的自動(dòng)配置類(lèi)

@ComponentScan(包含了兩個(gè)filter):在掃描階段過(guò)濾掉 @TestComponent 等專(zhuān)屬于測(cè)試的類(lèi)和過(guò)濾掉被 @Configuration 注解的自動(dòng)配置類(lèi)(使得自動(dòng)配置類(lèi)不會(huì)在掃描階段就被注冊(cè) beanDefinition,因?yàn)?自動(dòng)配置類(lèi)的優(yōu)先級(jí)應(yīng)該是最低的)

可以看出 @SpringBootTest 并沒(méi)有啟用任何自動(dòng)配置類(lèi),所以就不需要加 AutoConfigurationExcludeFilter 了

springboot 通過(guò)引入 @Test** 注解來(lái)在 測(cè)試環(huán)境下 引入不同的自動(dòng)配置類(lèi)!

4 @ComponentScan(包含了兩個(gè)filter) 解析

詳細(xì)的代碼如下:添加了 TypeExcludeFilter 和 AutoConfigurationExcludeFilter 兩個(gè) excludeFilter

作用:掃描包的時(shí)候過(guò)濾掉被這兩個(gè) Filter 匹配的類(lèi)!

@ComponentScan(excludeFilters = {
?? ??? ?@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
?? ??? ?@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })

4.1 TypeExcludeFilter 解析

主要移除測(cè)試相關(guān)的類(lèi)

public class TypeExcludeFilter implements TypeFilter, BeanFactoryAware {
? ?@Override
? ?public boolean match(MetadataReader metadataReader,
? ? ? ? ?MetadataReaderFactory metadataReaderFactory) throws IOException {
? ? ? if (this.beanFactory instanceof ListableBeanFactory
? ? ? ? ? ? && getClass() == TypeExcludeFilter.class) {
? ? ? ? ?Collection<TypeExcludeFilter> delegates = ((ListableBeanFactory) this.beanFactory)
? ? ? ? ? ? ? ?.getBeansOfType(TypeExcludeFilter.class).values();
? ? ? ? ?for (TypeExcludeFilter delegate : delegates) {
? ? ? ? ? ? if (delegate.match(metadataReader, metadataReaderFactory)) {
? ? ? ? ? ? ? ?return true;
? ? ? ? ? ? }
? ? ? ? ?}
? ? ? }
? ? ? return false;
? ?}
}
//delegate.match 走這個(gè)類(lèi)的 match 方法
class TestTypeExcludeFilter extends TypeExcludeFilter {
?? ?private static final String[] CLASS_ANNOTATIONS = { "org.junit.runner.RunWith",
?? ??? ??? ?"org.junit.jupiter.api.extension.ExtendWith" };
?? ?private static final String[] METHOD_ANNOTATIONS = { "org.junit.Test",
?? ??? ??? ?"org.junit.platform.commons.annotation.Testable" };

?? ?@Override
?? ?public boolean match(MetadataReader metadataReader,
?? ??? ??? ?MetadataReaderFactory metadataReaderFactory) throws IOException {
? ? ? ? //是否被 @TestComponent 及其父注解注釋
?? ??? ?if (isTestConfiguration(metadataReader)) {return true;}
? ? ? ? //類(lèi)上或類(lèi)中方法上有沒(méi)有 CLASS_ANNOTATIONS、METHOD_ANNOTATIONS 中的注解
?? ??? ?if (isTestClass(metadataReader)) {return true;}
?? ??? ?String enclosing = metadataReader.getClassMetadata().getEnclosingClassName();
?? ??? ?if (enclosing != null) {
? ? ? ? ? ? //遞歸內(nèi)部類(lèi)、父類(lèi)
? ? ? ? ? ? if (match(metadataReaderFactory.getMetadataReader(enclosing),
? ? ? ? ? ? ? ? ? ? ? metadataReaderFactory)) {
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
?? ??? ?}
?? ??? ?return false;
?? ?}
}

4.2 AutoConfigurationExcludeFilter 解析

主要移除被 @Configuration 修飾的 自動(dòng)配置類(lèi)

public class AutoConfigurationExcludeFilter implements TypeFilter, BeanClassLoaderAware {
?? ?@Override
?? ?public boolean match(MetadataReader metadataReader,
?? ??? ??? ?MetadataReaderFactory metadataReaderFactory) throws IOException {
? ? ? ? //如果被 @Configuration 注解,并且是 自動(dòng)配置類(lèi)就返回 true,即匹配成功?
? ? ? ? //注:被 @Component 等注解并不匹配
?? ??? ?return isConfiguration(metadataReader) && isAutoConfiguration(metadataReader);
?? ?}
}

5 @EnableAutoConfiguration 注解解析

作用:?jiǎn)⒂米詣?dòng)配置類(lèi)

@AutoConfigurationPackage
//啟用 AutoConfigurationImportSelector 配置類(lèi):掃描得到所有自動(dòng)配置類(lèi)
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
? ?String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
? ?//定義不啟用的 自動(dòng)配置類(lèi)
? ?Class<?>[] exclude() default {};
? ?//同上
? ?String[] excludeName() default {};
}
//這個(gè)注解主要是向容器中注冊(cè) AutoConfigurationPackages.Registrar 類(lèi)用來(lái)存儲(chǔ)自動(dòng)配置包
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {}
//關(guān)鍵:這個(gè)類(lèi)繼承了 DeferredImportSelector 接口,所以是到最后才解析的??!
public class AutoConfigurationImportSelector implements DeferredImportSelector{
? ? @Override
? ? public String[] selectImports(AnnotationMetadata annotationMetadata) {
? ? ? ? if (!isEnabled(annotationMetadata)) {
? ? ? ? ? ? return NO_IMPORTS;
? ? ? ? }
? ? ? ? AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
? ? ? ? ? ? .loadMetadata(this.beanClassLoader);
? ? ? ? AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
? ? ? ? ? ? autoConfigurationMetadata, annotationMetadata);
? ? ? ? return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
? ? }
}

6 @…Test 注解

Spring Boot 中文文檔 對(duì)每個(gè) @…Test 注解導(dǎo)入的自動(dòng)配置類(lèi)做了詳細(xì)的說(shuō)明

SpringBootTest對(duì)比SpringBootApplication

SpringBootTest 是測(cè)試使用類(lèi)的注解,標(biāo)志這個(gè)類(lèi)是測(cè)試用例。

具體看下源碼分析

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@BootstrapWith(SpringBootTestContextBootstrapper.class)
@ExtendWith({SpringExtension.class})
public @interface SpringBootTest {
@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 {

對(duì)比顯示都是復(fù)合注解,并且前四個(gè)注解是一樣的,后面區(qū)分BootstrapWith和ExtendWith這兩個(gè)是測(cè)試中包含的

BootstrapWith這個(gè)注解中有一個(gè)參數(shù)為SpringBootTestContextBootstrapper

具體可以看下里面是什么

在這里插入圖片描述

這里面申明了一些程序運(yùn)行所在包的路徑,在去查看繼承的頂級(jí)類(lèi)可以追溯到TestContextBootstrapper 這個(gè)接口 :

在這里插入圖片描述

從里面的方法可以看到是在運(yùn)行的時(shí)候設(shè)置上下文 以及如何獲取上下文,來(lái)提供測(cè)試啟動(dòng)的必須值。

接下來(lái)看下 ExtendWith 這個(gè)注解類(lèi)

在這里插入圖片描述

這個(gè)主要看里面的SpringExtension這個(gè)參數(shù)

在這里插入圖片描述

可以看出這個(gè)實(shí)現(xiàn)了很多接口,來(lái)處理測(cè)試需要的各種通知處理,以及在測(cè)試接口時(shí)可以提前處理請(qǐng)求參數(shù)。

SpringBootApplication中的復(fù)合注解則是掃描一些包和配置。雖然測(cè)試也是項(xiàng)目啟動(dòng)的一種,可以看到里面實(shí)現(xiàn)還是有些區(qū)別的。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 淺談一下Java中枚舉的用法

    淺談一下Java中枚舉的用法

    這篇文章主要介紹了淺談一下Java中枚舉的用法,枚舉是一個(gè)被命名的整型常數(shù)的集合,用于聲明一組帶標(biāo)識(shí)符的常數(shù),當(dāng)一個(gè)變量有幾種固定可能的取值時(shí),就可以將它定義為枚舉類(lèi)型,需要的朋友可以參考下
    2023-04-04
  • MyBatis-plus+達(dá)夢(mèng)數(shù)據(jù)庫(kù)實(shí)現(xiàn)自動(dòng)生成代碼的示例

    MyBatis-plus+達(dá)夢(mèng)數(shù)據(jù)庫(kù)實(shí)現(xiàn)自動(dòng)生成代碼的示例

    這篇文章主要介紹了MyBatis-plus+達(dá)夢(mèng)數(shù)據(jù)庫(kù)實(shí)現(xiàn)自動(dòng)生成代碼的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • JAVA基于數(shù)組實(shí)現(xiàn)的商品信息查詢(xún)功能示例

    JAVA基于數(shù)組實(shí)現(xiàn)的商品信息查詢(xún)功能示例

    這篇文章主要介紹了JAVA基于數(shù)組實(shí)現(xiàn)的商品信息查詢(xún)功能,結(jié)合實(shí)例形式詳細(xì)分析了java使用數(shù)組存儲(chǔ)數(shù)據(jù)實(shí)現(xiàn)的商品信息查詢(xún)功能相關(guān)操作技巧,需要的朋友可以參考下
    2019-11-11
  • IntelliJ IDEA遠(yuǎn)程Debug Linux的Java程序,找問(wèn)題不要只會(huì)看日志了(推薦)

    IntelliJ IDEA遠(yuǎn)程Debug Linux的Java程序,找問(wèn)題不要只會(huì)看日志了(推薦)

    這篇文章主要介紹了IntelliJ IDEA遠(yuǎn)程Debug Linux的Java程序,找問(wèn)題不要只會(huì)看日志了,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • spring boot 添加admin監(jiān)控的方法

    spring boot 添加admin監(jiān)控的方法

    這篇文章主要介紹了spring boot 添加admin監(jiān)控的相關(guān)知識(shí),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • MDC在多線(xiàn)程中的使用方式

    MDC在多線(xiàn)程中的使用方式

    這篇文章主要介紹了MDC在多線(xiàn)程中的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • springboot使用hibernate validation對(duì)參數(shù)校驗(yàn)的實(shí)現(xiàn)方法

    springboot使用hibernate validation對(duì)參數(shù)校驗(yàn)的實(shí)現(xiàn)方法

    這篇文章主要介紹了spring-boot 使用hibernate validation對(duì)參數(shù)進(jìn)行優(yōu)雅的校驗(yàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Java多線(xiàn)程程序中synchronized修飾方法的使用實(shí)例

    Java多線(xiàn)程程序中synchronized修飾方法的使用實(shí)例

    synchronized關(guān)鍵字主要北用來(lái)進(jìn)行線(xiàn)程同步,這里我們主要來(lái)演示Java多線(xiàn)程程序中synchronized修飾方法的使用實(shí)例,需要的朋友可以參考下:
    2016-06-06
  • Mybatis的Mapper中的方法為什么不能重載

    Mybatis的Mapper中的方法為什么不能重載

    這篇文章主要介紹了Mybatis的Mapper中的方法為什么不能重載,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • 新手了解java 異常處理基礎(chǔ)知識(shí)

    新手了解java 異常處理基礎(chǔ)知識(shí)

    Java中異常提供了一種識(shí)別及響應(yīng)錯(cuò)誤情況的一致性機(jī)制,有效地異常處理能使程序更加健壯、易于調(diào)試。那么這篇文章總結(jié)了Java有效處理異常的三個(gè)原則,有需要的朋友們可以參考借鑒
    2021-07-07

最新評(píng)論