@SpringBootApplication与@SpringBootTest的区别有哪些(@SpringBootApplication,开发技术)

时间:2024-05-10 08:31:51 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

@SpringBootApplication与@SpringBootTest区别用法

1 @SpringBootApplication 注解的应用

一般情况我们使用 @SpringBootApplication 注解来启动 SpringBoot 项目

它其实只相当于 @Configuration、@EnableAutoConfiguration、@ComponentScan(包含了两个filter)

@SpringBootApplicationpublicclassFrameworkUnitRealTestApp{publicstaticvoidmain(String[]args){SpringApplication.run(FrameworkUnitRealTestApp.class,args);}}

2 @SpringBootTest 注解的应用

一般情况我们使用 @SpringBootTest 和 @RunWith(SpringRunner.class) 注解来启动 SpringBoot 测试项目

@RunWith(SpringRunner.class)@SpringBootTestpublicclassFrameworkUnitRealTestApp{@Testpublicvoidtest(){}}

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 解析

主要移除测试相关的类

publicclassTypeExcludeFilterimplementsTypeFilter,BeanFactoryAware{@Overridepublicbooleanmatch(MetadataReadermetadataReader,MetadataReaderFactorymetadataReaderFactory)throwsIOException{if(this.beanFactoryinstanceofListableBeanFactory&&getClass()==TypeExcludeFilter.class){Collection<TypeExcludeFilter>delegates=((ListableBeanFactory)this.beanFactory).getBeansOfType(TypeExcludeFilter.class).values();for(TypeExcludeFilterdelegate:delegates){if(delegate.match(metadataReader,metadataReaderFactory)){returntrue;}}}returnfalse;}}//delegate.match走这个类的match方法classTestTypeExcludeFilterextendsTypeExcludeFilter{privatestaticfinalString[]CLASS_ANNOTATIONS={"org.junit.runner.RunWith","org.junit.jupiter.api.extension.ExtendWith"};privatestaticfinalString[]METHOD_ANNOTATIONS={"org.junit.Test","org.junit.platform.commons.annotation.Testable"};@Overridepublicbooleanmatch(MetadataReadermetadataReader,MetadataReaderFactorymetadataReaderFactory)throwsIOException{//是否被@TestComponent及其父注解注释if(isTestConfiguration(metadataReader)){returntrue;}//类上或类中方法上有没有CLASS_ANNOTATIONS、METHOD_ANNOTATIONS中的注解if(isTestClass(metadataReader)){returntrue;}Stringenclosing=metadataReader.getClassMetadata().getEnclosingClassName();if(enclosing!=null){//递归内部类、父类if(match(metadataReaderFactory.getMetadataReader(enclosing),metadataReaderFactory)){returntrue;}}returnfalse;}}

4.2 AutoConfigurationExcludeFilter 解析

主要移除被 @Configuration 修饰的 自动配置类

publicclassAutoConfigurationExcludeFilterimplementsTypeFilter,BeanClassLoaderAware{@Overridepublicbooleanmatch(MetadataReadermetadataReader,MetadataReaderFactorymetadataReaderFactory)throwsIOException{//如果被@Configuration注解,并且是自动配置类就返回true,即匹配成功//注:被@Component等注解并不匹配returnisConfiguration(metadataReader)&&isAutoConfiguration(metadataReader);}}

5 @EnableAutoConfiguration 注解解析

作用:启用自动配置类

@AutoConfigurationPackage//启用AutoConfigurationImportSelector配置类:扫描得到所有自动配置类@Import(AutoConfigurationImportSelector.class)public@interfaceEnableAutoConfiguration{StringENABLED_OVERRIDE_PROPERTY="spring.boot.enableautoconfiguration";//定义不启用的自动配置类Class<?>[]exclude()default{};//同上String[]excludeName()default{};}//这个注解主要是向容器中注册AutoConfigurationPackages.Registrar类用来存储自动配置包@Import(AutoConfigurationPackages.Registrar.class)public@interfaceAutoConfigurationPackage{}//关键:这个类继承了DeferredImportSelector接口,所以是到最后才解析的!!publicclassAutoConfigurationImportSelectorimplementsDeferredImportSelector{@OverridepublicString[]selectImports(AnnotationMetadataannotationMetadata){if(!isEnabled(annotationMetadata)){returnNO_IMPORTS;}AutoConfigurationMetadataautoConfigurationMetadata=AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);AutoConfigurationEntryautoConfigurationEntry=getAutoConfigurationEntry(autoConfigurationMetadata,annotationMetadata);returnStringUtils.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@interfaceSpringBootTest{
@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@interfaceSpringBootApplication{

对比显示都是复合注解,并且前四个注解是一样的,后面区分BootstrapWith和ExtendWith这两个是测试中包含的

BootstrapWith这个注解中有一个参数为SpringBootTestContextBootstrapper

具体可以看下里面是什么

@SpringBootApplication与@SpringBootTest的区别有哪些

这里面申明了一些程序运行所在包的路径,在去查看继承的顶级类可以追溯到TestContextBootstrapper 这个接口 :

@SpringBootApplication与@SpringBootTest的区别有哪些

从里面的方法可以看到是在运行的时候设置上下文 以及如何获取上下文,来提供测试启动的必须值。

接下来看下 ExtendWith 这个注解类

@SpringBootApplication与@SpringBootTest的区别有哪些

这个主要看里面的SpringExtension这个参数

@SpringBootApplication与@SpringBootTest的区别有哪些

可以看出这个实现了很多接口,来处理测试需要的各种通知处理,以及在测试接口时可以提前处理请求参数。

SpringBootApplication中的复合注解则是扫描一些包和配置。虽然测试也是项目启动的一种,可以看到里面实现还是有些区别的。

 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:@SpringBootApplication与@SpringBootTest的区别有哪些的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:Linux中Go环境配置和GoModule常用操作是什么下一篇:

12 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18