【SpringBoot源码】SpringBoot自动配置原理

目录

一、简介

1)、@SpringBootConfiguration 

2)、@ComponentScan 

3)、@EnableAutoConfiguration

二、@AutoConfigurationPackage 

 三、@Import(AutoConfigurationImportSelector.class)

1)、AutoConfigurationImportSelector介绍 

2)、自动配置流程 

2-1)、ConfigurationClassParser#parse() 

2-2)、this.deferredImportSelectorHandler.process() 

2-2-1)、第一步:register() 

2-2-2)、第二步:processGroupImports() 

2-2-2-1)、process()方法

2-2-2-2)、selectImports()方法 


本篇源码基于spring-boot-2.1.0.RELEASE版本进行分析,各个版本可能存在一些差别。 

一、简介

SpringBoot的启动从main()方法开始:

在主启动类上,我们只需要加上@SpringBootApplication注解,就能成功启动springboot应用了,那么我们就从注解入手,看下它是如何帮我们配置好所需要的一些环境的。 

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
// @SpringBootConfiguration内部使用@Configuration修饰,标记启动类是一个Spring的配置类
@SpringBootConfiguration
// @EnableAutoConfiguration: 实现自动装配的核心注解. 内部包含两个注解:@AutoConfigurationPackage + @Import(AutoConfigurationImportSelector.class)
@EnableAutoConfiguration
// 包扫描:扫描启动类所在的包以及子包所有Bean组件并注册到IOC容器中
@ComponentScan(excludeFilters = {
    @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
    @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
// SpringBoot项目启动的核心注解
// @SpringBootApplication = @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan
public @interface SpringBootApplication {
 
    /**
* Exclude specific auto-configuration classes such that they will never be applied.
* @return the classes to exclude
*/
    // 等同于EnableAutoConfiguration注解的exclude属性
    @AliasFor(annotation = EnableAutoConfiguration.class)
    Class<?>[] exclude() default {};
 
    /**
* Exclude specific auto-configuration class names such that they will never be
* applied.
* @return the class names to exclude
* @since 1.3.0
*/
    // 等同于EnableAutoConfiguration注解的excludeName属性
    @AliasFor(annotation = EnableAutoConfiguration.class)
    String[] excludeName() default {};
 
    /**
* Base packages to scan for annotated components. Use {@link #scanBasePackageClasses}
* for a type-safe alternative to String-based package names.
* @return base packages to scan
* @since 1.3.0
*/
    // 等同于ComponentScan注解的basePackages属性
    @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
    String[] scanBasePackages() default {};
 
    /**
* Type-safe alternative to {@link #scanBasePackages} for specifying the packages to
* scan for annotated components. The package of each class specified will be scanned.
* <p>
* Consider creating a special no-op marker class or interface in each package that
* serves no purpose other than being referenced by this attribute.
* @return base packages to scan
* @since 1.3.0
*/
    // 等同于ComponentScan注解的basePackageClasses属性
    @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
    Class<?>[] scanBasePackageClasses() default {};
 
}

@SpringBootApplication 使用三个注解修饰:

1)、@SpringBootConfiguration 

标记启动类是一个Spring的配置类。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
// 相当于@SpringBootConfiguration就是@Configuration
public @interface SpringBootConfiguration {
 
}

2)、@ComponentScan 

扫描启动类所在的包以及子包所有Bean组件并注册到IOC容器中。

3)、@EnableAutoConfiguration

实现自动装配的核心注解,内部包含两个注解:@AutoConfigurationPackage + @Import(AutoConfigurationImportSelector.class)。 

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
// 自动配置包
@AutoConfigurationPackage
// 使用@Import注解导入AutoConfigurationImportSelector类,实现了ImportSelector接口,重写了selectImports()方法,帮助我们返回所有需要被注册为bean的类全限定类名的数组集合
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
 
	String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
 
	/**
	 * 排除特定的自动配置类,使它们永远不会被应用
	 * Exclude specific auto-configuration classes such that they will never be applied.
	 * @return the classes to exclude
	 */
	Class<?>[] exclude() default {};
 
	/**
	 * 排除特定的自动配置类名称,使其永远不会被应用
	 * Exclude specific auto-configuration class names such that they will never be
	 * applied.
	 * @return the class names to exclude
	 * @since 1.3.0
	 */
	String[] excludeName() default {};
 
}

springboot的自动装配就是依靠@EnableAutoConfiguration这个注解实现的,而@EnableAutoConfiguration又是由下面两部分组成:

1、@AutoConfigurationPackage

2、@Import(AutoConfigurationImportSelector.class)

二、@AutoConfigurationPackage 

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
// 向容器中导入了AutoConfigurationPackages.Registrar组件
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
 
}

可以看到,@AutoConfigurationPackage注解的功能是由@Import注解实现的,它是Spring框架的底层注解,它的作用就是给容器中导入某个组件类AutoConfigurationPackages.Registrar,我们看下这是个什么组件?

@AutoConfigurationPackage注解的作用是将添加该注解的类所在的package作为自动配置package进行管理。也就是说当SpringBoot应用启动时默认会将启动类所在的package作为自动配置的package,这样主程序类所在包及所有子包下的组件就会被扫描到spring容器中。

// 实现了ImportBeanDefinitionRegistrar、DeterminableImports接口,重写了registerBeanDefinitions()、determineImports()方法
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
 
    // 注册bean定义
    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata,
            BeanDefinitionRegistry registry) {
        register(registry, new PackageImport(metadata).getPackageName());
    }
 
    // 返回一组需要注入的对象
    @Override
    public Set<Object> determineImports(AnnotationMetadata metadata) {
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值