热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

springboot项目内部停止并关闭

springboot项目内部停止并关闭,Go语言社区,Golang程序员人脉社
因业务需求,从内部停止并关闭springboot项目

首先说下遇到的需求,在项目中宁愿不执行也不能执行错误的需求时有发生,最近在做一个平台,在保存收款账户时考虑安全问题,在启动项目时作为必须校验项进行,如果校验不通过,阻止项目允许。
在百度上各种查,没有此类操作,现在研究出来了发现超级简单。写这篇文章的目的主要是记录下研究过程。心急的同学可以直接看的一部分,最终结果。

1、终于搞出来了

spring 的context(实现了ConfigurableApplicationContext的context)有一个close方法,在需要的地方执行context.close就好了。

2、我是怎么搞出来的

  • 一、内事不决问百度(主要是Google不了啊~~)

刚开始我像往常一样,期待网友们有一个成熟的解决方案。但是,经过几个小时的查找和筛选,没有找到我想要的。也不是一无所获。网友们都很乐于奉献,只要搜springboot 启动,关闭,终止的,都能查到两种方法。

这里写图片描述

对于这个结果刚开始我是很不开森的,因为只有这个结果,而且能搜到的都是这个结果,达到了一遇到这个结果就关页面的程度,最后实在找不到解决方案了。我愤怒了,既然没有人有研究,我就来贡献时间。

  • 二、Java程序员要想提升还是得看源码跟流程

既然spring官方提供了两种关闭服务的方法,说明可以做到,既然他们能做到,我也能!于是按照网友提供的步骤,下面引用网友提供的 通过http发送shutdown的方法 来研究

1.在pom.xml中引入actuator依赖
		
		  org.springframework.boot
		  spring-boot-starter-actuator
		
2.在application.properties文件开启shutdown endpoint,SpringBoot的endpoints.shutdown.enabled默认是关闭的。

    #启用shutdown 
    endpoints.shutdown.enabled=true 
    #禁用密码验证 
    endpoints.shutdown.sensitive=false

经过简单的两步就能实现远程调用关闭系统,但这不是我想要的,我要找的是在系统里直接调用某个方法就能实现自动关闭。
要查找这个方法必须从官方提供的远程调用入手,远程调用使用的HTTP请求,于是要查找HTTP请求的服务接口,没办法只能打印日志慢慢找

这里写图片描述

找到这个入口后开始一步步debug,很痛苦的,因为你不知道哪一步系统就关闭了,只能在关闭系统的方法上加断点再次启动系统,执行关闭,如此反复查找了好几次,终于让我发现了关闭服务的老巢,哈哈哈哈!!!
老巢,spring-boot-actuator-1.5.4RELEASE.jar包里的ShutdownEndpoint这个类,下面贴出来主要代码,这段代码主要是说能关闭系统时,返回说正在关闭,启动关闭线程,调用this.context.close()。我去,终于让我知道了你的秘密,使用context就能关闭。好像我spring有获取context的方法吧,我去查查(本人技术水平有限,只是知道有这个事儿,这是后面故事的开始)。

ShutdownEndpoint的主要代码

public ShutdownEndpoint() {
		super("shutdown", true, false);
	}
	@Override
	public Map invoke() {
		if (this.cOntext== null) {
			return NO_CONTEXT_MESSAGE;
		}
		try {
			return SHUTDOWN_MESSAGE;
		}
		finally {
			Thread thread = new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						Thread.sleep(500L);
					}
					catch (InterruptedException ex) {
						Thread.currentThread().interrupt();
					}
					ShutdownEndpoint.this.context.close();
				}
			});
	thread.setContextClassLoader(getClass().getClassLoader());
			thread.start();
		}
	}
	@Override
	public void setApplicationContext(ApplicationContext context) throws BeansException {
		if (context instanceof ConfigurableApplicationContext) {
			this.cOntext= (ConfigurableApplicationContext) context;
		}
	}

spring有获取context的方法
中国网友就是给力,一搜一大把,都是一样的 —— 实现ApplicationContextAware接口
嗯,照着做,实现接口,东复制下,西复制下,怀着无比期待的心情执行测试……咦怎么没有关闭!!!!!
我去,debug,然后各种查,痛苦死了,下面给出错误代码(哪里错了自己看),希望网友们引以为戒

public class ShutdownContext implements ApplicationContextAware
{
	private ConfigurableApplicationContext context;
	
	public void showdown(){
		if (null != context){
			context.close();
		}
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException{
		if (context instanceof ConfigurableApplicationContext) {
			this.cOntext=  (ConfigurableApplicationContext) applicationContext;
		}
	}
}

————————————————美丽的分割线—————————————————————

有网友说使用我的代码运行不了,时隔好久也不记得哪里错了,对比了下代码才发现最后一个判断错误了,应该判断传入参数,判断了成员变量。下面是完整代码

import org.springframework.beans.BeansException;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix ="spring")
public class ShutdownContext implements ApplicationContextAware
{

	private ConfigurableApplicationContext context;
	
	public void showdown()
	{
		if (null != context)
		{
			context.close();
		}
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
	{
		if (applicationContext instanceof ConfigurableApplicationContext) {
			this.cOntext=  (ConfigurableApplicationContext) applicationContext;
		}
		
	}
}

推荐阅读
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 标题: ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
  • Sleuth+zipkin链路追踪SpringCloud微服务的解决方案
    在庞大的微服务群中,随着业务扩展,微服务个数增多,系统调用链路复杂化。Sleuth+zipkin是解决SpringCloud微服务定位和追踪的方案。通过TraceId将不同服务调用的日志串联起来,实现请求链路跟踪。通过Feign调用和Request传递TraceId,将整个调用链路的服务日志归组合并,提供定位和追踪的功能。 ... [详细]
  • 精讲代理设计模式
    代理设计模式为其他对象提供一种代理以控制对这个对象的访问。代理模式实现原理代理模式主要包含三个角色,即抽象主题角色(Subject)、委托类角色(被代理角色ÿ ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • 嵌入式处理器的架构与内核发展历程
    本文主要介绍了嵌入式处理器的架构与内核发展历程,包括不同架构的指令集的变化,以及内核的流水线和结构。通过对ARM架构的分析,可以更好地理解嵌入式处理器的架构与内核的关系。 ... [详细]
  • Python脚本编写创建输出数据库并添加模型和场数据的方法
    本文介绍了使用Python脚本编写创建输出数据库并添加模型数据和场数据的方法。首先导入相应模块,然后创建输出数据库并添加材料属性、截面、部件实例、分析步和帧、节点和单元等对象。接着向输出数据库中添加场数据和历程数据,本例中只添加了节点位移。最后保存数据库文件并关闭文件。文章还提供了部分代码和Abaqus操作步骤。另外,作者还建立了关于Abaqus的学习交流群,欢迎加入并提问。 ... [详细]
author-avatar
俞承豪那个男人-
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有