java exit code 5,spring boot学习(5): 进程exit code自定义

在线上环境中,应用可能因为一些异常而终止,我们如果需要及时找到原因,根据 exit code 来定位,是个很好的途径。 spring boot 为开发者提供了相关的接口,方便开发者通过异常类型来定义自己的 exit code:ExitCodeGenerator 和 ExitCodeExceptionMapper.

1. ExitCodeGenerator:

用于主动退出应用,在 SpringApplication.exit(org.springframework.context.ApplicationContext,ExitCodeGenerator..)中用到,该方法会寻找所有的 ExitCodeGenerator 的 Bean, 也会用到方法中的入参对象。

ExitCodeGenerator 声明如下:

@FunctionalInterface

public interface ExitCodeGenerator {

/**

* Returns the exit code that should be returned from the application.

* @return the exit code.

*/

int getExitCode();

}

复制代码

1.1 使用:

System.exit(SpringApplication.exit(SpringApplication.run(DemoApplication.class, args)));

@SpringBootApplication

public class DemoApplication{

@Bean

public ExitCoder getTestExitCoder(){

return new ExitCoder();

}

@Bean

public ExitCoder1 getTestExitCoder1(){

return new ExitCoder1();

}

public static void main(String[] args) {

System.exit(SpringApplication.exit(SpringApplication.run(DemoApplication.class, args)));

}

}

复制代码

import org.springframework.boot.ExitCodeGenerator;

public class ExitCoder implements ExitCodeGenerator {

@Override

public int getExitCode() {

System.out.println("get exit code from class: ExitCoder");

return 222;

}

}

复制代码

import org.springframework.boot.ExitCodeGenerator;

public class ExitCoder1 implements ExitCodeGenerator {

@Override

public int getExitCode() {

System.out.println("get exit code from class: ExitCoder1");

return 221;

}

}

复制代码

输出为

2019-03-21 21:52:55.802 INFO 44627 --- [ main] com.example.exitcode.DemoApplication : Starting DemoApplication on lei.local with PID 44627 (/Users/lei/own/projects/java_learning/spring_boot_learning/blog/5exitcode/exitcode/out/production/classes started by lei in /Users/lei/own/projects/java_learning/spring_boot_learning/blog/5exitcode/exitcode)

2019-03-21 21:52:55.806 INFO 44627 --- [ main] com.example.exitcode.DemoApplication : No active profile set, falling back to default profiles: default

2019-03-21 21:52:56.339 INFO 44627 --- [ main] com.example.exitcode.DemoApplication : Started DemoApplication in 15.901 seconds (JVM running for 21.676)

get exit code from class: ExitCoder

get exit code from class: ExitCoder1

Disconnected from the target VM, address: '127.0.0.1:50873', transport: 'socket'

Process finished with exit code 222

复制代码

从上面可以看到,以 exit code 最大的为最终值。

2. ExitCodeExceptionMapper:

用于应用发生不可调整的异常,导致应用退出的情况。声明如下:

@FunctionalInterface

public interface ExitCodeExceptionMapper {

/**

* Returns the exit code that should be returned from the application.

* @param exception the exception causing the application to exit

* @return the exit code or {@code 0}.

*/

int getExitCode(Throwable exception);

}

复制代码

2.1 使用方式

通过 Bean 来注册,当应用发生异常时,会调用每个ExitCodeExceptionMapper 的实现类。这里,我们可以根据异常类型来设置自己的 exit code:

@SpringBootApplication

public class DemoApplication{

@Bean

public DemoExitCodeExceptionMapper getExitCodeMapper(){

return new DemoExitCodeExceptionMapper();

}

public static void main(String[] args) {

SpringApplication.run(DemoApplication.class, args);

}

@Bean

CommandLineRunner showUsers() {

return args -> {throw new Exception("xxxxx");};

}

}

复制代码

public class DemoExitCodeExceptionMapper implements ExitCodeExceptionMapper{

/**

* Returns the exit code that should be returned from the application.

* @param exception the exception causing the application to exit

* @return the exit code or {@code 0}.

*/

@Override

public int getExitCode(Throwable exception){

System.out.println("exit cod xxxx" + exception.getMessage());

if(exception.getCause().getMessage().equals("sdf")){

return 254;

}

return 243;

}

}

复制代码

运行输出为:

2019-03-21 22:13:34.261 INFO 45049 --- [ main] com.example.exitcode.DemoApplication : Started DemoApplication in 15.816 seconds (JVM running for 21.521)

exit cod xxxxFailed to execute CommandLineRunner

2019-03-21 22:13:38.797 INFO 45049 --- [ main] ConditionEvaluationReportLoggingListener :

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.

2019-03-21 22:13:38.845 ERROR 45049 --- [ main] o.s.boot.SpringApplication : Application run failed

java.lang.IllegalStateException: Failed to execute CommandLineRunner

at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:816) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]

at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:797) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]

at org.springframework.boot.SpringApplication.run(SpringApplication.java:324) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]

at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]

at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]

at com.example.exitcode.DemoApplication.main(DemoApplication.java:31) [classes/:na]

Caused by: java.lang.Exception: xxxxx

at com.example.exitcode.DemoApplication.lambda$showUsers$0(DemoApplication.java:37) [classes/:na]

at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:813) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]

... 5 common frames omitted

Disconnected from the target VM, address: '127.0.0.1:51237', transport: 'socket'

Process finished with exit code 243

复制代码

3. 取值逻辑

public int getExitCode() {

int exitCode = 0;

for (ExitCodeGenerator generator : this.generators) {

try {

int value = generator.getExitCode();

if (value > 0 && value > exitCode || value < 0 && value < exitCode) {

exitCode = value;

}

}

catch (Exception ex) {

exitCode = (exitCode != 0) ? exitCode : 1;

ex.printStackTrace();

}

}

return exitCode;

}

复制代码

第一个: 直接取第一个的值。

2....n-1,n: n 和n-1 正负不同,取 n, 相同,取绝对值大的。

4.总结:

主动调用SpringApplication.exit 方法使用ExitCodeGenerator ,可以通过 Bean注册,也可通过传值。

应用异常退出使用 ExitCodeExceptionMapper, 只能通过 Bean 注册使用。

取值: 前后正负不同,取最新, 相同,取绝对值大的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值