zoukankan      html  css  js  c++  java
  • springboot 基础

    配置

    application.properties 优先于 application.yml  
    properties 属性值不支持map、数组等,yml 可以
    

    读取默认配置文件(基本类型)

    直接在 application.yml 添加,程序中通过 @Value 读取(只能是基本类型)
    

    读取默认配置文件(复杂类型)

    直接在 application.yml 添加,使用一个 java 类来映射
    
    @Component
    @ConfigurationProperties(prefix = "person")
        public class Person {
        private int id; 
        private String name; 
        private List<String> hobby; 
        private String[] family; 
        private Map map;
        private Pet pet; // 需要创建一个 Pet 类
    }
    
    person: 
        id: 1
        name: Milk
        bobby: [吃饭, 睡觉, 打豆豆]
        family: [father, mother]
        map: {k1: v1, k2:v2}
        pet: {type: dog, name: 旺财} # 会根据 Pet 类自动映射
    
    <!-- 自定义配置属性不会提示,如果想要提示导入这个依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>
    

    读取非默认配置文件

    • resource 下创建一个 test.properties 文件
    test.id=110
    test.name=test
    
    • 配置类
    @Configuration 
    @PropertySource("classpath:test.properties") // 指定自定义配置文件位置和名称
    @EnableConfigurationProperties(MyProperties.class) // 开启对应配置类的属性注入功能
    @ConfigurationProperties(prefix = "test") // 指定配置文件注入属性前缀
        public class MyProperties {
        private int id;
        private String name;
    }
    

    注解完成配置

    不依赖配置文件,使用 @Configuration(类) 和 @Bean(方法)完成
    
    // 定义该类是一个配置类
    @Configuration 
    public class MyConfig {
        // 将返回值对象作为组件添加到Spring容器中,该组件id默认为方法名
        @Bean 
        public MyService myService(){
            return new MyService();
        }
    }
    

    自动配置(启动流程)

    /**
     * SpringbootApplication 定义
     * 
     *  除开元注解,主要关注 @SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan 三个注解
     */
    @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 @interface SpringBootConfiguration{}
    

    1,@SpringBootConfiguration

    1,作用和 @Configuration 相同,换个名子包装一下而已
    2,正因如此可以直接在启动类里使用 @Bean 直接定义 bean
    

    2,@EnableAutoConfiguration

    1,表示开启自动配置功能,简单说就是自动创建一些 bean
    2,@Configuration 和 @Compoment 等自己写的 bean 由 @AutoConfigurationPackage 实现
    3,别的需要的 bean 由 @Import(AutoConfigurationPackages.Registrar.class) 实现
    
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    @Import(AutoConfigurationImportSelector.class)
    public @interface EnableAutoConfiguration{}
    
    2.1,@AutoConfigurationPackage
    1,由 @Import(AutoConfigurationPackages.Registrar.class) 注解导入 Registrar 类
    2,Registrar 的作用是通过 registerBeanDefinitions 方法把启动类同级及子包的配置类(@Configure注解的类)加入到容器中
    
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @Import(AutoConfigurationPackages.Registrar.class) // 导入 Registrar 中注册的组件
    public @interface AutoConfigurationPackage {}
    
    // AutoConfigurationPackages.Registrar
    static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
        @Override
        public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
            // debug 模式断点可以发现 new PackageImports(metadata).getPackageNames() 是启动类所在的包路径
            register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
        }
        @Override
        public Set<Object> determineImports(AnnotationMetadata metadata) {
            return Collections.singleton(new PackageImports(metadata));
        }
    }
    
    2.2,@Import(AutoConfigurationImportSelector.class)
    • 将 AutoConfigurationImportSelector 导入到 spring 容器中
    • AutoConfigurationImportSelector 类作用
      是通过 selectImports 方法来导入组件
    • selectImports 方法使用内部工具类 SpringFactoriesLoader 加载 spring.factories 文件,spring.factories 就是所有能自动配置的类
    • 并不是所有的类都会配置,每个配置类都有 @ConditionalOnClass 注解,这个注解决定当前类是否自动配置,具体是判断当前类是否存在(导入了 maven 依赖就存在)
    // AutoConfigurationImportSelector.selectImports
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 调用 getAutoConfigurationEntry
        AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }
    
    // AutoConfigurationImportSelector.getAutoConfigurationEntry
    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 获取 EnableAutoConfiguration 注解的 exclude 和 excludeName 属性值
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 获取 spring.factories 中 EnableAutoConfiguration 的配置值,这些就是能自动配置的类(spring-boot-autoconfigure jar 下 META-INF/spring.factories)
        List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
        // 去重
        configurations = removeDuplicates(configurations);
        // 获取不自动装备的类,根据 EnableAutoConfiguration 注解值
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        // 检查不自动装备的类是否必须存在,如果是则抛出异常
        checkExcludedClasses(configurations, exclusions);
        // 这里才正式排除
        configurations.removeAll(exclusions);
        configurations = getConfigurationClassFilter().filter(configurations);
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
    

    3,@ComponentScan

    指定路径,@EnableAutoConfiguration 根据这里配置的路径进行扫描和排除,默认是启动类同级及其子包
  • 相关阅读:
    东南亚互联网创业哪些领域比较有前景?
    2021最新最实用.NET Core笔试题附答案
    2021UpdateC#.NET笔试题基础篇
    Ubuntu下 安装MiniGUI
    MiniGUI 如何显示繁体字
    Android 基础一 TextView,Style样式,Activity 传值,选择CheckBox 显示密码
    【玩转开源】BananaPi R2 —— 第一篇 Openwrt安装
    JAVA面对对象(二)——继承、方法的覆写
    JAVA面对对象(一)——封装
    JAVA关键字及作用
  • 原文地址:https://www.cnblogs.com/huanggy/p/15152390.html
Copyright © 2011-2022 走看看