SpringBoot2自动配置3

1、配置绑定(要么使用把它加到容器中,要么在配置类中开启配置绑定)

过程:properties-->配置文件-->JavaBean

  ~使用原生代码编写(麻烦):

public class getProperties {
     public static void main(String[] args) throws FileNotFoundException, IOException {
         Properties pps = new Properties();
         pps.load(new FileInputStream("a.properties"));
         Enumeration enum1 = pps.propertyNames();//得到配置文件的名字
        //遍历配置属性名,拿到属性值
         while(enum1.hasMoreElements()) {
             String strKey = (String) enum1.nextElement();
             String strValue = pps.getProperty(strKey);
             System.out.println(strKey + "=" + strValue);
             //封装到JavaBean。
         }
     }
 }

  ~使用注解的方式:@ConfigurationProperties(简单)

       (配置文件时yml后缀,所以配置项要用:冒号分隔)

    使用@ConfigurationProperties这个注解,说明这是一个配置绑定,且把用@Component加到容器中。

    让Car类属性中的值跟配置文件中设置的值已经成功绑定上,也就是配置文件为Car组件的属性赋值。

//测试配置绑定功能
//上一步中,配置文件为Car组件赋值,IOC容器中已经存在该组件,
//我们只要在控制类中使用自动注入,就可以把容器中的组件拿来用

 需要修改组件中属性的值,只需要修改配置文件,然后重新启动项目,重新浏览器请求:

~还可以使用@EnableConfigurationProperties + @ConfigurationProperties方式配置

   这种方式不需要使用@Component标注配置注解,而是在配置类MyConfig上方加一个注解,来开启某个类的配置绑定和将该类组件自动注册到容器中

 2、自动配置原理

   2.1引导加载自动配置类 核心注解:@SpringBootApplication,它包含了三个注解:

 

重点讲解@EnableAutoConfiguration开启自动配置,它又是@AutoConfigurationPackage和@Import这两个注解的合成:

                     

    这里用到Import用于给容器中导入一个组件,导的是Registrar这个组件,但是这个组件要干的事是导入一系列组件(MainApplication所在包下)。

 底层源代码:Registrar批量注册,根据注解元信息获取MainApplication所在位置、获取所有包名,给容器中导入一系列组件。

 

     ~调试代码,查看元信息包含了哪些?

 上面的调试看到的是这个注解的元信息!

               ~计算代码

 得到的是包名。

                     2、@Import({AutoConfigurationImportSelector.class})

 

1、利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件
2、调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类
3、利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的组件
4、从META-INF/spring.factories位置来加载一个文件。
    默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件
    spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories
    

              Selector核心代码  this.getAutoConfigurationEntry

public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }

3、按需加载,只有导进来了某些场景,对应的包才能导入,包下的组件才能生效

   ~修改默认配置:防止有些用户配置的文件上传解析器不符合规范

        @Bean
        @ConditionalOnBean(MultipartResolver.class)  //容器中有这个类型组件
        @ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) //容器中没有这个名字 multipartResolver 的组件
        public MultipartResolver multipartResolver(MultipartResolver resolver) {
            //给@Bean标注的方法传入了对象参数,这个参数的值就会从容器中找。
            //SpringMVC multipartResolver。防止有些用户配置的文件上传解析器不符合规范
            // Detect if the user has created a MultipartResolver but named it incorrectly
            return resolver;
        }
给容器中加入了文件上传解析器;

XXXAutoConfig自动导进来,给容器装配好一系列组件,这些组件就从xxxProperties中拿值,最终会到配置文件中拿值。

 

要修改配置文件:方法一查文档、方法二查底层。

 4、官方文档:https://docs.spring.io/spring-boot/docs/2.4.3/reference/html/using-spring-boot.html#using-boot

 

 

 

 5、最佳实践

  5.1 引入场景依赖

https://docs.spring.io/spring-boot/docs/2.4.3/reference/html/using-spring-boot.html#using-boot-starter

  5.2查看自动配置了哪些(涉及底层原理,选做)

    ~自己分析,引入场景对应的自动配置一般都生效了

    ~配置文件中debug=true开启自动配置报告。Negative(不生效)Positive(生效)

  

 

   5.3是否需要修改

    ~参照文档修改配置项:https://docs.spring.io/spring-boot/docs/2.4.3/reference/html/appendix-application-properties.html#common-application-properties;自己分析:xxxProperties绑定了配置文件的哪些

    

     ~自定义加入或者替换组件(除了改配置外还想增加一些功能):@Bean、@Component。。

    ~自定义器 XXXCustomizer

    ~。。。。

   

原文地址:https://www.cnblogs.com/Yi-ling/p/14456312.html