部署和运行
一、打包部署
使用内嵌服务器:
war或者jar,进行maven-build进行构建,target 目录下就找到了打好的包了。
通过命令 java -jar xxx.war启动项目,SpringBoot内嵌的服务器运行这个war包
也可以指定端口 java -jar xxx.war --server.port=9080
使用外部第三方服务器:
将war包复制到外部 Tomcat webapps目录下,即可以完成部署。
二、热部署
应用正在运行的时候升级软件,无需重新启动应用。
依赖spring-boot-devtools
<!--当导入该依赖,修改其中的文件时,文件就会立即生效
optional选项为 true,代表别的项目依赖于当前项目,这个热部署不会在该项目上生效
-->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-devtools</artifactid>
<optional>true</optional>
</dependency>
热部署的配置
#是否启用 livereload.com 兼容的服务器
spring.devtools.livereload.enabled=true
#端口 livereload com 服务苦苦端口
spring.devtools.livereload.port=35729
#在原来的基础上新增不重启服务的文件夹目录
spring.devtools.restart.additional-exclude=
#在原来的基础上新增重启服务的文件夹目录
spring.devtools.restart.additional-paths=
#是否启用自动重启功能
spring.devtools.restart.enabled=true
#不重启服务的文件夹配置
spring.devtools.restart.exclude=META INF/maven/** , META-INF/resources/** , resources/** ,
static/** public/**,templates/** **/*Test.class **/*Tests.class,git.properties
#设置对路径变化进行监测的时间间隔(以毫秒为单位)
spring.devtools.restart.poll-interval=lOOO
#在没有改变任何 classpath 的情况下在重启被触发前的静默时 毫秒
spring.devtools.restart.quiet-period=400
#设置触发文件 当需要实际触发重启检查时 则需要修改这个文件
spring.devtools.restart trigger-file=
测试
引入测试依赖
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-test</artifactid>
<scope>test</scope>
</dependency>
IDEA自动搭建的测试环境
@RunWith(SpringRunner.class) //注解@RunWith所载入的类SpringRunner是Spring结合JUnit的运行器
@SpringBootTest
public class ChapterApplicationTests{
@Autowired
private UserService userService = null;
@Test
public void contextLoads(){
User user = userService.getUser(1L);
//判断用户信息是否为空
Assert.assertNotNull(user);
}
}
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)//使用随机端口启动测试服务(防止端口被占用)
public class ChapterApplicationTests{
//Rest测试模板,SpringBoot自动提供
@Autowired
private TestRestTemplate restTemplate = null;
@Test
public void testGetUser(){
//请求当前启动的服务,注意URI的缩写
User user = this.restTemplate.getForObject("/user/{id}",User.class,1L);
Assert.assertNotNull(user);
}
}
//Mock用于虚拟提供一个服务进行测试
@MockBean
private ProduceService produceServie = null;//表示对Product使用Mock测试
@Test
public void testGetProduct(){
//构建虚拟对象
Product mockProduct = new Product();
mockProduct.setId(1L);
mockProduct.setProductName("product_name_"+1);
mockProduct.setNote("note_"+1);
BDDMockito.given(this.productService.getProduct(1L))//指定mockbean、方法、参数
.willReturn(mockProduct);//指定返回的虚拟对象
//进行mock测试
Product product = productService.getProduct(1L);
Assert.assertTrue(product.getId() == 1L);
}
监控端点Actuator
一、导入依赖
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-actuator</artifactid>
</dependency>
<!--REST架构中复杂的约束-->
<dependency>
<groupid>org.springframework.hateoas</groupid>
<artifactid>spring-hateoas</artifactid>
<version>0.24.0.RELEASE</version>
</dependency>
Actuator提供如下端点监控SpringBoot运行情况
二、监控手段
包括 HTTP 和JMX等多种手段
HTTP监控
引入spring-boot-starter-actuator和spring-boot-starter-web基础上,启动SpringBoot
浏览器中输入:http://localhost:8080/actuator/health 默认前缀/actuator/ 端点health默认是启用的
浏览器中输入:http://localhost:8080/actuator/beans 访问端点beans(非暴露端点)失败
可以通过application.properties配置文件中进行设置端点暴露
management.endpoints.web.exposure.include=info,health,beans
#暴露所有端点
management.endpoints.web.exposure.include=*
#不暴露 env 端点
management.endpoints.web.exposure.exclude=env
以上通过配置文件进行访问对于安全有隐患,所以通过SpringSecurity配置用户和角色来解决
- 引入spring-boot-starter-security
- 代码,配置用户和角色访问敏感信息
@SpringBootApplication(scanBasePackages="com.springboot.chapter")
public class ChapterApplication extends WebSecurityConfigurerAdapter{
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
//密码编辑器
PasswordEncoder passwordEncoder = new BCrypterPasswordEncoder();
//使用内存存储
auth.inMemoryAuthentication()
//设置密码编辑器
.passwordEncoder(passwordEncoder)
//注册用户admin,密码abc,并赋予user和admin的角色权限
.withUser("admin")
//获取加密后的密码
.password("")
//赋予角色
.roles("USER","ADMIN")
.and()
//注册用户myuser,密码123456,并赋予user角色权限
.withUser()
//可通过passwordEncoder.encode("123456")得到加密后的密码
.password("")
//赋予角色
.roles("USER");
}
@Override
protected void configure(HttpSecurity http){
//需要保护的端点
String[] endPoints = {"auditevents","beans","conditions","configprops","env","flyway",
"httptrace","loggers","liquibase","metrics","mappings","scheduledtasks","sessions",
"shutdown","threaddump"
};
//需要验证的端点
http.requestMatcher(EndpointRequest.to(endPoints))
//签名登录后
.authorizeRequests().anyRequest()
//要求登录用户拥有ADMIN角色
.hasRole("ADMIN")
.and()
//请求关闭页面需要ROLE_ADMIN角色
antMatcher("/close").authorizeRequests().anyRequest().hasRole("ADMIN")
.and()
//启动HTTP基础验证
.httpBasic();
}
}
特殊端点shutdown,因为他的请求是危险的,默认情况下是关闭的。
通过配置文件开启
属于Post请求,无法通过浏览器进行访问
通过页面进行访问,启动 Spring Boot 应用并请求这个close 方法后, 使用“ admin "用户登录就会跳转到 close.jsp ,然后点击关闭按钮就能停止当前的spring Boot 应用。
控制器
@RestController
public class CloseController{
@GetMapping("/close")
public ModelAndView close(ModelAndView mv){
//定义视图名称close,跳转对应的jsp
mv.setViewName("close");
return mv;
}
}
自定义端点
- @Endpoint 同时提供JMX监控和Web监控
- @JmxEndpoint 只提供JMX监控
- @WebEndpoint 只提供Web监控
@WebEndpointExtension或@EndpointJmxExtension对已有端点进行扩展
自定义端点,监控数据库是否连接得上
@Component
@Endpoint(id="dbcheck",enableByDefault=true)//声明为端点,默认情况下启动端点
public class DataBaseConnectionEndpoint{
private static final String DRIVER = "com.mysql.jdbc.Driver";
@Value("${spring.datasource.url}")
private String url = null;
@Value("${spring.datasource.username}")
private String username = null;
@Value("${spring.datasource.password}")
private String password = null
/**
@WriteOperation 代表HTTP的POST请求,只能接收请求类型(Consumes为application, vnd.spring-boot.actuator.v2+ json
application/json 类型的请求.返回值在默认情况下都会返回为 application/vnd spring-boot.actuator. v2+json application/ison 类型
@DeleteOperation代表HTTP的DELETE请求
*/
@ReadOperation //读操作,同一个端点下只有一个该注解标注的方法
public Map<String,Object> test(){
Connection conn = null;
Map<String,Object> msgMap = new HashMap<>();
try{
Class.forName(DRIVER);
conn = DriverManager.getConnection(url,username,password);
msgMap.put("success",true);
msgMap.put("message","测试数据库连接成功");
}catch(Exception e){
msgMap.put("success",false);
msgMap.out("message",ex.getMessage());
}finally{
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
return msgMap;
}
}
属性文件
浏览器访问
健康指标项