[SpringBoot] The principle of automatic configuration &&automatic loading of controller

The principle of SpringBoot automatic configuration &&automatic loading of controller.md

I haven’t updated my blog for a long time. I just have some free time to do it recently. I was writing and writing when I suddenly remembered,

Why we can automatically load when we click application? (Good guy, I was stunned. Haha)@Controller

1. First we come to the startup site ===>Startup class

@SpringBootApplication
public class TestApplication extends SpringBootServletInitializer {
    
    

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
    
    
        return builder.sources(ActAfterApplication.class);
    }

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

We will see that there will be an annotation onTestApplication the startup class:@SpringBootApplication

This annotation is the core of our article today, core**, core**!!!=====> ;You may say, I asked how to load d, why do you show me these? Don’t worry!Dabai (●—●) , let’s look down@Controller

2.@SpringBootApplication剖析

First, let’s look at the three key annotations that can be entered by clicking on this annotation.

  1. @SpringBootConfiguration
  2. @EnableAutoConfiguration
  3. @ComponentScan ====> This annotation is the key to why we Spring load the @Controller component a>
@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 {
    
    

3.@SpringBootConfiguration:

This annotation indicates that this class isConfiguration class, click on it and you will find that it is@Configuration, when loading Load intoSpring IOC

Just think of him as a character who hasconfiguration ===> Set him up Dragon robe, being a prince

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration    //就是这个注解最关键=====================================
public @interface SpringBootConfiguration {
    
    

}

4.@EnableAutoConfiguration

**Function:**This annotation can be said to be the soul ofSpringboot,automatic configuration, also That is to load all the configuration classes configured in our configuration file,

It will scan the files under the jar package and load all qualified automatic configuration classes into ====> in the container is the core of automatic configurationMETA-INF/spring.factoriesIOC

Why? Let’s click into the source code to take a look. In the following source code, we will look at two core annotations (which are the key to automatic configuration. These two annotations can be ignored or ignoredCore Notes)Go to the next one

1.@AutoConfigurationPackage

2.@Import(AutoConfigurationImportSelector.class)

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
    
    

4.1 @AutoConfigurationPackage

Click on the source code and we will see one of them:@Import(AutoConfigurationPackages.Registrar.class)

**Function:**Use@Import annotation to import a collection that conforms to the automatic configuration class,purpose for Load intoIOCcontainer

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
    
    

AutoConfigurationPackages.Registrar.classThe source code can be ignored directly. If you are interested, you can take a look.

	static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
    
    

		@Override
		public void registerBeanDefinitions(AnnotationMetadata metadata,
				BeanDefinitionRegistry registry) {
    
    
			register(registry, new PackageImport(metadata).getPackageName());  //获取包名
		}

		@Override
		public Set<Object> determineImports(AnnotationMetadata metadata) {
    
    
			return Collections.singleton(new PackageImport(metadata));
		}

	}

4.2@Import(AutoConfigurationImportSelector.class)

This class is even more important. Why do you say this? Let us interpret it together with the source code below (for the convenience of reading, only the core block of the required source code is retained< /span>)

  1. According to the method introduced in AutoConfigurationImportSelector,selectImports
  2. Readall dependenciesjarThe package below isMETA-INF/spring.factories The following files (how to load the files under this directory? ===>Please seegetCandidateConfigurations for explanation)
  3. And load the classes required by the project according to the loading conditions

Through these three steps, the automatic loading ofSpringBoot is completed ===> and thus@AutoConfigurationPackageexecution ends

public class AutoConfigurationImportSelector
		implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware,
		BeanFactoryAware, EnvironmentAware, Ordered {
    
    

	@Override
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
    
    
		if (!isEnabled(annotationMetadata)) {
    
    
			return NO_IMPORTS;
		}
		AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
				.loadMetadata(this.beanClassLoader);
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
		List<String> configurations = getCandidateConfigurations(annotationMetadata,attributes);
		configurations = removeDuplicates(configurations);
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
		checkExcludedClasses(configurations, exclusions);
		configurations.removeAll(exclusions);
		configurations = filter(configurations, autoConfigurationMetadata);
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return StringUtils.toStringArray(configurations);
	}

getCandidateConfigurations:

In order to facilitate confirmation, I willAutoConfigurationImportSelectorclass the following methodSeparatelyPick it out

zThis method will read all the dependencies of 'META-INF/spring.factories'jar,

Getspring.factoriesFull name,====.>In fact, the following annotation is also written >Point 击loadFactoryNamesMethod,> LoadMETA-INF/spring.factories

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
			AnnotationAttributes attributes) {
    
    
		List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
				getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
		Assert.notEmpty(configurations,
				"No auto configuration classes found in META-INF/spring.factories. If you "
						+ "are using a custom packaging, make sure that file is correct.");
		return configurations;
	}

5.@ComponentScan

Now that the previous two notes have been explained, we finally come to this note, which is also the note that solved my doubts

Do you want me to explain?===> Just register us@Controller,@Service, and wait for the annotations to be automatically scanned and addedIOCIn container

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

6.META-INF/spring.factories

What the hell is this??? After talking for a long time, let’s go take a look. In fact, I am very curious when writing this blog, hahaha

Let's go and see together

https://blog.csdn.net/weixin_40017062/article/details/128710518

Guess you like

Origin blog.csdn.net/weixin_43475992/article/details/132109806