SpringBoot--实战开发--配置(三)

作者: 无剑_君 | 来源:发表于2019-05-05 15:08 被阅读129次

    一、SpringBoot配置文件

    相信很多人选择Spring Boot主要是考虑到它既能兼顾Spring的强大功能,还能实现快速开发的便捷。我们在Spring Boot使用过程中,最直观的感受就是没有了原来自己整合Spring应用时繁多的XML配置内容,替代它的是在pom.xml中引入模块化的Starter POMs,其中各个模块都有自己的默认配置,所以如果不是特殊应用场景,就只需要在application.properties中完成一些属性配置就能开启各模块的应用。

    二、自定义属性与加载

    我们在使用Spring Boot的时候,通常也需要定义一些自己使用的属性:

    com.neuedu.name=neuedu
    com.neuedu.title=东软睿道
    
    1. 然后通过@Value("${属性名}")注解来加载对应的配置属性:
    @RestController
    public class UserController {
    
        @Value("${com.neuedu.name}")
        private String name;
        @Value("${com.neuedu.title}")
        private String title;
    
        @GetMapping("/getListUser")
        public List<User >getUser() {
            List<User> users = new ArrayList<User>();
            User user = new User();
            user.setId(2);
            user.setPassword("123456");
            user.setUsername("光头强");
            users.add(user);
            System.out.println(name+":"+title);
            return users;
        }
    }
    
    1. 使用@ConfigurationProperties 读取多个属性
      1)读取属性值
    @Component
    @ConfigurationProperties(prefix = "com.neuedu.user")
    public class User {
        private Integer id;
        private String username;
        private String password;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    }
    
    
    1. 控制器测试
    @RestController
    public class UserController {
    
        @Autowired
        private User user;
    
        @GetMapping("/getUser")
        public User getUser() {
            return user;
        }
    }
    

    3)关于@ConfigurationProperties和@Value的区别
    关于两者的简单功能对比:

    特性 @ConfigurationProperties @Value
    松绑定 Yes No
    元数据(Meta-data ) Yes No
    支持SpringEL No Yes

    显然,前者支持松绑定的特性更强大,所以在实际开发中建议使用@ConfigurationProperties来读取自定义属性。

    三、参数间的引用

    在application.properties中的各个参数之间也可以直接引用来使用,就像下面的设置:

    com.neuedu.desc=${com.neuedu.name}就是${com.neuedu.title}
    

    四、使用随机数

    在一些情况下,有些参数我们需要希望它不是一个固定的值,比如密钥、服务端口等。Spring Boot的属性配置文件中可以通过${random}来产生int值、long值或者string字符串,来支持属性的随机值。

    # 随机字符串
    com.neuedu.value=${random.value}
    # 随机int
    com.neuedu.number=${random.int}
    # 随机long
    com.neuedu.bignumber=${random.long}
    # 10以内的随机数
    com.neuedu.test1=${random.int(10)}
    # 10-20的随机数
    com.neuedu.test2=${random.int[10,20]}
    

    五、通过命令行设置属性值

    命令:java -jar xxx.jar --server.port=8888,通过使用–server.port属性来设置xxx.jar应用的端口为8888。
    在命令行运行时,连续的两个减号--就是对application.properties中的属性值进行赋值的标识。所以,java -jar xxx.jar --server.port=8888命令,等价于我们在application.properties中添加属性server.port=8888,该设置在样例工程中可见,读者可通过删除该值或使用命令行来设置该值来验证。
    通过命令行来修改属性值固然提供了不错的便利性,但是通过命令行就能更改应用运行的参数,那岂不是很不安全?是的,所以Spring Boot也贴心的提供了屏蔽命令行访问属性的设置,只需要这句设置就能屏蔽:

     SpringApplication application = new SpringApplication(SpringbootDevPracticeApplication.class);
            //屏蔽命令行访问属性的设置
            application.setAddCommandLineProperties(false);
            application.run(SpringbootDevPracticeApplication.class, args);
    

    六、多环境配置

    我们在开发Spring Boot应用时,通常同一套程序会被应用和安装到几个不同的环境,比如:开发、测试、生产等。其中每个环境的数据库地址、服务器端口等等配置都会不同,如果在为不同环境打包时都要频繁修改配置文件的话,那必将是个非常繁琐且容易发生错误的事。

    对于多环境的配置,各种项目构建工具或是框架的基本思路是一致的,通过配置多份不同环境的配置文件,再通过打包命令指定需要打包的内容之后进行区分打包,Spring Boot也不例外,或者说更加简单。

    在Spring Boot中多环境配置文件名需要满足application-{profile}.properties的格式,其中{profile}对应你的环境标识,比如:

    application-dev.properties:开发环境
    application-test.properties:测试环境
    application-prod.properties:生产环境

    至于哪个具体的配置文件会被加载,需要在application.properties文件中通过spring.profiles.active属性来设置,其值对应{profile}值。
    如:spring.profiles.active=test就会加载application-test.properties配置文件内容
    下面,以不同环境配置不同的服务端口为例,进行样例实验。

    针对各环境新建不同的配置文件
    application-dev.properties、application-test.properties、application-prod.properties

    在这三个文件均都设置不同的server.port属性,如:
    dev环境设置为1111,test环境设置为2222,prod环境设置为3333

    application.properties中设置spring.profiles.active=dev,就是说默认以dev环境设置
    测试不同配置的加载。

    执行java -jar xxx.jar,可以观察到服务端口被设置为1111,也就是默认的开发环境(dev)
    执行java -jar xxx.jar --spring.profiles.active=test,可以观察到服务端口被设置为2222,也就是测试环境的配置(test)
    执行java -jar xxx.jar --spring.profiles.active=prod,可以观察到服务端口被设置为3333,也就是生产环境的配置(prod)
    按照上面的实验,可以如下总结多环境的配置思路:
    application.properties中配置通用内容,并设置spring.profiles.active=dev,以开发环境为默认配置。
    application-{profile}.properties中配置各个环境不同的内容。
    通过命令行方式去激活不同环境的配置。

    七、默认加载路径

    SpringBoot 默认会加载这些路径加载核心配置文件,按优先级从高到低进行排列:具体规则详见 ConfigFileApplicationListener
    工程根目录的config目录:file:./config/
    工程根目录:file:./
    类路径的config目录:classpath:/config/
    类路径:classpath:/ (推荐使用)


    默认加载路径

    如果存在多个配置文件,则严格按照优先级进行覆盖,最高者胜出:
    举个简单的例子,例如再上述位置都有一个application.properties ,并且每个文件都写入了server.port=xx (xx分别是9001,9002,9003,9004),在启动成功之后,最终应用的端口为:9004。


    工程顶层目录

    如果想修改默认的加载路径 或者 调改默认的配置文件名,我们可以借助命令行参数进行指定,例如:

    java -jar demo.jar --spring.config.name=app --spring.config.location=classpath:/myconfig/
    

    注:不管 spring.config.location 配置什么值,默认总会按照 classpath:,classpath:/config,file:,file:config/ 的顺序进行搜索,优先级由低到高,也就是 file:config/ 获胜。如果你指定自己的位置,它们会优先于所有的默认位置,并使用相同的由低到高的优先级顺序。

    1. Banner修改:
      http://patorjk.com/software/taag/#p=display&f=Graffiti&t=Type%20Something%20
    @SpringBootApplication
    public class SpringbootDevPracticeApplication {
    
        public static void main(String[] args) {
            SpringApplication application = new SpringApplication(SpringbootDevPracticeApplication.class);
            // Banner.Mode.OFF:关闭;
            // Banner.Mode.CONSOLE:控制台输出,默认方式;
            // Banner.Mode.LOG:日志输出方式;
            application.setBannerMode(Banner.Mode.OFF);
            application.run(args);
        }
    }
    
    

    在resource目录下面放入一个banner.txt文件,Spring Boot启动项目的时候就会优先启动这个文件中的内容。注意,不止在war包或者Fat Jar的resource目录放置会起效果,在任一插件的resource目录放置也可以生效。当然这里涉及到一个优先级的问题,在war包或Fat Jar中放置的优先级高于插件jar包的。

    1. 读取版本信息:
      在src/main/resouces下新建banner.txt,在文件中加入:
    #设置控制台中输出内容的颜色
    ${AnsiColor.BRIGHT_RED}    
    #这个是MANIFEST.MF文件中的版本号
    ${application.version}
    #这个是上面的的版本号前面加v后上括号
    ${application.formatted-version}
    #这个是springboot的版本号
    ${spring-boot.version}
    #这个是springboot的版本号
    ${spring-boot.formatted-version}
    
    1. 在application.properties进行配置
    ### 是否显示banner,可选值[true|false]
    spring.main.banner-mode = off
    

    示例:

    ${AnsiColor.BRIGHT_YELLOW}
    ////////////////////////////////////////////////////////////////////
    //                          _ooOoo_                               //
    //                         o8888888o                              //
    //                         88" . "88                              //
    //                         (| ^_^ |)                              //
    //                         O\  =  /O                              //
    //                      ____/`---'\____                           //
    //                    .'  \\|     |//  `.                         //
    //                   /  \\|||  :  |||//  \                        //
    //                  /  _||||| -:- |||||-  \                       //
    //                  |   | \\\  -  /// |   |                       //
    //                  | \_|  ''\---/''  |   |                       //
    //                  \  .-\__  `-`  ___/-. /                       //
    //                ___`. .'  /--.--\  `. . ___                     //
    //              ."" '<  `.___\_<|>_/___.'  >'"".                  //
    //            | | :  `- \`.;`\ _ /`;.`/ - ` : | |                 //
    //            \  \ `-.   \_ __\ /__ _/   .-` /  /                 //
    //      ========`-.____`-.___\_____/___.-`____.-'========         //
    //                           `=---='                              //
    //      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
    //                  佛祖保佑       永不宕机     永无BUG           //
    ////////////////////////////////////////////////////////////////////
    

    八、 bootstrap配置文件
    在 Spring Boot 中有两种上下文,一种是 bootstrap, 另外一种是 application, bootstrap 是应用程序的父上下文,也就是说 bootstrap 加载优先于 applicaton。bootstrap 主要用于从额外的资源来加载配置信息,还可以在本地外部配置文件中解密属性。这两个上下文共用一个环境,它是任何Spring应用程序的外部属性的来源。bootstrap 里面的属性会优先加载,它们默认也不能被本地相同配置覆盖。
    因此,对比 application 配置文件,bootstrap 配置文件具有以下几个特性。
    boostrap 由父 ApplicationContext 加载,比 applicaton 优先加载
    boostrap 里面的属性不能被覆盖
    通过设置spring.cloud.bootstrap.enabled=false(例如,在系统属性中),可以完全禁用引导过程。

    1.加载顺序
    这里主要是说明application和bootstrap的加载顺序。
    bootstrap.yml(bootstrap.properties)先加载application.yml(application.properties)后加载
    bootstrap.yml 用于应用程序上下文的引导阶段。
    bootstrap.yml 由父Spring ApplicationContext加载。
    父ApplicationContext 被加载到使用 application.yml 的之前。
    2.配置区别
    bootstrap.yml 和application.yml 都可以用来配置参数。
    bootstrap.yml 可以理解成系统级别的一些参数配置,这些参数一般是不会变动的。
    application.yml 可以用来定义应用级别的,如果搭配 spring-cloud-config 使用 application.yml 里面定义的文件可以实现动态替换。

    1. bootstrap/ application 的应用场景
      application 配置文件这个容易理解,主要用于 Spring Boot 项目的自动化配置。
      bootstrap 配置文件有以下几个应用场景。
      使用 Spring Cloud Config 配置中心时,这时需要在 bootstrap 配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息;
      一些固定的不能被覆盖的属性
      一些加密/解密的场景;

    需要和Spring Cloud 的组件结合——只有加上Spring Cloud Context依赖才能生效。

    八、常见问题:

    1. 控制台乱码问题:
      找到idea.exe.vmoption与idea64.exe.vmoptions文件,打开,在最后一行填加:
      -Dfile.encoding=UTF-8
    2. 配置文件读取中文乱码
    server.tomcat.uri-encoding=UTF-8
    spring.http.encoding.charset=UTF-8
    spring.http.encoding.enabled=true
    spring.http.encoding.force=true
    spring.messages.encoding=UTF-8
    
    配置文件读取中文乱码
    1. 不显示彩色日志
      -Dspring.output.ansi.enabled=ALWAYS


      显示彩色日志
      显示彩色日志

    相关文章

      网友评论

        本文标题:SpringBoot--实战开发--配置(三)

        本文链接:https://www.haomeiwen.com/subject/tymfoqtx.html