唐僧喜欢小龙女

导航

SpringBoot 的自动配置原理

1、SpringBoot项目用依赖整理

问一个问题,我们创建了一个SpringBoot项目,添加starter依赖的时候为什么不用写版本号?根本原因是Springboot每个版本的根项目里面定义好了starter的版本号,使用的标签是<dependencyManagement>这样避免了我们自己引入相关依赖的时候出现依赖冲突。

 

2、SpringBoot 加载内部和外部配置文件的顺序

2.1 加载内部配置文件的顺序

  –file:./config/
  –file:./
  –classpath:/config/
  –classpath:/

2.2 加载外部配置文件的顺序

1.命令行参数

所有的配置都可以在命令行上进行指定;
多个配置用空格分开; –配置项=值
  java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --server.port=8087 --server.context-path=/abc

2.来自java:comp/env的JNDI属性

3.Java系统属性(System.getProperties())

4.操作系统环境变量

5.RandomValuePropertySource配置的random.*属性值

由jar包外向jar 包内寻找

6.jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件

7.jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件

8.jar包外部的application.properties或application.yml(不带spring.profile)配置文件

9.jar包内部的application.properties或application.yml(不带spring.profile)配置文件

特别注意不是我理解的那样:A依赖B,A启动的时候会找B的配置文件。

10.@Configuration注解类上的@PropertySource

11.通过SpringApplication.setDefaultProperties指定的默认属性

3. 自动配置原理 

我们需要开发某个场景时就引入某个场景的starter,该starter会把该场景所需的组件放到IOC容器里面。
容器扫描的时候使用默认的包扫描规则,场景组件自带默认的值,可以通过配置文件修改。这就解决了组件怎么放到IOC容器中
的问题、组件值的问题,从而让我们使用起来某个场景。

@SpringBootApplication 由三个注解组成 @SpringBootConfiguration、@EnableAutoConfiguration 和 @ComponentScan

3.1@SpringBootConfiguration

核心的注解如下

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Indexed
public @interface SpringBootConfiguration {
    @AliasFor(
        annotation = Configuration.class
    )
    boolean proxyBeanMethods() default true;
}

@Configuration标注在某个类上,表示这是一个 springboot的配置类。可以向容器中注入组件。

 3.2 @ComponentScan

  • @ComponentScan:配置用于 Configuration 类的组件扫描指令。
  • 提供与 Spring XML 的 <context:component-scan> 元素并行的支持。
  • 可以 basePackageClasses 或basePackages 来定义要扫描的特定包。 如果没有定义特定的包,将从声明该注解的类的包开始扫描
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)

这里根据类型排除了两个类。

3.3 @EnableAutoConfiguration 

这个配置是核心的注解,主要是开启自动配置的,由一下的两个注解组成 @AutoConfigurationPackage 和 @Import({AutoConfigurationImportSelector.class})

 

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage //自动配置包
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};
}

@AutoConfigurationPackage 由 @Import({Registrar.class}) 组成,Registrar实现了 ImportBeanDefinitionRegistrar 这个接口

负责导入主配置类和所在的包以及下面的子包里面所有的组件扫描进Sprint容器,例如用用@Controller注解的类。

@Import({AutoConfigurationImportSelector.class}) 主要负责扫描当前系统的类路径下所有的META-INF/spring.factories文件中的EnableAutoConfiguration的值(非常多的的XXXAutoConfiguration)

按需让这些配置类里面的组件生效(因为配置类里面有很多的条件注解)。比如说:之前搭建一个Springmvc 的web工程需要配置dispacheserverlet,

根容器、子容器、视图解析器等,使用SpringBoot开发的话只需要引入spring-boot-starter-web这个依赖,WebMvcAutoConfiguration就会生效,这个配置类里面的视图解析器、dispacheserverlet、子容器的组件都会加载到容器里面,这样就可以访问我们的应用了。

 

posted on 2022-01-04 09:38  与时具进&不忘初心  阅读(165)  评论(0编辑  收藏  举报