preface

Springboot’s startup class can be very simple. The two key parts are the Annotation definition (@SpringBootApplication) and the class definition (SpringApplication.run). This article focuses on the @SpringBootApplication annotation, and the class definition will be examined in subsequent articles.

@SpringBootApplication
public class Application {


    public static void main(String[] args) { SpringApplication.run(Application.class, args); }}Copy the code

Which reference “SpringBoot revealed” inside the analysis, is also a summary of learning.

@ SpringBootApplication annotations

@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 {
    .....
}
Copy the code

It looks like there are so many annotations, but the @SpringBootApplication is actually a “three-body” structure, with only three annotations that matter:

  • @Configuration
  • @EnableAutoConfiguration
  • @ComponentScan

Why does @SpringBootApplication annotation not include @Configuration when it is actually in @SpringBootConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
Copy the code

@SpringBootConfiguration inherits from @Configuration and has the same functionality. It labels the current class as a Configuration class and will include instances of one or more @Bean annotated methods declared in the current class into the Spring container, and the instance name is the method name.

In fact, if we use the following Springboot boot class, the entire Springboot application will still be functionally equivalent to the previous boot class.

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {


    public static void main(String[] args) { SpringApplication.run(Application.class, args); }}Copy the code

Here are three key notes

@Configuration

The @Configuration here is the same @Configuration used by the Spring IoC container Configuration class in the form of JavaConfig, so the startup class labeled @Configuration is itself an IoC container Configuration class.

The previous XML configuration looked like this:

<?xml version="1.0" encoding="UTF-8"? >
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
       default-lazy-init="true">
    <! - bean definitions -- -- >
</beans>
Copy the code

The current JavaConfig configuration looks like this, and the effect is equivalent, with this annotation the specification is a configuration class

@Configuration
public class Application{
    / / bean definition
}
Copy the code

For more information on @Configuration and @Beans, see the article: Using Java Configuration for Spring Bean Management

@ComponentScan

The functionality of @ComponentScan is to automatically scan and load qualified component or bean definitions, and eventually load those bean definitions into the container. We can specify the scope of the @ComponentScan automatic scan with properties such as basePackages. If not, the default Spring framework implementation is to scan the package from the class where @ComponentScan is declared. By default, this is not specified. SpringBoot’s boot classes are best placed in the root package.

@EnableAutoConfiguration

Remember the various Annotation definitions that the Spring framework provides with names beginning with @enable? For example, @enablescheduling, @enablecaching, @enablemBeanexport, etc., the concept of @enableAutoConfiguration and the “way of doing things” are actually in the same line, with the support of @import, Collect and register the bean definitions related to a particular scenario:

  • @EnableSchedulingSpring scheduling framework-related bean definitions are loaded into the Ioc container via @import.
  • @EnableMBeanExportJmx-related bean definitions are loaded into the Ioc container via @import

With the help of @Import, @enableAutoConfiguration loads all the bean definitions that meet the autoconfiguration criteria into the Ioc container, and that’s it

@enableAutoConfiguration is also a compound Annotation, defined as follows:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<? >[] exclude()default {};

    String[] excludeName() default {};
}
Copy the code

One of the most critical is @ Import (AutoConfigurationImportSelector. Class), with the aid of AutoConfigurationImportSelector this class, The @enableAutoConfiguration can help the Springboot application load all the qualified @Configuration into the current Ioc container created and used by Springboot

AutoConfigurationImportSelector

Before SpringBoot1.5, use EnableAutoConfigurationImportSelector, it inherits from AutoConfigurationImportSelector, after 1.5, EnableAutoConfigurationImportSelector already no longer been advised to use, but it is recommended to use AutoConfigurationImportSelector.

When it is executed

We now know the introduced in @ EnableAutoConfiguration AutoConfigurationImportSelector class, so how is it?

Springboot starts with ConfigurationClassParser to resolve a Configuration class that is decorated with @Configuration, and then handles other annotations that are decorated inside the class, such as @Import, @ComponentScan, @bean annotation, etc.

If @import (ImportSelector) is found in the annotation, a corresponding ImportSelector object is created and its selectImports method is called, And AutoConfigurationImportSelector is a ImportSelector implementation class. For more analysis of ConfigurationClassParser, see the article :Spring Class Registry Notes

The hero behind automatic configuration :SpringFactoriesLoader

The main function of the SpringFactoriesLoader is to load the configuration from the specified configuration file META/spring.factories, which is a typical Java properties file with key-value configuration format. It’s just that both Key and Value are full class names of Java types.

If you go to the loadFactoryNames() method, you see that loadFactoryNames() reads the meta-INF /spring.factories file under the ClassPath.

Four methods in the SpringBootApplication annotation

The @springBootApplication includes not only the three important annotations above, but also four methods:

  • Class<? >[] exclude() default {};Exclude specific classes from the Spring container based on Class, passing in the Class type
  • String[] excludeName() default {};Exclude a particular Class from the Spring container based on its Class name, passing in an array of the full Class name strings
  • String[] scanBasePackages() default {};Specifies the scanned package as an array of strings of package names
  • Class<? >[] scanBasePackageClasses() default {};Specifies the scan package as an array of Class types

summary

Here’s a summary of the characteristics of three important annotations in the @SpringBootApplication:

  • @Configuration

Defines the configuration class for the Spring Ioc container

  • @EnableAutoConfiguration:

From the classpath to search all META/spring. Factories configuration files, and will be one of org. Springframework. Boot. Autoconfigure. EnableAutoConfiguration corresponding configuration items, That is, a list of auto-configuration classes is loaded into the Ioc container. Simple says, is that @ EnawebleAutoConfiguration let Spring Boot according to the classpath jar packages depend on automatic configuration for the current project, for example, to add the Spring – the Boot – starter – web dependence, Tomcat and Spring MVC dependencies are automatically added. All Configuration classes annotated with @configuration are resolved using ConfigurationClassParser.

  • @ComponentScan

Automatically scans and loads eligible component or bean definitions

The resources

  • SpringBoot reveal
  • Spring Boot dry series :(3) Boot principle analysis