91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

@SpringBootApplication與@SpringBootTest的區別有哪些

發布時間:2022-01-19 10:29:44 來源:億速云 閱讀:235 作者:小新 欄目:開發技術

小編給大家分享一下@SpringBootApplication與@SpringBootTest的區別有哪些,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

@SpringBootApplication與@SpringBootTest區別用法

1 @SpringBootApplication 注解的應用

一般情況我們使用 @SpringBootApplication 注解來啟動 SpringBoot 項目

它其實只相當于 @Configuration、@EnableAutoConfiguration、@ComponentScan(包含了兩個filter)

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

2 @SpringBootTest 注解的應用

一般情況我們使用 @SpringBootTest 和 @RunWith(SpringRunner.class) 注解來啟動 SpringBoot 測試項目

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

3 @SpringBootApplication 和 @SpringBootTest 的區別

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

@EnableAutoConfiguration 啟動了所有的自動配置類

@ComponentScan(包含了兩個filter):在掃描階段過濾掉 @TestComponent 等專屬于測試的類和過濾掉被 @Configuration 注解的自動配置類(使得自動配置類不會在掃描階段就被注冊 beanDefinition,因為 自動配置類的優先級應該是最低的)

可以看出 @SpringBootTest 并沒有啟用任何自動配置類,所以就不需要加 AutoConfigurationExcludeFilter 了

springboot 通過引入 @Test** 注解來在 測試環境下 引入不同的自動配置類!

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

詳細的代碼如下:添加了 TypeExcludeFilter 和 AutoConfigurationExcludeFilter 兩個 excludeFilter

作用:掃描包的時候過濾掉被這兩個 Filter 匹配的類!

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

4.1 TypeExcludeFilter 解析

主要移除測試相關的類

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 走這個類的 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;}
        //類上或類中方法上有沒有 CLASS_ANNOTATIONS、METHOD_ANNOTATIONS 中的注解
        if (isTestClass(metadataReader)) {return true;}
        String enclosing = metadataReader.getClassMetadata().getEnclosingClassName();
        if (enclosing != null) {
            //遞歸內部類、父類
            if (match(metadataReaderFactory.getMetadataReader(enclosing),
                      metadataReaderFactory)) {
                return true;
            }
        }
        return false;
    }
}

4.2 AutoConfigurationExcludeFilter 解析

主要移除被 @Configuration 修飾的 自動配置類

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

5 @EnableAutoConfiguration 注解解析

作用:啟用自動配置類

@AutoConfigurationPackage
//啟用 AutoConfigurationImportSelector 配置類:掃描得到所有自動配置類
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
   String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
   //定義不啟用的 自動配置類
   Class<?>[] exclude() default {};
   //同上
   String[] excludeName() default {};
}
//這個注解主要是向容器中注冊 AutoConfigurationPackages.Registrar 類用來存儲自動配置包
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {}
//關鍵:這個類繼承了 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 @&hellip;Test 注解

Spring Boot 中文文檔 對每個 @&hellip;Test 注解導入的自動配置類做了詳細的說明

SpringBootTest對比SpringBootApplication

SpringBootTest 是測試使用類的注解,標志這個類是測試用例。

具體看下源碼分析

@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 {

對比顯示都是復合注解,并且前四個注解是一樣的,后面區分BootstrapWith和ExtendWith這兩個是測試中包含的

BootstrapWith這個注解中有一個參數為SpringBootTestContextBootstrapper

具體可以看下里面是什么

@SpringBootApplication與@SpringBootTest的區別有哪些

這里面申明了一些程序運行所在包的路徑,在去查看繼承的頂級類可以追溯到TestContextBootstrapper 這個接口 :

@SpringBootApplication與@SpringBootTest的區別有哪些

從里面的方法可以看到是在運行的時候設置上下文 以及如何獲取上下文,來提供測試啟動的必須值。

接下來看下 ExtendWith 這個注解類

@SpringBootApplication與@SpringBootTest的區別有哪些

這個主要看里面的SpringExtension這個參數

@SpringBootApplication與@SpringBootTest的區別有哪些

可以看出這個實現了很多接口,來處理測試需要的各種通知處理,以及在測試接口時可以提前處理請求參數。

SpringBootApplication中的復合注解則是掃描一些包和配置。雖然測試也是項目啟動的一種,可以看到里面實現還是有些區別的。

看完了這篇文章,相信你對“@SpringBootApplication與@SpringBootTest的區別有哪些”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

福安市| 永春县| 江西省| 都匀市| 湾仔区| 平顶山市| 芷江| 南丹县| 武山县| 焉耆| 土默特左旗| 承德市| 萍乡市| 安义县| 兰溪市| 仪陇县| 樟树市| 呼玛县| 丹东市| 宝坻区| 花莲县| 安龙县| 青州市| 永吉县| 承德县| 靖宇县| 民勤县| 鄂托克前旗| 黑河市| 桐梓县| 平凉市| 清河县| 桐乡市| 古蔺县| 宁强县| 资讯| 嘉义市| 山丹县| 仁布县| 临潭县| 巧家县|