大纲
这一篇总结springboot的运行环境定制, 总结了如下知识:
- springboot如何切换开发/测试/生产环境
- 需要加的配置类或annoation, 包括tomcat/mongodb
开发环境/生产环境的切换
软件产品的运行环境至少应该包括三个: 开发环境, 内部测试环境和正式产品环境. 本地测试环境是程序员开发时候的环境, 内部测试环境是程序员开发完毕, 放到内网只允许测试人员测试的环境, 等所有测试完毕, 再把代码和数据部署到正式环境. (有些大公司还包括多个内部测试环境用于严格测试, 但技术都是共通的, 掌握之后自己再加运行环境很简单)
配置文件
在resources目录下加入4个配置文件, 如下:
这4个配置文件的作用是:
- application.properties : 放置两个环境共用的参数, 并且拥有切换配置文件的变量.
- application-dev.properties: 放置开发环境的参数
- application-test.properties: 放置测试环境的参数
- application-prod.properties: 放置产品环境的参数
在 application.properties 加入如下参数:
spring.profiles.active=dev # 表示默认使用开发环境配置
myapp.port = 17010 # 定制tomcat的端口
在 application-dev.properties 加入如下参数. 这个是vue的域参数, 后续会用到:
vue.domain = http://localhost:17000
在 application-test.properties 加入如下参数:
vue.domain = http://test.domain:17000
在 application-prod.properties 加入如下参数:
vue.domain = http://111.222.333.444:17000
如何使用
新增一个 MyAppConfig.java 类, 代码如下:
package org.diego.springvue;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* 读取各种配置
* @author cys
*
*/
@Component
public class MyAppConfig {
@Value("${myapp.port}")
int appPort;
@Value("${vue.domain}")
String vueDomain;
public int getAppPort() {
return appPort;
}
public void setAppPort(int appPort) {
this.appPort = appPort;
}
public String getVueDomain() {
return vueDomain;
}
public void setVueDomain(String vueDomain) {
this.vueDomain = vueDomain;
}
}
然后在junit测试目录新增一个测试类, 如下:
package org.diego.springvue;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ConfigTests {
@Autowired
MyAppConfig config;
@Test
public void test() {
System.out.println("=================== tomcat port: " + config.getAppPort());
System.out.println("=================== vue domain: " + config.getAppPort());
}
}
别忘了启动你的mongodb服务器. 然后运行这个测试类, 就可以看到这个输出结果:
切换环境
上面的代码只是确定了配置环境变量可以被读取, 还没有证明springboot如何切换. 所以我们要修改 springboot的启动类, 如下:
package org.diego.springvue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan("org.diego.springvue")
public class SpringVueApplication implements CommandLineRunner{
@Autowired
MyAppConfig config;
@Override
public void run(String... args) throws Exception {
System.out.println("=================== 产品环境");
System.out.println("=================== tomcat port: " + config.getAppPort());
System.out.println("=================== vue domain: " + config.getVueDomain());
}
public static void main(String[] args) {
SpringApplication.run(SpringVueApplication.class, args);
}
}
在部署环境中程序一般以命令行启动,所以这里需要继承一个新接口. 然后在这个接口实现里进行测试. 现在修改 application.properties , 修改 active profile 如下:
spring.profiles.active=prod
myapp.port = 17010
然后在工程的根目录, 即和springboot命令行脚本同级的目录, 看这里:
运行命令行, 如下:
mvn spring-boot:run
一大段log之后, 你就能看到参数的输出了:
这个配置和我们在 application-prod.properties 的配置一致, 这表示springboot已经正确读取到所需文件. test文件同理, 把 application.properties 的 active profile 修改成 test 即可, 读者可以试试.
常用的定制配置
这里只总结了我开发时候经常使用的一些配置, 如tomcat, mongodb, filter... 更多的配置例如mysql这种, 你应该很容易就能在这里找到: https://stackoverflow.com/questions/37980914/spring-global-cors-configuration-not-working-but-controller-level-config-does
tomcat的启动端口
修改MyAppConfig如下:
package org.diego.springvue;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.server.ConfigurableWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 读取各种配置
* @author cys
*
*/
@Component
@EnableWebMvc
public class MyAppConfig implements WebMvcConfigurer,WebServerFactoryCustomizer{
@Value("${myapp.port}")
int appPort;
@Value("${vue.domain}")
String vueDomain;
public int getAppPort() {
return appPort;
}
public void setAppPort(int appPort) {
this.appPort = appPort;
}
public String getVueDomain() {
return vueDomain;
}
public void setVueDomain(String vueDomain) {
this.vueDomain = vueDomain;
}
@Override
public void customize(ConfigurableWebServerFactory factory) {
factory.setPort(this.appPort);
}
}
现在重新启动 SpringVueApplication , 你可以在这堆log里看到端口确实起作用了:
mongodb 的配置
mongod的配置很简单, 按照 spring.data.mongodb.xxx 配置即可. 如下:
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
#spring.data.mongodb.authentication-database=
#spring.data.mongodb.username=
#spring.data.mongodb.password=
#spring.data.mongodb.database=test
这段配置放到 application.properties 里, 由于这节暂时没有用到mongodb, 所以先注释掉用户名/密码等信息.
mvc环境的拦截器
拦截每个请求, 在请求的前后做点什么. 这是web程序中很常用的功能. 在springboot中, 这个功能的实现和以前没有分别, 实现handler的相关接口即可.
新增一个 org.diego.springvue.webhelper的包, 然后新增 CheckLoginHandler 代码如下:
package org.diego.springvue.webhelper;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Service
public class CheckLoginHandler implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("==== preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("==== postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("==== afterCompletion");
}
}
修改MyAppConfig, 增加如下配置:
// 覆盖, 增加拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
WebMvcConfigurer.super.addInterceptors(registry);
// addPathPatterns 添加拦截规则
// excludePathPatterns 添加排除规则
registry.addInterceptor(new CheckLoginHandler()).addPathPatterns("/**");
}
handler暂时只打印log, 现在访问url: http://localhost:17010/ , 你能看到控制台的log了.
好了, 这一篇就写到这里, 更多的定制随着后续文章的开始再补上.
代码
惯例, 代码位于我的githup: https://github.com/yunshichen/spring-vue