springboot如何通过注解实现自动配置

SpringBootApplication源码如下:

@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 {
    
    }

其中和自动配置相关的注解是@EnableAutoConfiguration,源码如下:

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

先看@AutoConfigurationPackage,该注解的源码如下:

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

}

通过@Import(AutoConfigurationPackages.Registrar.class)引入启动类所在包路径,主要给后续框架使用,如JPA等,debug如下:

org.springframework.boot.autoconfigure.AutoConfigurationPackages#register
public static void register(BeanDefinitionRegistry registry, String... packageNames) {
    
    
	if (registry.containsBeanDefinition(BEAN)) {
    
    
		BeanDefinition beanDefinition = registry.getBeanDefinition(BEAN);
		ConstructorArgumentValues constructorArguments = beanDefinition.getConstructorArgumentValues();
		constructorArguments.addIndexedArgumentValue(0, addBasePackages(constructorArguments, packageNames));
	}
	else {
    
    
		GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
		beanDefinition.setBeanClass(BasePackages.class);
		beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, packageNames);
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		registry.registerBeanDefinition(BEAN, beanDefinition);
	}
}

在这里插入图片描述
注解@Import(AutoConfigurationImportSelector.class)就是引入需要的自动配置了,debug如下:

org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGrouping#getImports
public Iterable<Group.Entry> getImports() {
    
    
	for (DeferredImportSelectorHolder deferredImport : this.deferredImports) {
    
    
		this.group.process(deferredImport.getConfigurationClass().getMetadata(),
				deferredImport.getImportSelector());
	}
	return this.group.selectImports();
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/wang0907/article/details/113463404