0


Springboot自动配置


   我们使用Springboot进行开发的时候发现真的很方便,只需很少的配置、少量注解以及引入一些starter就可以完成一个简单项目的开发。使我们受益的就是Springboot的自动配置功能,下面我们来探索Springboot的自动配置原理。

Springboot自动配置核心原理图

在这里插入图片描述

SpringBoot的标准启动入口如下:

@SpringBootApplicationpublicclassGraduationProjectApplication{publicstaticvoidmain(String[] args){SpringApplication.run(GraduationProjectApplication.class, args);}}

   通过标准启动入口的代码可以看出,Springboot启动类的核心注解是@SpringBootApplication。

@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@interfaceSpringBootApplication{@AliasFor(
        annotation =EnableAutoConfiguration.class)Class<?>[]exclude()default{};@AliasFor(
        annotation =EnableAutoConfiguration.class)String[]excludeName()default{};@AliasFor(
        annotation =ComponentScan.class,
        attribute ="basePackages")String[]scanBasePackages()default{};@AliasFor(
        annotation =ComponentScan.class,
        attribute ="basePackageClasses")Class<?>[]scanBasePackageClasses()default{};@AliasFor(
        annotation =ComponentScan.class,
        attribute ="nameGenerator")Class<?extendsBeanNameGenerator>nameGenerator()defaultBeanNameGenerator.class;@AliasFor(
        annotation =Configuration.class)booleanproxyBeanMethods()defaulttrue;}

   根据源码,可以看出@SpringBootApplication注解主要包含3个注解:@SpringBootConfiguration 、@EnableAutoConfiguration 、@ComponentScan。接下来,分别讲解这三个注解。

一、@SpringBootConfiguration源码如下:

@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Configurationpublic@interfaceSpringBootConfiguration{@AliasFor(
        annotation =Configuration.class)booleanproxyBeanMethods()defaulttrue;}

   作用:继承自@Configuration,标注在类上表示这是一个SpringBoot的配置类,允许在上下文中注册额外的bean或者导入其他配置项。

二、@ComponentScan 的源码如下:

@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE})@Documented@Repeatable(ComponentScans.class)public@interfaceComponentScan{@AliasFor("basePackages")String[]value()default{};@AliasFor("value")String[]basePackages()default{};Class<?>[]basePackageClasses()default{};Class<?extendsBeanNameGenerator>nameGenerator()defaultBeanNameGenerator.class;Class<?extendsScopeMetadataResolver>scopeResolver()defaultAnnotationScopeMetadataResolver.class;ScopedProxyModescopedProxy()defaultScopedProxyMode.DEFAULT;StringresourcePattern()default"**/*.class";booleanuseDefaultFilters()defaulttrue;ComponentScan.Filter[]includeFilters()default{};ComponentScan.Filter[]excludeFilters()default{};booleanlazyInit()defaultfalse;@Retention(RetentionPolicy.RUNTIME)@Target({})public@interfaceFilter{FilterTypetype()defaultFilterType.ANNOTATION;@AliasFor("classes")Class<?>[]value()default{};@AliasFor("value")Class<?>[]classes()default{};String[]pattern()default{};}}

   作用:自动扫描并加载符合条件的组件或者bean , 将这个bean定义加载到IOC容器中 。扫描被@Compent(@Service@Controller)注解的bean,注解是会默认扫描启动类所在的包下的所有的类,也可以自定义不扫描一些bean。

三、@EnableAutoConfiguration源码如下:

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

   作用:开启自动配置功能,通过@EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效。

   在源码中我们可以看出@EnableAutoConfiguration主要包含两个注解:@AutoConfigurationPackage、@Import。

(一) @AutoConfigurationPackage

   点进源码,发现其包含了@Import({Registrar.class}),再点进去发现是批量注册组件,而默认扫描路径就是与主启动类所在的包,也就是主启动类坐在的包下面,所有的组件会被扫描注册到IoC容器中。这就解释了为什么要把自己的组件写到与主启动类同包下。

(二) @Import

   @EnableAutoConfiguration其底层原理是使用@Import注解导入一些配置类,实现Bean的动态加载。

   @Enable底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到IOC容器中。而@Import提供4种用法:

   1.导入Bean

   2.导入配置类

   3.导入 ImportSelector 实现类。一般用于加载配置文件中的类

   4.导入 ImportBeanDefinitionRegistrar 实现类。

   @EnableAutoConfiguration 注解内部使用第3种方法:@Import导入 ImportSelector 实现类的方式加载配置类,即 @Import(AutoConfigurationImportSelector.class),给容器导入组件。AutoConfigurationImportSelector :自动配置导入选择器,给容器中导入一些组件,自动配置核心功能的实现实际上是通过AutoConfigurationImportSelector来实现的。

   META-INF/spring.factories配置文件中定义了大量的配置类,当 SpringBoot 应用启动时,会自动加载这些配置类,根据@conditional注解按需初始化Bean ,从而实现了springboot的自动配置。

(三) @Conditional(条件类.class)注解

   作用:实现选择性的创建 Bean 操作。

   SpringBoot 提供的常用条件注解:

      ConditionalOnProperty:判断配置文件中是否有对应属性和值才初始化Bean

      ConditionalOnClass:判断环境中是否有对应字节码文件才初始化Bean

      ConditionalOnMissingBean:判断环境中没有对应Bean才初始化Bean

      ConditionalOnBean:判断环境中有对应Bean才初始化Bean

四、自动配置具体实现步骤

   1.SpringBoot启动的时候加载主启动类,通过@EnableAutoConfiguration开启自动配置功能。

   2.@EnableAutoConfiguration利用AutoConfigurationImportSelector给容器中导入一些组件。

   3.通过protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes)获取候选的配置和核心方法,扫描所有jar包类路径下"META-INF/spring.factories",通过@AutoConfigurationPackage自动配置包。

   4.把扫描到的文件包装成Properties对象。

   5.从properties中获取到EnableAutoConfiguration.class类名对应的值,并把他们添加在容器中。

   6.整个过程就是将类路径下"META-INF/spring.factories"里面配置的所有EnableAutoConfiguration的值加入到容器中。

   7.根据@Conditional注解中的条件判断,决定这个配置是否生效。

   8.初始化Bean,自动配置完成。

总结

   SpringBoot通过@EnableAutoConfiguration开启自动装配,通过 SpringFactoriesLoader 最终加载META-INF/spring.factories中的自动配置类实现自动装配,自动配置类其实就是通过@Conditional按需加载的配置类。

标签: spring boot java spring

本文转载自: https://blog.csdn.net/yanghang1122/article/details/124970078
版权归原作者 yhang0802 所有, 如有侵权,请联系我们删除。

“Springboot自动配置”的评论:

还没有评论