@SpringBootApplication与@SpringBootTest的区别有哪些
导读:本文共4201字符,通常情况下阅读需要14分钟。同时您也可以点击右侧朗读,来听本文内容。按键盘←(左) →(右) 方向键可以翻页。
摘要: @SpringBootApplication与@SpringBootTest区别用法1 @SpringBootApplication 注解的应用一般情况我们使用 @SpringBootApplication 注解来启动 SpringBoot 项目它其实只相当于 @Configuration、@EnableAutoConfiguration、@ComponentS... ...
目录
(为您整理了一些要点),点击可以直达。@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 @…Test 注解
Spring Boot 中文文档 对每个 @…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
具体可以看下里面是什么
这里面申明了一些程序运行所在包的路径,在去查看继承的顶级类可以追溯到TestContextBootstrapper 这个接口 :
从里面的方法可以看到是在运行的时候设置上下文 以及如何获取上下文,来提供测试启动的必须值。
接下来看下 ExtendWith 这个注解类
这个主要看里面的SpringExtension这个参数
可以看出这个实现了很多接口,来处理测试需要的各种通知处理,以及在测试接口时可以提前处理请求参数。
SpringBootApplication中的复合注解则是扫描一些包和配置。虽然测试也是项目启动的一种,可以看到里面实现还是有些区别的。
</div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
@SpringBootApplication与@SpringBootTest的区别有哪些的详细内容,希望对您有所帮助,信息来源于网络。