springboot项目初始化和项目结束调用自定义方法

1、在项目启动类中实现CommandLineRunner,实现run方法。run方法会在项目启动后调用。

@SpringBootApplication
@MapperScan(basePackages = "com.yin.freemakeradd.mapper")
public class FreemakeraddApplication implements CommandLineRunner {
    @Autowired
    private List<Init> inits;
public static void main(String[] args) {
        SpringApplication.run(FreemakeraddApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
       if(Objects.isNull(inits)){
           return;
       }
        for (Init init : inits) {
            init.init();
        }
    }
    }

2、定义一个Init接口

public interface Init {
    void init();

    void exeact();
}

3、实现Init接口

public abstract class InitWork implements Init{
    @Override
    public void init() {
        exeact();
    }
}
@Component
public class JobWorker extends InitWork {
    @Override
    public void exeact() {
        System.out.println("-----------------start job");
        close();
    }

    void close(){
        Runtime.getRuntime().addShutdownHook(new Thread(){
            @Override
            public void run() {
                System.out.println("-----------------end job");
            }
        });
    }
}

启动项目(结束代码执行—end job)

2019-10-08 19:19:55.081  INFO 9776 --- [           main] c.y.databaseweb.DatabaseWebApplication   : No active profile set, falling back to default profiles: default
2019-10-08 19:19:57.261  INFO 9776 --- [           main] c.y.databaseweb.DatabaseWebApplication   : Started DatabaseWebApplication in 3.687 seconds (JVM running for 6.341)
-----------------start job
Disconnected from the target VM, address: '127.0.0.1:63629', transport: 'socket'
-----------------end job

Runtime.getRuntime().addShutdownHook(new Thread(){})生效的条件:

Java 虚拟机会为了响应以下两类事件而关闭:

程序正常退出:这发生在最后的非守护线程退出时,或者在调用 exit(等同于System.exit)方法时。

为响应用户中断而终止虚拟机:如键入 ^C(注:也就是我们再dos窗口下常用的Ctrl+C退出命令);或发生系统事件,比如用户注销或系统关闭。

shutdown hook只是一个已初始化但尚未启动的线程。虚拟机开始启用其关闭序列时,它会以某种未指定的顺序启动所有已注册的关闭挂钩,并让它们同时运行。运行完所有的挂钩后,如果已启用退出终结,那么虚拟机接着会运行所有未调用的终结方法。最后,虚拟机会暂停。注意,关闭序列期间会继续运行守护线程,如果通过调用 exit 方法来发起关闭序列,那么也会继续运行非守护线程。

一旦开始了关闭序列,则只能通过调用 halt 方法来停止这个序列,此方法可强行终止虚拟机。

一旦开始了关闭序列,则不可能注册新的关闭挂钩或取消注册先前已注册的挂钩。尝试执行这些操作会导致抛出 IllegalStateException。

关闭挂钩可在虚拟机生命周期中的特定时间运行,因此应保护性地对其进行编码。特别是应将关闭挂钩编写为线程安全的,并尽可能地避免死锁。关闭挂钩还应该不盲目地依靠某些服务,这些服务可能已注册了自己的关闭挂钩,所以其本身可能正处于关闭进程中。

关闭挂钩应该快速地完成其工作。当程序调用 exit 时,虚拟机应该迅速地关闭并退出。由于用户注销或系统关闭而终止虚拟机时,底层的操作系统可能只允许在固定的时间内关闭并退出。因此在关闭挂钩中尝试进行任何用户交互或执行长时间的计算都是不明智的。

与其他所有线程一样,通过调用线程 ThreadGroup 对象的 uncaughtException 方法,可在关闭挂钩中处理未捕获的异常。此方法的默认实现是将该异常的堆栈跟踪 (stack trace) 打印至 System.err 并终止线程;它不会导致虚拟机退出或暂停。

仅在很少的情况下,虚拟机可能会中止,也就是没有完全关闭就停止运行。虚拟机被外部终止时会出现这种现象,比如在 Unix 上使用 SIGKILL 信号或者在 Microsoft Windows 上调用 TerminateProcess。如果由于内部数据结构损坏或试图访问不存在的内存而导致本机方法执行错误,那么可能也会中止虚拟机。如果虚拟机中止,则无法保证是否将运行关闭挂钩。

注:

在eclipse环境下,程序运行时的那个红色小方形按钮是强制终止程序,也就是相当于kill进程。因此这时候,如果你的程序中有一个hook,那么它就不会执行。因为按照上文的说法,只有在两种情况下运行hook中的程序。这一点和tomcat的程序关闭有点类似,tomcat中的listener中的contextDestroyed()方法也是在jvm关闭的时候才执行这个函数里面的程序。而我们如果直接关掉tomcat的运行窗口,就相当于直接kill掉进程了,因此并不会执行这个函数,但是如果使用的是tomcat里面的shutdown.bat命令,那么这个函数就会执行。
所以对于意外关闭JVM或者强制杀死进程的情况,想要清理垃圾或者一些资源回收的问题,本文的addShutdownHook的方法也不管用。

假如你在程序中还开启了一个端口,那么意外的程序终止,这个端口还被占用,并没有被释放,那么下一次程序重启或者别的程序要使用这个端口的时候,就会出现端口被占用的情况。

对于addShutdownHook()中的Hook,这个线程里面更不能出现死循环的情况,因为这样的话,那么当程序正常终止的时候,就会出现程序关闭不了的情况。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
springboot学习笔记 spring基础 Spring概述 Spring的简史 xml配置 注解配置 java配置 Spring概述 Spring的模块 核心容器CoreContainer Spring-Core Spring-Beans Spring-Context Spring-Context-Support Spring-Expression AOP Spring-AOP Spring-Aspects Messaging Spring-Messaging WEB Spring-Web Spring-Webmvc Spring-WebSocket Spring-Webmvc-Portlet 数据访问/集成(DataAccess/Intefration) Spring-JDBC Spring-TX Spring-ORM Spring-OXM Spring-JMS Spring的生态 Spring Boot Spring XD Spring Cloud Spring Data Spring Integration Spring Batch Spring Security Spring HATEOAS Spring Social Spring AMQP Spring Mobile Spring for Android Spring Web Flow Spring Web Services Spring LDAP Spring Session Spring项目快速搭建 Maven简介 Maven安装 Maven的pom.xml dependencies dependency 变量定义 编译插件 Spring项目的搭建 Spring Tool Suite https://spring.io/tools/sts/all IntelliJ IDEA NetBeans https://netbeans.org/downloads/ Spring基础配置 依赖注入 声明Bean的注解 @Component组件,没有明确的角色 @Service在业务逻辑层(service层) @Repository在数据访问层(dao层) @Controller在展现层(MVC→SpringMVC) 注入Bean的注解 @Autowired:Spring提供的注解 @Inject:JSR-330提供的注解 @Resource:JSR-250提供的注解 Java配置 @Configuration声明当前类是一个配置类 @Bean注解在方法上,声明当前方法的返回值为一个Bean AOP @Aspect 声明是一个切面 拦截规则@After @Before @Around PointCut JoinPoint Spring常用配置 Bean的Scope Singleton Prototype Request Session GlobalSession SpringEL和资源调用 注入普通字符 注入操作系统属性 注入表达式云算结果 注入其他Bean的属性 注入文件内容 注入网址内容 注入属性文件 Bean的初始化和销毁 Java配置方式 注解方式 Profile @Profile 通过设定jvm的spring.profiles.active参数 web项目设置在Servlet的context parameter中 事件Application Event 自定义事件,集成ApplicationEvent 定义事件监听器,实现ApplicationListener 使用容器发布事件 Spring高级话题 Spring Aware BeanNameAware BeanFactoryAware

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值