SpringBoot基础配置
准备工作
使用spring Initializr
构建工具构建一个SpringBoot的Web应用,名称为hellospringboot,之后在项目根目录中新建controller包,同时在该包内新建MyController
类,里面的代码为(忽略导包操作):
1 | @RestController |
然后运行启动类中的main方法,启动项目,在浏览器地址栏中输入http://localhosts:8080/hello
即可访问到该页面。
不使用spring-boot-starter-parent
入门篇说了在向pom.xml文件中添加依赖前需要先添加spring-boot-starter-parent
,而spring-boot-starter-parent
主要提供了如下默认的配置信息:1、Java版本默认使用1.8;2、编码格式默认使用UTF-8;3、提供Dependency Management进行项目依赖的版本管理;4、默认的资源过滤和插件配置。
spring-boot-starter-parent
虽然方便,但是如果你在公司在开发微服务项目或者多模块项目时需要使用自己公司的parent时,就无法进行项目依赖版本的统一管理了,不过你还是需要这个功能时,可以使用dependency Management
,毕竟spring-boot-starter-parent
之所以能进行依赖版本的管理,是因为它内嵌了这个dependency Management
。此时添加如下代码到pom.xml文件中:
1 | <!--不使用spring-boot-starter-parent时,然需要dependency Management时的代码--> |
此时就可以不继承spring-boot-starter-parent
,就具有了dependency Management,但是Java版本、编码格式等还得需要开发人员来手动配置。Java版本的配置非常简单,只需要添加一个plugin即可:
1 | <!--不使用spring-boot-starter-parent时,然需要手动进行Java版本的配置--> |
至于编码格式,如果使用了spring Initializr
构建工具构建的SpringBoot应用,那么编码格式默认会加上(默认为UTF-8)。如果你是通过普通的Maven项目配置而成的SpringBoot项目,那么需要在pom.xml文件中加入如下配置信息:
1 | <!--通过普通的Maven项目配置而成的SpringBoot项目,需要手动添加字符编码信息--> |
@SpringBootApplication注解
在入门篇你已经知道@SpringBootApplication
注解是加在项目启动类上面的,而实际上@SpringBootApplication是一个组合注解,你可以翻看源码进行阅读:
1 | @SpringBootConfiguration |
也就是说这个注解由三个注解组成。第一个是@SpringBootConfiguration
注解,它的定义如下:
1 | @Configuration |
原来这就是一个@Configuration,所以@SpringBootConfiguration的功能就是表明这是一个配置类,开发者可以在这个类中配置Bean。从这个角度来说,这个类其所扮演的角色有点类似于Spring中applicationContext.xml文件的角色。
第二个注解是@EnableAutoConfiguration,其实也很好理解,它表示开启自动化配置。SpringBoot中的自动化配置是侵入式的,在任意时刻开发者都可以使用自定义配置来代替自动化配置中的某一个配置。
第三个注解是@ComponentScan完成包扫描,也是Spring中的功能。由于@ComponentScan注解默认扫描的类都位于当前类所在的包的下面,因此建议在实际项目开发中把项目启动类放在根包中,如下图所示:
尽管项目的启动类中也包含@Configuration注解,但是开发者可以创建一个新的类专门用来配置Bean,这样便于配置的管理。这个类只需要加上@Configuration注解即可,举个例子来说:
1 | //com.envy.hellospringboot.config.MyConfig |
项目启动类中的@ComponentScan注解,除了扫描@Service、@Repository、@Component、@Controller和@RestController等注解之外,也会扫描@Configuration注解的类,因为它是组件扫描注解。
定制banner
接下来介绍一个非常好玩的东西,你可能注意到了SpringBoot项目在启动时会打印一个banner,如下图所示:
其实这个banner是可以定制的。在resources目录下创建一个banner.txt文件,然后在这个文件中写入的文本信息将会在项目启动时打印出来。如果想将TXT文本设置为艺术字体,可以使用以下几个在线网站:network-science、kammerl和patorjk。以第一个网站为例进行说明,按照图示操作进行,注意是将4中生成的文本复制到banner.txt文件中:
之后再重新启动项目,就会发现banner已经发生了变化:
当然了如果你想关闭banner也是可以的,只需要修改项目启动类的main方法,相关代码为:
1 | //关闭banner的方法 |
这里通过SpringApplicationBuilder
来设置bannerMode(mode为模式,model为模型单词不要搞错)为OFF,这样项目在启动的时候banner就自动消失了。
Web容器配置
Tomcat配置
1、常规配置。在SpringBoot项目中,可以内置Tomcat、Jetty、Undertow、Netty等容器。当开发者添加了spring-boot-starter-web
依赖后,默认会使用Tomcat作为Web容器。如果需要进一步对Tomcat进行配置,可以在application.properties配置文件中进行设置,代码如下:
1 | server.port=8081 |
接下来解释一下上述代码代表的各个含义:server.port配置了Web容器的端口号;.error.path配置了当项目出错时跳转去的页面;session.timeout配置了session的失效时间,此处为30m,代表30分钟,如果不写单位,那么默认单位为秒。请注意Tomcat中配置session过期时间以分钟为单位,因此这里单位如果是秒的话,该时间会被转换为一个不超过所配置秒数的最大分钟数。举个例子,如果这里配置了119,默认单位为秒,则实际session的过期时间为1分钟。context-path为表示项目的名称,如果你不配置则使用默认的/
,若配置了则在访问的路径中加上配置的路径。uri-encoding表示配置Tomcat的请求编码。max-threads表示Tomcat的最大线程数。basedir是一个存放Tomcat运行日志和临时文件的目录,如不配置,则默认使用系统的临时目录。当然了Web容器的相关配置有很多,这里列举的只是常用的配置,完整的配置可以点击 这里,进行阅读。在SpringBoot中,更推荐你使用application.yml文件来进行Web容器的属性配置,其实这只是提供了另一种层次感更强的配置方式而已:
1 | server: |
获取更多信息,推荐阅读 SpringBoot参考文档,里面详细介绍了SpringBoot相关信息。
2、HTTPS配置。众所周知HTTPS具有良好的安全性,因此在开发中越来越被广泛使用,尤其是在某些领域,像微信公众号、小程序等开发必须使用HTTPS。对于个人开发者而言, 一个HTTPS证书还是有些贵的,不过国内一些云服务器厂商提供了免费的HTTPS 证书, 一个账号可以申请数个,这一点在很大程度上做到了人手一个HTTPS证书。
其实你知道吗,Java已经提供了一个用于生成Java数字证书的管理工具keytool ,就在\jdk\bin
目录下:
通过这个工具且使用下面的命令,你可以生成自己的一个数字证书:
1 | keytool -genkey -alias tomcathttps -keyalg RSA -keysize 2048 -keystore sang.p12 -validity 365 |
先解释一下上述代码中的各个参数的含义:-genkey
表示要创建一个新的密钥;-alias
表示keystore的别名,此处设为tomcathttps;-keyalg
表示使用的是加密算法RSA,一种非对称加密算法;-keysize
表示密钥的长度;-keystore
表示生成的密钥存放的位置;-validity
表示密钥的有效时间,单位为天。
打开cmd窗口,直接运行上述命令,它会让你输入密钥口令等信息,只需根据输入提示即可(注意你cmd窗口在哪打开,它就在哪生成文件):
注意这里是输入“是”,不是直接回车。既然提示使用上面的代码语句进行迁移,那你就使用它迁移一下:
1 | keytool -importkeystore -srckeystore sang.p12 -destkeystore sang.p12 -deststoretype pkcs12 |
之后就会在cmd窗口目录下生成名为sang.p12
和sang.p12.old
这两个文件。你需要将这个sang.p12
文件复制到项目的根目录下(与pom.xml文件同级),接着在application.properties
配置文件中进行设置:
1 | server.ssl.key-store=sang.p12 |
同样解释一下上述代码中的各个参数的含义:key-store
表示密钥文件名称;key-alias
表示密钥文件的别名;key-store-password
就是你在cmd命令执行过程中输入的密码;key-store-type
表示密钥文件的存储方式为PKCS12。
接下来启动项目,在浏览器地址栏中输入https://localhosts:8081/hellospringboot/hello
:
点击继续,即可访问到预设的信息:
如果你使用了http://localhosts:8081/hellospringboot/hello
链接来访问的话,页面会出下面的情况:
这是因为SpringBoot不支持同时在配置中启动HTTP和HTTPS 。这个时候可以配置请求重定向,将HTTP请求重定向为HTTPS请求。新建一个config类,接着在里面新建一个TomcatConfig类,里面的代码为:
1 | package com.envy.hellospringboot.config; |
这里首先配置一个TomcatServletWebServerFactory ,然后添加一个Tomcat 中的Connector(监听8080端口) 并将请求转发到8081上去。配置完成后,在浏览器中输入http://localhost:8080/hellospringboot/hello
就会自动重定向到https://localhost:8081/hellospringboot/hello
。请注意此时我们在application.properties中配置的server.port为8081没有变化。
如果在上述过程中出现跳转到https://localhost:8081/hellospringboot/hello
后无法访问的情况,同时IDEA出现下面的情况:
你需要将Tomcat版本降低到9.0.12版本,你只需要在pom.xml文件中进行配置,然后重新import即可:
1 | <properties> |
Jetty设置
Jetty是一个开源的servlet容器,它为基于Java的web容器,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立运行(stand-alone)的Java应用提供网络和web连接。
除了Tomcat之外,也可以在SpringBoot中嵌入Jetty,首先你需要在pom.xml文件中引入jetty:
1 | <!--引入Jetty容器,但前提是需要将Web容器内的Tomcat去除掉--> |
上面代码的意思就是从spring-boot-starter-web
中除去默认的Tomcat,然后加入Jetty的依赖,如果你想正常运行的话,需要将前面配置的TomcatConfig类注释掉,因为此时SpringBoot内已经没有Tomcat容器了。
Undertow配置
Undertow是红帽公司开源的一款基于NIO 的高性能Web嵌入式Java服务器,具有非常好的性能,在SpringBoot中也得到了很好的支持,配置方式和Jetty类似。虽然SpringBoot内嵌Jetty、Tomcat和Undertow,但是默认是Tomcat,因此使用其他两个就需要先去除Tomcat,然后进行依赖安装:
1 | <!--引入Undertow容器,但前提是需要将Web容器内的Tomcat去除掉--> |
Properties配置
SpringBoot中采用了大量的自动化配置,但是在实际开发过程中有些配置,像数据库信息等这些依然还是要开发者自己动手来配置,承载这些自定义配置的文件就是resources目录下的application.properties
文件(前面说过也可以使用application.yml来代替)。前面介绍的只是application.properties
配置的基本用法,接下来将对其作进一步的说明。SpringBoot项目中的application.properties
配置文件一共可以出现在如下4个位置:
序号1表示项目根目录config文件夹中;序号2表示项目根目录中;序号3表示classpath下的config文件夹中;序号4表示classpath中。(classpath就是resources目录下)。如果这4个位置都有application.properties
配置文件,那么加载的优先级从1到4依次降低,SpringBoot会按照这个优先级查找配置信息,并加载到SpringEnvironment中。当然如果你使用了application.yml作为配置文件,这个优先级还是一样的。一般我们都是采用序号4的位置。
默认情况下SpringBoot按照前面说的顺序依次去加载application.properties
配置文件。如果开发者不想使用application.properties
作为配置文件的名称,又或者说想自定义配置文件的名称,这也是可以的。举个例子来说,假设你想在resources目录下新建一个app.properties
作为配置文件,然后使用maven install命令将其打包为jar包,之后就可以使用下面的命令来运行该jar包了:
1 | java -jar hellospringboot-SNAPSHOPT.jar --spring.config.name=app |
当然上面运行是有条件的,就是生成的jar包必须和app.properties
配置文件在同一目录中。其实你还可以在命令行中指定app.properties
配置文件的位置,这样就不受目录同级的限制了:
1 | java -jar hellospringboot-0.0.1-SNAPSHOT.jar --spring.config.name=app --spring.config.location=classpath:/ |
类型安全配置属性
其实这个在《两小时入门SpringBoot基础篇》内就已经介绍过它的用法了,但是这里还是觉得有必要需要拿出来介绍。
前面说过无论是使用properties配置,还是yaml配置,最终都会被加载到Spring Environment中。Spring提供了@Value注解以及EnvironmentAware接口来将Spring Environment中的数据注入到属性上,SpringBoot对此进一步提出了类型安全配置属性(Type-Safe Configuration Properties)这样即使在配置信息量非常大的情况下,也能更加方便的将配置文件中的数据注入到Bean中。
举一个例子来说,在application.properties
配置文件中添加如下一段配置:
1 | person.name=思录 |
接着在com.envy.hellospringboot包内新建一个config包,在里面新建一个PersonConfig配置类,往其中新增如下代码:
1 | package com.envy.hellospringboot.config; |
解释一下上面代码中两个注解的含义:1、@Component注解表示该类会自动被Spring容器所管理;2、@ConfigurationProperties(prefix = “person”)注解表示该类为一个属性配置类,prefix属性用于描述要加载的配置文件的前置,这里是person。如果配置文件是一个yaml文件,那么你可以将数据注入到一个集合中,后面会介绍。
SpringBoot采用了一种宽松的规则来进行属性绑定,如果Bean中的属性名称为firstName,那么配置文件中的属性可以为person.first_name、person.first_name、person.firstName又或者是person.FIRSTNAME。同时别忘了在settings中进行文件编码格式的修改,否则会出错。
注意如果在文件上方出现了如下提示:
那么你需要在pom.xml文件中添加spring-boot-configuration-processor
依赖:
1 | <dependency> |
最后在controller包内新建一个PersonController类,用于进行属性测试:
1 | package com.envy.hellospringboot.controller; |
然后按照下图进行项目文件编码格式的修改(序号5右侧的Transparent native-to也勾选一下):
然后启动项目,在浏览器地址栏中输入https://localhost:8081/hellospringboot/person
,即可访问到该页面信息:
YAML配置
常规配置
YAML是JSON的超集,简介而强大,是一种专门用来书写配置文件的语言,可以代替application.properties
。在创建一个SpringBoot项目时,引入的spring-boot-starter-web
依赖时其实也间接地引入了snakeyaml依赖,snakeyaml会实现对YAML配置的解析。YAML的使用非常简单,利用缩进来表示层级关系,且对大小写敏感。在SpringBoot项目中使用YAML只需要在resources目录下创建一个application.yml
文件即可,然后往里面新加以下代码:
1 | server: |
前面也说过了,其实它就相当于你在application.properties
文件中添加的如下代码的作用:
1 | server.port=8081 |
这时候就可以将resources目录下的application.properties
文件删除,完全使用YAML来完成文件的配置。(记得将其中的ssl配置也写到yaml文件里)
复杂配置
(1)YAML文件不仅可以配置一些常规的属性,同样也能和properties一样配置一下较为复杂的属性。还是以前面举过的Person例子来进行说明。在application.yml
文件中新增以下代码:
1 | # person属性设置 |
同样也需要像properties一样,在config包内新建一个PersonConfig类,里面的代码和它完全一样这里就不再重复粘贴了,后续步骤也是完全一样。
(2)YAML还支持列表的配置,例如下面的一组配置:
1 | # person属性设置 |
那么你在config包中的PersonConfig类也需要进行修改:
1 | @Component |
(3)YAML还支持更加复杂的配置,即集合中也可以是一个对象,将对象内嵌到集合中,例如下面的一组配置:
1 | test: |
那么你在config包中的PersonConfig类也需要进行修改:
1 | package com.envy.hellospringboot.config; |
在SpringBoot中使用YAML虽然很方便,但是YAML也有一些缺陷,例如无法使用@PropertySource注解以来加载YAML文件,当你项目中有这种需求的时候,建议还是使用Properties格式的配置文件。
Profile
Profile这个非常重要,开发者在项目发布之前,一般都需要频繁的在开发环境,测试环境以及生产环境之间进行切换,这个时候大量的配置需要频繁修改,如数据库配置,Redis配置,MongoDB配置,JMS配置等。频繁修改带来了巨大的工作量,Spring对此提供了解决方案(@Profile注解),而在SpringBoot中则更进一步提供了更加简洁的解决方案,SpringBoot的理念是约定大于配置,它约定在不同的环境下配置文件名称按照如下规则:application-{profile}.properties
,其中的profile占位符表示当前环境的名称,具体配置步骤如下:
(1)创建配置文件。首先你需要在resources目录下创建两个配置文件:application-dev.properties
和application-prod.properties
,分别表示开发环境和生产环境中的配置。其中application-dev.properties
文件的内容如下所示:
1 | server.port=8080 |
而application-prod.properties
文件的内容如下所示:
1 | server.port=80 |
这里仅仅是通过两个配置文件中项目端口的不同来说明页面效果。
(2)配置application.properties
文件。你只需要在application.properties
文件中添加一行代码spring.profiles.active=dev
,即可,这行代码的意思就是表示使用application-dev.properties
配置文件来启动项目,如果将dev修改为prod,则表示使用生产配置文件application-prod.properties
来启动项目。之后就可以使用相应的端口来进行项目访问了。
(3)在代码中配置。对于第二步在application.properties
文件中添加的配置,其实你完全可以通过在代码中添加配置来实现,只需要在项目启动类的main方法上添加如下代码,这样就可以替换第二步的配置:
1 | //在代码中选择使用的环境类型 |
(4)项目启动时配置。对于第2步和第3步提到的两种配置方式,其实你可以在将项目打包成为jar包后启动时,在命令行中通过代码来指定运行的环境类型:
1 | java -jar hellospringboot-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod |
基础配置小结
本篇主要学习了SpringBoot中常见的基础性配置,包括依赖管理的多种方式,如入口类注解,banner定制,Web容器配置,Properties配置和YAML配置等,这些配置是后续学习的基础。