Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the difference between @ SpringBootApplication and @ SpringBootTest

2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

The editor will share with you the differences between @ SpringBootApplication and @ SpringBootTest. I hope you will get something after reading this article. Let's discuss it together.

The differential usage of @ SpringBootApplication and @ SpringBootTest the application of 1 @ SpringBootApplication annotation

In general, we use the @ SpringBootApplication annotation to start the SpringBoot project

It is only equivalent to @ Configuration, @ EnableAutoConfiguration, @ ComponentScan (including two filter)

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

Normally we use @ SpringBootTest and @ RunWith (SpringRunner.class) annotations to start the SpringBoot test project

@ RunWith (SpringRunner.class) @ SpringBootTestpublic class FrameworkUnitRealTestApp {@ Testpublic void test () {}} 3 @ SpringBootApplication and @ SpringBootTest

The core of the difference between the two annotations lies in two annotations: @ EnableAutoConfiguration, @ ComponentScan (which contains two filter)

@ EnableAutoConfiguration starts all automatic configuration classes

@ ComponentScan (contains two filter): filter out @ TestComponent and other test-specific classes during the scan phase and filter out the autoconfiguration classes annotated by @ Configuration (so that the autoconfiguration class will not be registered with beanDefinition during the scan phase, because the autoconfiguration class should have the lowest priority)

You can see that @ SpringBootTest does not have any autoconfiguration classes enabled, so there is no need to add AutoConfigurationExcludeFilter

Springboot introduces different autoconfiguration classes in the test environment by introducing the @ Test** annotation!

4 @ ComponentScan (including two filter) parsing

The detailed code is as follows: TypeExcludeFilter and AutoConfigurationExcludeFilter excludeFilter have been added

Function: filter out the classes that are matched by the two Filter when scanning the package!

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

4.1 TypeExcludeFilter parsing

Mainly remove test-related classes

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 delegates = ((ListableBeanFactory) this.beanFactory) .getBeansOfType (TypeExcludeFilter.class). Values () For (TypeExcludeFilter delegate: delegates) {if (delegate.match (metadataReader, metadataReaderFactory)) {return true;} return false }} / / delegate.match take the match method of this class 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 {/ / whether @ TestComponent and its parent annotation if (isTestConfiguration (metadataReader)) {return true;} / / are there any annotations in CLASS_ANNOTATIONS or METHOD_ANNOTATIONS (isTestClass (metadataReader)) {return true;} String enclosing = metadataReader.getClassMetadata (). GetEnclosingClassName () If (enclosing! = null) {/ / Recursive inner class, parent class if (match (metadataReaderFactory.getMetadataReader (enclosing), metadataReaderFactory)) {return true;}} return false;}}

4.2 AutoConfigurationExcludeFilter parsing

Mainly remove autoconfiguration classes modified by @ Configuration

Public class AutoConfigurationExcludeFilter implements TypeFilter, BeanClassLoaderAware {@ Override public boolean match (MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {/ / return true if it is annotated by @ Configuration and the autoconfiguration class is automatically configured, that is, the match is successful / / Note: annotations such as @ Component do not match return isConfiguration (metadataReader) & & isAutoConfiguration (metadataReader);}} 5 @ EnableAutoConfiguration annotation resolution

Purpose: enable automatic configuration classes

@ AutoConfigurationPackage// enable AutoConfigurationImportSelector configuration class: scan all auto configuration classes @ Import (AutoConfigurationImportSelector.class) public @ interface EnableAutoConfiguration {String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; / / define Class [] exclude () default {}; / / ditto String [] excludeName () default {} } / / this annotation is mainly used to register the AutoConfigurationPackages.Registrar class with the container to store the automatic configuration package @ Import (AutoConfigurationPackages.Registrar.class) public @ interface AutoConfigurationPackage {} / / key: this class inherits the DeferredImportSelector interface, so it is not parsed until the end! Public class AutoConfigurationImportSelector implements DeferredImportSelector {@ Override public String [] selectImports (AnnotationMetadata annotationMetadata) {if (! isEnabled (annotationMetadata)) {return NO_IMPORTS;} AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader .loadMetavian (this.beanClassLoader); AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry (autoConfigurationMetadata, annotationMetadata); return StringUtils.toStringArray (autoConfigurationEntry.getConfigurations ());}} 6 @ … Test comments

Spring Boot Chinese documents for each @ … The automatic configuration class imported by Test comments is described in detail.

SpringBootTest vs. SpringBootApplication

SpringBootTest is an annotation of the test usage class, indicating that the class is a test case.

Specifically, take a look at the source code analysis @ 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 {

The comparison shows that they are all composite annotations, and the first four annotations are the same, and the distinction between BootstrapWith and ExtendWith is included in the test.

One parameter in the BootstrapWith annotation is SpringBootTestContextBootstrapper

You can take a look at what's in it.

This states the path of the package in which some programs are running, and the top-level classes that are inherited can be traced back to the TestContextBootstrapper interface:

From the methods inside, you can see that the context is set at run time and how to get the context to provide the necessary values for test startup.

Next, take a look at the annotated class ExtendWith.

This mainly depends on the parameter SpringExtension in it.

You can see that this implements a number of interfaces to handle the various notification processing required for testing, and to handle request parameters in advance when testing the interface.

The composite annotations in SpringBootApplication scan some packages and configurations. Although testing is also a kind of project startup, you can see that there are some differences in the implementation.

After reading this article, I believe you have a certain understanding of "what is the difference between @ SpringBootApplication and @ SpringBootTest". If you want to know more about it, you are welcome to follow the industry information channel. Thank you for reading!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report