• 后端——框架——容器框架——spring_boot——《官网》阅读笔记——第三章节3(使用SpringBoot)——核心配置


    1、自动注入

    1.1   原理

      当类上添加@SpringBootApplication注解时,就可以实现自动注入的功能,在第二章的末尾介绍它等价于@Configuration,@EnableAutoConfiguration,@ComponentScan注解。真正实现自动注入功能的是@EnableAutoConfiguration。

      查看@EnableAutoConfiguration的源码,发现它又等价于@AutoConfigurationPackage,并且引入了AutoConfigurationImportSelector对象。

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    @Import(AutoConfigurationImportSelector.class)
    public @interface EnableAutoConfiguration {
    
    	String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
    
    	/**
    	 * Exclude specific auto-configuration classes such that they will never be applied.
    	 * @return the classes to exclude
    	 */
    	Class<?>[] exclude() default {};
    
    	/**
    	 * Exclude specific auto-configuration class names such that they will never be
    	 * applied.
    	 * @return the class names to exclude
    	 * @since 1.3.0
    	 */
    	String[] excludeName() default {};
    }
    

      其中@AutoConfigurationPackage用于自动扫描相关的包。

      AutoConfigurationImportSelector中有个方法getCandidateConfigurations,它的调用栈为getCandidateConfiguration---->SpringFactoriesLoader.loadFactoryNames--->loadSpringFactories,查看loadSpringFactories代码如下:

    Enumeration<URL> urls = (classLoader != null ?
    		ClassLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
    		ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
    

      其中常量值为:

    public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
    

    它会加载spring-boot-autoconfiguration-version.jar包,META-INF目录下的spring.factories文件,这个文件就是spring boot自动注入的配置。

    1.2  禁用自动配置

      当想要禁用某个自动配置项时,在启动类的SpringBootApplication注解上添加exclude属性,它指定禁用的自动配置项,多个时使用逗号分割。示例如下:

    // 禁用了数据源的自动注入功能
    @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
    public class DemoApplication {
    	public static void main(String[] args) {
    		SpringApplication.run(DemoApplication.class, args);
    	}
    }
    

      效果如下:

    Exclusions:
    -----------
        org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
    

    2、配置信息

      在使用Spring时,有两种方式,XML方式,注解方式,它们都是在配置Bean,本质是将bean注入到IOC容器中。在spring boot有个很明显的变化,自动注入,它注入的这些bean虽然有默认值,但是遇到具体的需求,还是需要手动设置这些bean的值。

      例如日志框架logback,之前是添加一份logback.xml,logback框架会根据这份配置文件创建一些对象,如Logger,Appender,这些对象并不在IOC容器中。Spring boot项目自动检测logback相关依赖,存在便自动注入bean,如ConsoleAppender,它有默认的pattern属性值,当不满足我们的需求时,就需要手动配置这些信息。

      大部分的配置信息本质上都是给对象的属性赋值,我把它分为两类,

    1. 第一类为集成框架,框架核心对象的配置信息。
    2. 第二类为自定义的对象赋值。

      少部分的配置信息是给容器上下文中添加全局变量。

    2.1  定义配置信息

      Spring boot获取配置信息的方式和顺序如下,如果找到则不会再继续往下查找。

    1. Devtools global settings properties:略
    2. @TestPropertySource:略
    3. @SpringBootTest:略
    4. Command line arguments:命令行的参数
    5. spring.application.json:变量spring.application.json,它的值是一个JSON字符串
    6. ServletConfig:ServletConfig对象中的初始化参数
    7. ServletContext:ServletContext对象中的初始化参数
    8. JNDI:略
    9. System.getProperties:JVM的系统变量
    10. OS environment:操作系统的环境变量
    11. RandomValuePropertySource:随机数。
    12. Profile-specific outside of the package jar:它是指当前项目中的application-profile配置文件
    13.  Profile-specific inside of the package jar:它是指项目依赖的jar包下存在application-profile配置文件。
    14. Application outside of the package jar:当前项目中的applicaton配置文件。
    15. Application inside of the package jar:项目依赖的jar包下存在的application配置文件
    16.  @PropertySource:使用注解引入的xx.properties文件中定义的变量
    17.  SpringApplication.setDefaultProperties方法或SpringBootBuilder.properties方法。

      Spring的变量确实比较复杂,所以在编写时规范一些,使用一种方式即可。例如都写在xx.properties文件中,然后引入。

    2.1.1   命令行参数

      参考CommandLineRunner接口

    2.1.2   spring_application_json

      它的值是JSON字符串,会将JSON中所有变量添加到容器中,例如'{"user":{"name":"jack","age":20}}'会把user.name,user.age添加到容器中

      注:spring_application_json只有在命令行时才有效,在配置文件中无效

    2.1.3   系统变量

      系统变量有两种,操作系统的变量和JVM的系统变量,JVM也可以获取操作系统变量,调用System.getProperties方法即可,也可以向JVM中添加系统变量,调用System.setProperties。这些变量类似于全局变量,在程序的任何地方都可以获取,例如获取os.name系统变量,程序方式@Value("${os.name}"),配置文件中使用${os.name}。

    2.1.4   RandomValuePropertySource

      它的作用是为变量设置随机数(随机数不一定是数字,例如UUID),原著中的示例如下

    my.secret=${random.value}
    my.number=${random.int}
    my.bignumber=${random.long}
    my.uuid=${random.uuid}
    my.number.less.than.ten=${random.int(10)}
    my.number.in.range=${random.int[1024,65536]}
    

    2.1.5  配置文件

      配置文件分为两类,一类是名称有profile,另一类是无profile。

      查找无profile的配置文件分为两步:

    1. 第一步:首先需要找到配置文件存放的文件夹,它的默认查找步骤如下:
      • 首先查找current directory下的config子目录,其中current directory为项目的根路径。
      • 其次查找current directory目录。
      • 之后查找classpath下的config子目录,一般这个文件夹为resources/config
      • 最后查找classpath。

      2.第二步:查找配置文件名称,它的默认查找步骤如下:

      • 首先查找application.properties,
      • 其次查找application.yml。

      查找有profile的配置文件步骤不变,配置文件名变为application-{profile}.properties

      可以通过设置spring.config.location指定文件夹的路径,设置spring.config.name指定配置文件的名称。

      例如在resources下创建spring文件夹,配置文件名称为application-context.properties。

      需要指定如下配置

    --spring.config.location=classpath:/spring/
    --spring.config.name=application-context
    

      注:spring.config.name与spring.config.location写在配置文件中无效,可以设置为JVM变量或者是添加到命令行中

    2.1.6  @PropertySource

      是spring 框架的注解,功能是引入xx.properties文件,它有局限性,只在它标注的类上有效。例如多个@Configuration配置类上各自的@PropertySource只对自己有效。

    2.1.7  API

      调用SpringBuilder.setDefaultProperties或者SpringBootBuilder.properties方法。我感觉使用System.setProperties更好,JVM系统变量拥有更高的优先级。

    2.2   对象的属性(无前缀)

      当变量无前缀时,变量映射为属性遵循驼峰方式,例如userName属性,它会查找:

    1. user-name变量,
    2. user.name变量
    3. userName变量

      注:变量名是不区分大小写的。

      示例如下:

    • 第一步定义变量,我在application.properties中定义变量app.name=learn spring boot
    • 第二步在任何类中定义属性appName,在属性上添加@value注解
    @Value("${app.name}")
    private String appName;
    
    • 第三步验证,
    ********************
    项目名称是:learn spring boot
    

      它与类无关,只与属性的名称有关,极大可能会引起重名。

    2.3  对象的属性(有前缀)

      当变量有前缀时,首先前缀映射到具体的类,变量名去除前缀的部分映射为属性,例如需要为User类属性赋值

    1. 第一步,定义User类,拥有三个属性
    /**
     * 
     * @Title: User.java
     * @Package learn.spring.boot.bean
     * @Description: 用户类
     * @version V1.0
     */
    @Component
    @ConfigurationProperties(prefix = "test-user")
    public class User {
    	// 用户姓名
    	private String name;
    	// 用户地址
    	private String address;
    	// 用户年龄
    	private Integer age;
    	// get & set省略
    }

      2.第二步,定义变量,这里我单独定义了user.properties文件,并且通过@PropertySource引入,也可以直接定义在application.proerties文件中

    # user name
    testUser.name=Jack
    # user age
    testUser.age=20
    # user address
    testUser.address=some place
    

      3.第三步:通过ApplicationContext获取User对象

    // 获取用户对象
    ApplicationContext ac = builder.context();
    User user = ac.getBean("user",User.class);
    System.out.println("***********************");
    System.out.println("user Name:"+user.getName());
    System.out.println("user Age:"+user.getAge());
    System.out.println("user Address:"+user.getAddress());
    

      4.第四步:验证

    ***********************
    user Name:Jack
    user Age:20
    user Address:some place
    

      注:

    • 在设置对象属性时,不再使用@Value注解。
    • 需要深刻变量名与属性名之间的映射关系

    3、Profiles

      Profile指针对不同场景加载不同的配置文件,此时配置文件的名称默认为application-profile.properties。

      使用Profile有两个步骤,

      1. 创建application-{profile}.properties文件,本示例中创建application-test和application-production
      2. 激活profile。

      激活profile的方式有三种

      1. 第一种设置spring.profiles.active变量
      2. 第二种方式在启动类上添加@ActiveProfiles注解
      3. 第三种方式调用SpringBootBuilder的profiles方法。
  • 相关阅读:
    学会Git玩转Github笔记(一)——Github基本概念 & 仓库管理
    Github 入门基本操作
    Struts2拦截器浅析
    SSH(Struts2+Spring4+Hibernate4)框架教程之配置篇
    Spring 体系结构
    Ubuntu启动sshd服务
    jquery ajax/post 请求 案例
    Elasticsearch 配置
    Jenkins安装与配置
    解决Ubuntu环境变量错误导致无法正常登录  (command 'xxx' is available in bin ls)
  • 原文地址:https://www.cnblogs.com/rain144576/p/12498486.html
Copyright © 2020-2023  润新知