19-springboot自动配置原理

SpringBoot自动配置原理(SpringBoot自动装配原理,SpringBoot starter原理)

SpringBoot可以根据定义在classpath下的类,自动的给你生成一些Bean,并加载到Spring的Context中,自动配置充分的利用了Spring 4.0的条件化配置特性,能够自动配置特定的Spring bean,用来启动某项特性;

关于条件化@Conditional注解:

如果你希望一个bean在某些条件下加载,在某些条件下不加载,则可以使用@Conditional注解;

@Configuration
public class MyConfig {
    @Bean
    @Conditional(MyBeanCondition.class)
    public MyBean myBean(){
        return new MyBean();
    }
}

 

public class MyBeanCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return false;
    }
}

当@Conditional(MyBeanCondition.class)true时,MyBean才会被创建,否则不会创建;

有了条件注解以保证某些bean在没满足特定条件的情况下就可以不必初始化,避免在bean初始化过程中由于条件不足,导致应用启动失败。

Conditional:有条件的; 条件; 有条件; 条件响应; 条件式;

有很多关于Conditional的注解

 

1、@SpringBootApplication

 

该注解本身,它本身还可以指定如下属性:

----

 

exclude : 排除指定的类,比如:

 

@SpringBootApplication(exclude = RedisAutoConfiguration.class)

 

可以排除自定义配置等等,根据自己的需要进行定制。

----

excludeName:排除指定的类名,通过bean name来进行排除指定的类,如下:

@SpringBootApplication(excludeName = "org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration")

----

scanBasePackages: 扫描指定的包添加到Spring容器中,参数为数组类型:

@SpringBootApplication(scanBasePackages="com.bjpowernode.boot.component")

扫描的包能注册识别,没有扫描的包将不能注册识别;

----

scanBasePackageClasses: 扫描指定包的类并添加到Spring容器中,参数为Class类型数组格式:

@SpringBootApplication(scanBasePackageClasses=MyComponent.class)

注册的类能识别,在同级包下或子包下的都能注册,否则不能识别;

----

@SpringBootApplication注解本身又是一个复合注解,它等效于如下四个注解:

@SpringBootConfiguration

@EnableAutoConfiguration

@ComponentScan

@ConfigurationPropertiesScan

@SpringBootConfiguration

该注解等效于@Configuration,那也就是说这个注解相当于@Configuration,所以这两个注解作用是一样的,它是让我们能够去注册一些额外的Bean,或者导入一些额外的配置,@Configuration还表示该类是一个配置类,不需要额外的xml进行配置,同时该类也是Spring容器中的一个bean

@EnableAutoConfiguration (重点)

该注解是Spring Boot自动配置注解,Spring Boot中的自动配置主要是@EnableAutoConfiguration的功劳,该注解可以让Spring Boot根据类路径中的jar包依赖为当前项目进行自动配置,该注解由如下两个注解构成:

@AutoConfigurationPackage

@Import(EnableAutoConfigurationImportSelector.class) 

-------------------------------

@AutoConfigurationPackage

让包中的类以及子包中的类能够被自动扫描到Spring容器中;

@Import(AutoConfigurationPackages.Registrar.class)

register(registry, new PackageImport(metadata).getPackageName());

@Import注解,这个注解就是通过import的方式将bean添加到Spring容器中;

-------------------------------

重点看看注解:

@EnableAutoConfiguration

这是Spring Boot自动配置的核心注解;

Spring框架本身也提供了几个名字为@Enable开头的Annotation定义。比如@EnableScheduling、@EnableCaching等,@EnableAutoConfiguration的理念和这些注解其实是一脉相承的。

@EnableScheduling是通过@Import将Spring调度框架相关的bean定义都加载到IoC容器。

@EnableAutoConfiguration也是借助@Import的帮助,将所有符合自动配置条件的bean定义加载到IoC容器;

 

该注解通过@Import注解导入了一个组件:AutoConfigurationImportSelector

,该组件实现了接口:
public interface DeferredImportSelector extends ImportSelector

该接口主要是为了导入@Configuration的配置项,而DeferredImportSelector是延期导入,当所有的@Configuration都处理过后才会执行;

 

 

 

 

 

 

该方法会先判断是否进行自动装配,而后会从META-INF/spring-autoconfigure-metadata.properties读取元数据与元数据的相关属性,紧接着会调用getCandidateConfigurations方法:

 

 

 

 

 

spring.factories

 

 

在这里又遇到我们熟悉的SpringFactoryiesLoader, 它会读取META-INF/spring.factories下的EnableAutoConfiguration的配置,紧接着在进行排除与过滤,进而得到需要装配的类

 

 

 

 

 

@EnableAutoConfiguration与@Conditional

@EnableAutoConfiguration自动加载配置,@Conditional根据环境决定是否解析处理配置,这两个注解的配合完成了自动化配置功能;

 

 

 

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

回到主题,@EnableAutoConfiguration中@Import注解通过引入ImportSelector实现类的方式将依赖中的默认配置加载到容器中。AutoConfigurationImportSelector类的具体内容在这里不做分析,这个过程简而言之就是:

查看Jar包中META-INF/spring.factories文件,获取其中EnableAutoConfiguration配置的value值。value值是由多个url组成,一个url表示一个配置类的全类名。然后通过@Import注解导入这些配置类。

@AutoConfigurationPackage中的@Import是通过引入ImportBeanDefinitionRegistrar实现类方式将各种组件和配置引入Spring容器的。简而言之,就是将标注了该注解的类所在的package设置成为自动配置package,这样主程序所在的包及其子包中的组件都能够被扫描到Spring容器中。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

Spring Boot中怎么自定义自动配置?

1、需要提供jar包,在jar包中需要包含META-INF/spring.factories文件;

2、在spring.factories中添加配置:

org.springframework.boot.autoconfigure.EnableAutoConfiguration =

com.yyf.xxxx.xxxConfiguration(该类我们自己去实现,里面主要是要做自动化的配置,给使用者把该配的配置好,让别人可以直接用)

3、xxxConfiguration的实现需要添加注解@Configuration;

4、xxxConfiguration也可以选择添加@Conditional来适应不同的环境;

5、在xxxConfiguration类中实现自动化配置;

有了SpringBoot的自动化配置,我们可以灵活的自定义我们自己的自动配置,当应用需要该功能时,只需要简单的依赖该jar包即可,同时Spring Boot为我们提供的条件注解,同样的代码可以灵活适应各种环境;

自动化配置实现参考文章:

https://blog.csdn.net/iSleepyPig/article/details/128072280

https://www.jianshu.com/p/6b2f672e2446

实现例子: https://blog.csdn.net/qq360694660/article/details/103121525

 

 

posted on 2023-03-28 17:42  companion  阅读(72)  评论(0编辑  收藏  举报