【Spring Boot 基础配置】
一、不使用spring-boot-starter-parent
? spring-boot-starter-parent虽然方便,但是在公司开发微服务项目或者多模块项目时一般需要使用自己公司的parent,这个时候如果还想进行项目依赖版本的统一管理,就需要使用dependencyManagement来实现了。添加如下代码到pom.xml文件中
<dependencyManagement>
<dependencies>
<denpendency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-denpendencies</artifactId>
<version>2.0.4.RELEASE</version>
<type>pom</type>
<scopo>import</scopo>
</denpendency>
</dependencies>
</dependencyManagement>
? 此时,就可以不用继承spring-boot-starter-parent了,但是Java的版本,编码的格式都需要开发者手动配置。Java版本的配置很简单,添加一个plugin即可。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
二、@SpringBootApplication
我们知道@Spring BootApplication注解是加在项目启动类上的。@SpringBootApplication实际上是一个组合注解,定义如下:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
1、@SpringBootConfiguration
本质上就是一个@Configuration。所以其功能就是表明这是一个配置类,开发者可以在这个类中配置Bean。有点类似于Spring中applicaionContext.xml文件的角色。
2、@EnableAutoConfiguration
表示开启自动化配置,SpringBoot中的自动化配置是非侵入式的,在任意时刻,开发者都可以使用自定义配置代替自动化配置中的某一个配置。
3、@ComponentScan
完成包的扫描,也是Spring中的功能。由于@ComponentScan注解默认扫描的类都位于当前类所在包的下面,因此建议在实际项目开发中把启动类放在根包中!!
4、自定义配置Bean
虽然项目的启动类也包含@Configuration注解,但是开发者可以创建一个新的类专门用来配置Bean,这样便于配置的管理。这个类只需要加上@Configuration注解即可,代码如下:
@Configuration
public class MyConfig{
}
项目启动类中的@ComponentScan注解,除了扫描@Service、@Repository、@Component、@Controller和@RestController等之外,也会扫描@Configuration注解的类。
三、Tomcat配置
1、常规配置
? SpringBoot中,可以配置Tomcat、Jetty、Undertow、Netty等容器。当开发者添加了spring-boot-starter-web依赖之后,默认会使用Tomcat作为Web容器。如果需要对Tomcat做进一步的配置,可以在application.properties中进行配置,代码如下:
server.port=8081
server.error.path=/error
server.servlet.session.timeout=30m
server.servlet.context-path=/chapter02
server.tomcat.uri-encoding=utf-8
server.tomcat.threads.max= 500
server.tomcat.basedir=/hom/sang/tmp
- error.path配置类当项目出错时跳转去的页面
- session.timeout配置了session失效时间,如果不写单位,默认是秒,m是分钟。
- context-path表示项目名称,不配置时默认为/,配置了,就要在访问路径中加上配置的路径。
- threads.max表示配置Tomcat最大线程数。
- basedir是一个存放Tomcat运行日志和临时文件的目录,不配置就使用系统的临时目录。
2、HTTPS配置
国内有一些云服务器厂商提供免费的HTTPS证书,一个账号可以申请数个。不过在JDK中提供了一个Java数字证书管理工具keytool,在\jdk\bin目录下,通过这个工具可以自己生成一个数字证书,生成命令如下:
keytool -genkey -alias tomcathttps -keyalg RSA -keysize 2048 -keystore sang.p12 -validity 365
命令解释:
- -genkey表示要创建一个新的密钥
- -alias表示keystore的别名
- -keyalg表示使用的加密算法是RSA
- -keysize表示密钥的长度
- -keystore表示生成的密钥存放位置
- -validity表示密钥的有效时间
cmd执行上述命令,根据提示输入即可。在当前目录下生成sang.p12的文件,将这个文件复制到项目的根目录下,然后在application.properties中做如下配置:
server.ssl.key-store=sang.p12
server.ssl.key-alias=tomcathttps
server.ssl.key-store-password=123456
代码解释:
- key-store-password就是在cmd命令执行过程中输入的密码
若以http访问:
这是因为SpringBoot不支持同时在配置中启动HTTP和HTTPS。这个时候可以配置请求重定向,将HTTP请求重定向为HTTPS请求。配置方式如下:
编写自定义配置类
package com.darkerg.helloworld.config;
import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class TomcatConfig {
@Bean
TomcatServletWebServerFactory tomcatServletWebServerFactory(){
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(){
@Override
protected void postProcessContext(Context context){
SecurityConstraint constraint = new SecurityConstraint();
constraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
context.addConstraint(constraint);
}
};
factory.addAdditionalTomcatConnectors(createTomcatConnector());
return factory;
}
private Connector createTomcatConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(8080);
connector.setSecure(false);
connector.setRedirectPort(8081);
return connector;
}
}
? 这里首先配置一个TomcatServletWebServerFactory,然后添加一个Tomcat中的Connector(监听8080端口),并将请求转发到8081上去。
? 配置完成之后,在浏览器中输入 “http://localhost:8080/chapter02/hello”,就会自动重定向到http://localhost:8081/chapter02/hello上面去。
3、Jetty配置和Undertow配置
4、Properties配置
SpringBoot项目中的application.properties配置文件可以出现在下面4个位置:
- 项目根目录下的config文件夹中
- 项目根目录下
- classpath下的config文件夹中(resources)
- classpath下
并且这也是加载的优先级,SpringBoot将按照这个优先级查找配置信息,并加载到Spring Environment中。
5、类型安全配置属性
Spring提供了@Value注解以及EnvironmentAware接口来将Spring Environment中的数据注入到属性上,SpringBoot对此进一步提出了类型安全配置属性(Type-safe-ConfigurationProperties),这样即时在数据量非常庞大的情况下,也可以更加方便地将配置文件中的数据注入Bean中。考虑在application.properties中添加如下配置:
book.name=三国演义
book.author=罗贯中
book.price=30
将这一段配置注入如下Bean中:
@Component
@ConfigurationProperties(prefix = "book")
public class Book {
private String name;
private String author;
private Float price;
//省略getter/setter
}
代码解释:
- @ConfigurationProperties中的prefix属性描述了要加载的配置文件的前缀
- 如果配置文件是一个YAML文件。那么可以将数据注入到一个集合中。
- Spring Boot采用了一种宽松的规则来进行属性绑定,如果Bean中的属性名为authorName,那么配置文件中的属性可以是book.author_name、book.author-name、book.authorName或者book.AUTHORNAME。
修改编码
最后创建BookController进行简单测试
@RestController
public class BookController {
@Autowired
Book book;
@GetMapping("/book")
public String book(){
return book.toString();
}
}
6、YAML配置
①常规配置
YAML是JSON的超集,简洁而强大,是一种专门书写配置文件的语言,可以替代application.properties。在创建一个SpringBoot项目时,引入的spring-boot-starter-web依赖间接地引入了snakeyaml依赖,snakeyaml会实现对YAML配置的解析。YAML的使用非常简单,利用缩进来表示层级关系,并且大小写敏感。在SpringBoot项目中使用YAML只需要在resources目录下创建一个application.yml文件即可,然后向application.yml中添加如下配置:
server:
port: 80
servlet:
context-path: /chapter02
tomcat:
uri-encoding: utf-8
此时可以将resources目录下的application.properties文件删除,完全使用YAML完成文件的配置。
②复杂配置
? YAML不仅可以配置常规属性,也可以配置复杂属性,例如下面一组配置:
my:
name: 北京
address: China
如上面,这样也可以注入到一个Bean中。
? YAML还支持列表的配置,例如下面的一组配置:
my:
name: 北京
address: China
favorites:
- 足球
- 徒步
- Coding
注入到Bean中,需要添加
private List<String> favorites;
? 更复杂的配置,即集合中也可以是一个对象,如下:
my:
users:
- name: darkerg
address: China
favorites:
- 足球
- 徒步
- Coding
- name: darkerg2
address: China
favorites:
- 阅读
- 吉他
注入:
User.java
import lombok.Data;
import java.util.List;
@Data
public class User {
private String name;
private String address;
private List<String> favorites;
}
Users.java
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@Data
@ConfigurationProperties(prefix = "my")
public class Users {
private List<User> Users;
}
YAML虽然方便,但是YAML也有一些缺陷,例如无法使用@PropertySource注解加载YAML文件。
7、Profile
? 开发者在项目发布之前,一般需要频繁地在开发环境、测试环境以及生产环境之间进行切换,这个时候大量的配置需要频繁更改,例如数据库配置、redis配置、mongodb配置、jms配置等。频繁修改带来了巨大的工作量,Spring对此提供了解决方案(@Profile注解),SpringBoot则更进一步提供了更加简洁的解决方案,SpringBoot中约定的不同环境下配置文件名称规则为application-{profile}.properties,profile占位符表示当前环境的名称,具体配置步骤如下:
①创建配置文件
? 首先在resources目录下创建两个配置文件:application-dev.properties 和 application-prod.properties,分别表示开发环境中的配置和生产环境中的配置。
其中,application-dev.properties文件的内容:
server.port=8080
? application-prod.properties文件的内容如下:
server.port=80
②配置application.properties
然后在application.properties中进行配置
spring.profiles.active=dev
③在代码中配置
在启动类的main方法上添加如下代码,可以代替第二步。
@SpringBootApplication
public class HelloworldApplication {
public static void main(String[] args) {
SpringApplicationBuilder builder = new SpringApplicationBuilder(HelloworldApplication.class);
builder.application().setAdditionalProfiles("prod");
SpringApplication.run(HelloworldApplication.class, args);
}
}
④项目启动时候配置
? 也可以将项目打包成jar包启动时候,命令行:
java -jar xxx.jar --spring.profiles.active=prod