Spring Boot Actuator - 如何将自定义逻辑添加到 /shutdown 端点
Spring Boot Actuator - how to add custom logic to /shutdown endpoint
在我的项目中,我开始使用 Spring Boot Actuator。我使用 /shutdown
端点优雅地停止嵌入式 Tomcat(这很好用),但我还需要在关闭期间执行一些自定义逻辑。有什么办法,怎么做吗?
我可以想出两种方法来在 关闭应用程序之前 执行一些逻辑:
- 注册一个
Filter
,毕竟是一个网络应用
- 使用
@Before
建议拦截 invoke
方法
Servlet 过滤器
由于 /shutdown
是一个 Servlet 端点,您可以在调用 /shutdown
端点之前将 Filter
注册到 运行:
public class ShutdownFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
// Put your logic here
filterChain.doFilter(request, response);
}
}
另外别忘了注册一下:
@Bean
@ConditionalOnProperty(value = "endpoints.shutdown.enabled", havingValue = "true")
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new ShutdownFilter());
registrationBean.setUrlPatterns(Collections.singleton("/shutdown"));
return registrationBean;
}
正在定义 @Aspect
如果您向 /shutdown
端点发送请求,假设关闭端点已启用且安全性未阻止该请求,则将调用 invoke
方法。您可以定义一个 @Aspect
来拦截此方法调用并将您的逻辑放在那里:
@Aspect
@Component
public class ShutdownAspect {
@Before("execution(* org.springframework.boot.actuate.endpoint.ShutdownEndpoint.invoke())")
public void runBeforeShutdownHook() {
// Put your logic here
System.out.println("Going to shutdown...");
}
}
另外不要忘记启用 AspectJAutoProxy
:
@SpringBootApplication
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class Application { ... }
与spring-aspects
依赖关系:
compile 'org.springframework:spring-aspects'
调用时,关闭端点会在应用程序上下文中调用 close()
。这意味着在关闭处理期间 运行 某些自定义逻辑的所有常用机制都可用。
例如,您可以将一个 bean 添加到实现 DisposableBean
的应用程序上下文中,或者在通过 Java 声明一个 bean 时使用 @Bean
的 destroyMethod
属性配置:
@Bean(destroyMethod="whateverYouWant")
public void Foo {
return new Foo();
}
如果您制作自定义 ShutdownEndpoint bean,您可以添加自定义逻辑。
@Component
public class CustomShutdownEndpoint extends ShutdownEndpoint {
@Override
public Map<String, Object> invoke() {
// Add your custom logic here
return super.invoke();
}
}
通过这种方式,您可以更改任何逻辑spring-boot-actuator Endpoints。
在我的项目中,我开始使用 Spring Boot Actuator。我使用 /shutdown
端点优雅地停止嵌入式 Tomcat(这很好用),但我还需要在关闭期间执行一些自定义逻辑。有什么办法,怎么做吗?
我可以想出两种方法来在 关闭应用程序之前 执行一些逻辑:
- 注册一个
Filter
,毕竟是一个网络应用 - 使用
@Before
建议拦截invoke
方法
Servlet 过滤器
由于 /shutdown
是一个 Servlet 端点,您可以在调用 /shutdown
端点之前将 Filter
注册到 运行:
public class ShutdownFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
// Put your logic here
filterChain.doFilter(request, response);
}
}
另外别忘了注册一下:
@Bean
@ConditionalOnProperty(value = "endpoints.shutdown.enabled", havingValue = "true")
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new ShutdownFilter());
registrationBean.setUrlPatterns(Collections.singleton("/shutdown"));
return registrationBean;
}
正在定义 @Aspect
如果您向 /shutdown
端点发送请求,假设关闭端点已启用且安全性未阻止该请求,则将调用 invoke
方法。您可以定义一个 @Aspect
来拦截此方法调用并将您的逻辑放在那里:
@Aspect
@Component
public class ShutdownAspect {
@Before("execution(* org.springframework.boot.actuate.endpoint.ShutdownEndpoint.invoke())")
public void runBeforeShutdownHook() {
// Put your logic here
System.out.println("Going to shutdown...");
}
}
另外不要忘记启用 AspectJAutoProxy
:
@SpringBootApplication
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class Application { ... }
与spring-aspects
依赖关系:
compile 'org.springframework:spring-aspects'
调用时,关闭端点会在应用程序上下文中调用 close()
。这意味着在关闭处理期间 运行 某些自定义逻辑的所有常用机制都可用。
例如,您可以将一个 bean 添加到实现 DisposableBean
的应用程序上下文中,或者在通过 Java 声明一个 bean 时使用 @Bean
的 destroyMethod
属性配置:
@Bean(destroyMethod="whateverYouWant")
public void Foo {
return new Foo();
}
如果您制作自定义 ShutdownEndpoint bean,您可以添加自定义逻辑。
@Component
public class CustomShutdownEndpoint extends ShutdownEndpoint {
@Override
public Map<String, Object> invoke() {
// Add your custom logic here
return super.invoke();
}
}
通过这种方式,您可以更改任何逻辑spring-boot-actuator Endpoints。