SpringBoot入门---自动配置原理

最近学习springboot的过程中,学到了自动配置的原理,在这里写一下笔记,加深一下印象,方便以后复习。

1.创建一个springboot项目(省略)

2.分析主配置类

@SpringBootApplication // 表示该类是一个主配置类,应该运行该类的main()来启动springboot应用(主入口)
public class DemoApplication {

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

}

@SpringBootApplication注解

@Target(ElementType.TYPE)	//表示该注解可以使用的范围,ElementType.TYPE:用于描述类、接口(包括注解类型) 或enum声明
@Retention(RetentionPolicy.RUNTIME)	// 保存注解信息,RetentionPoicy.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) 注解中的 AutoConfigurationPackages.Registrar.class

static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {

   // 扫描主配置类所在的包及其子包。这就是为什么不需要配置@ComponentScan来扫描包。springboot搞定了
   @Override
   public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
      register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
   }

}

@Import(AutoConfigurationImportSelector.class) 注解

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

   private static final AutoConfigurationEntry EMPTY_ENTRY = new AutoConfigurationEntry();

   private static final String[] NO_IMPORTS = {};

   private static final Log logger = LogFactory.getLog(AutoConfigurationImportSelector.class);

   private static final String PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE = "spring.autoconfigure.exclude";

   private ConfigurableListableBeanFactory beanFactory;

   private Environment environment;

   private ClassLoader beanClassLoader;

   private ResourceLoader resourceLoader;

   private ConfigurationClassFilter configurationClassFilter;

   @Override
   public String[] selectImports(AnnotationMetadata annotationMetadata) {
      if (!isEnabled(annotationMetadata)) {
         return NO_IMPORTS;
      }
      // 获取自动配置条目
      AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
      return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
   }

   protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
       if (!isEnabled(annotationMetadata)) {
           return EMPTY_ENTRY;
       }
       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 = getConfigurationClassFilter().filter(configurations);
       fireAutoConfigurationImportEvents(configurations, exclusions);
       return new AutoConfigurationEntry(configurations, exclusions);
	}
          
   protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
       	/*
        	1.扫描所有jar包类路径下的 META-INF/spring.factories 文件,这一步,获取到了所有的自动配置类的全限定类名,然后将这些内容包装成了 Properties 类。
        	2.通过 Properties 类获取到 EnableAutoConfiguration.class类(全限定类名)对应的值,一个一个添加到容器中
      	*/
		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;
	}
    // 其他方法省略
}

springboot使用的自动配置都是以 xxxAutoConfiguration.class 命名,将每一个的自动配置类都加载到容器中,进行自动配置。

如果需要对某个功能自定义属性,就需要找到 xxxProperties.class ,该类中的每一个属性都是可以通过 @ConfigurationProperties(prefix = “xxx”) 中的 perfile 指定的 前缀+属性 来自定义属性。

本文章是博主学习SpringBoot过程中的一些视频笔记,如有错误,请大佬指出,感谢大佬!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值