Start class 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

1. @SpringBootConfiguration

SpringBootConfiguration is a wrapper around @Configuration, which is equivalent to @Configuration

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

}
Copy the code

2. @EnableAutoConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited

@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

}
Copy the code

2.1 @ AutoConfigurationPackage

By introducing AutoConfigurationPackages. @ Import Registar class, for @ SpringBootApplication annotation class of scan and its child package, add components to the container

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

}
-----------------------------------------------------------------------------------------
static class Registrar implements ImportBeanDefinitionRegistrar.DeterminableImports {
	@Override
	public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
		// All components under the package and subpackages of the class annotated by @SpringBootApplication are scanned by default
		register(registry, new PackageImport(metadata).getPackageName());
	}

	@Override
	public Set<Object> determineImports(AnnotationMetadata metadata) {
		return Collections.singleton(newPackageImport(metadata)); }}Copy the code

2.2 @ Import (AutoConfigurationImportSelector. Class)

Help the SpringBoot application load all eligible @Configuration configurations into the IOC container currently created and used by SpringBoot

org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#selectImports

@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
	// Check whether the @enableAutoConfiguration annotation is enabled by default
	if(! isEnabled(annotationMetadata)) {return NO_IMPORTS;
	}
	//1. Load the meta-INF /spring-autoconfigure-metadata.properties file to obtain all the conditions for automatic configuration of expenditures.
	// The full name of the auto-configured class. Conditions = value
	AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
			.loadMetadata(this.beanClassLoader);
	AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
			annotationMetadata);
	return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}

Copy the code

2.3 @ ComponentScan

The @ComponentScan annotation scans the packages and subpackages of the SpringBoot main program startup class, which are resolved by the @AutoConfigurationPackage annotation above

conclusion

@ SpringBootApplication annotations

|- @SpringBootApplication  // Core annotations
	|- @SpringBootConfiguration // flags are configuration annotations
		|- @Configuration	// flags are configuration annotations
	|- @AutoConfigurationPackage // Automatically configure the package, get the boot class (annotated @springBootApplication) package path
	|- @Import(AutoConfigurationImportSelector.class) // Load the beans defined in meta-INF/spring.Factories into the IOC container
|- @ComponentScan / / package scans
Copy the code

3. Customize the Starter

3.1 Importing Dependencies

	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-autoconfigure</artifactId>
		<version>2.1.6. RELEASE</version>
	</dependency>
Copy the code

3.2 Writing injection classes

@Configuration
@ConditionalOnClass(SimpleBean.class)
public class MyAutoConfiguration {

    static {
        System.out.println("My Auto Configuration Init.....");
    }

    @Bean
    public SimpleBean simpleBean(a){
        return newSimpleBean(); }} -- -- -- -- -- -- -- -- -- -- -@EnableConfigurationProperties(SimpleBean.class)
@ConfigurationProperties(prefix = "simplebean")
public class SimpleBean {
    private int id;
    private String name;

    @Override
    public String toString(a) {
        return "SimpleBean{" +
                "id=" + id +
                ", name='" + name + '\' ' +
                '} ';
    }

    public int getId(a) {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName(a) {
        return name;
    }

    public void setName(String name) {
        this.name = name; }} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -@Configuration
@ConditionalOnClass(SimpleBean.class)
public class MyAutoConfiguration {

    static {
        System.out.println("My Auto Configuration Init.....");
    }

    @Bean
    public SimpleBean simpleBean(a){
        return newSimpleBean(); }}Copy the code

3.3. Compile the resources/ meta-INF /spring.factories file

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.lagou.config.MyAutoConfiguration
Copy the code

3.4 The caller introduces the usage method

simplebean:
  id: 1
  name: Custom starter
Copy the code
@RestController
public class DemoController {

    @Autowired
    private SimpleBean simpleBean;

    @RequestMapping("/")
    public SimpleBean hello(a){
        returnsimpleBean; }}Copy the code