org.zodiac.autoconfigure.boot.PlatformBootExecutorAutoConfiguration Maven / Gradle / Ivy
package org.zodiac.autoconfigure.boot;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.task.TaskExecutorCustomizer;
import org.springframework.boot.task.TaskSchedulerCustomizer;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.lang.NonNull;
import org.springframework.scheduling.annotation.AsyncConfigurerSupport;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.util.ErrorHandler;
import org.zodiac.autoconfigure.application.ApplicationInfoProperties;
import org.zodiac.autoconfigure.log.condition.ConditionalOnPatformLogRequestEnabled;
import org.zodiac.commons.concurrent.RunnableWrapper;
import org.zodiac.commons.util.Colls;
import org.zodiac.core.context.platform.ServiceContext;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 异步处理。
*
*/
@EnableAsync
@EnableScheduling
@SpringBootConfiguration
@ConditionalOnPatformLogRequestEnabled
@ConditionalOnClass(value = {org.zodiac.log.LogOperations.class})
public class PlatformBootExecutorAutoConfiguration extends AsyncConfigurerSupport {
private final ServiceContext serviceContext;
private final ApplicationInfoProperties applicationInfoProperties;
private final ApplicationEventPublisher publisher;
public PlatformBootExecutorAutoConfiguration(ServiceContext serviceContext,
ApplicationInfoProperties applicationInfoProperties, ApplicationEventPublisher publisher) {
this.serviceContext = serviceContext;
this.applicationInfoProperties = applicationInfoProperties;
this.publisher = publisher;
}
@Bean
protected TaskExecutorCustomizer taskExecutorCustomizer() {
return taskExecutor -> {
taskExecutor.setThreadNamePrefix("async-task-");
taskExecutor.setTaskDecorator(RunnableWrapper::new);
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
};
}
@Bean
protected TaskSchedulerCustomizer taskSchedulerCustomizer() {
return taskExecutor -> {
taskExecutor.setThreadNamePrefix("async-scheduler");
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
taskExecutor.setErrorHandler(new PlatformErrorHandler(serviceContext, applicationInfoProperties, publisher));
};
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new PlatformAsyncUncaughtExceptionHandler(serviceContext, applicationInfoProperties, publisher);
}
private static class PlatformAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {
private final Logger log = LoggerFactory.getLogger(getClass());
private final ServiceContext serviceContext;
private final ApplicationInfoProperties applicationInfoProperties;
private final ApplicationEventPublisher eventPublisher;
public PlatformAsyncUncaughtExceptionHandler(ServiceContext serviceContext,
ApplicationInfoProperties applicationInfoProperties, ApplicationEventPublisher eventPublisher) {
this.serviceContext = serviceContext;
this.applicationInfoProperties = applicationInfoProperties;
this.eventPublisher = eventPublisher;
}
@Override
public void handleUncaughtException(@NonNull Throwable error, @NonNull Method method,
@NonNull Object... params) {
log.error("Unexpected exception occurred invoking async method: {}", method, error);
org.zodiac.log.model.entity.LogError logError = new org.zodiac.log.model.entity.LogError();
/*服务信息、环境、异常类型*/
logError.setParams(org.zodiac.boot.error.ErrorType.ASYNC.getType());
logError.setEnv(applicationInfoProperties.getEnvType());
logError.setServiceId(applicationInfoProperties.getName());
logError.setRequestUri(serviceContext.getRequestId());
/*堆栈信息*/
org.zodiac.boot.error.ErrorUtil.initErrorInfo(error, logError);
Map event = Colls.map(16);
event.put(org.zodiac.log.constants.EventConstants.EVENT_LOG, logError);
eventPublisher.publishEvent(new org.zodiac.log.event.ErrorLogApplicationEvent(event));
}
}
private static class PlatformErrorHandler implements ErrorHandler {
private final Logger log = LoggerFactory.getLogger(getClass());
private final ServiceContext serviceContext;
private final ApplicationInfoProperties applicationInfoProperties;
private final ApplicationEventPublisher eventPublisher;
public PlatformErrorHandler(ServiceContext serviceContext, ApplicationInfoProperties applicationInfoProperties,
ApplicationEventPublisher eventPublisher) {
this.serviceContext = serviceContext;
this.applicationInfoProperties = applicationInfoProperties;
this.eventPublisher = eventPublisher;
}
@Override
public void handleError(@NonNull Throwable error) {
log.error("Unexpected scheduler exception.", error);
org.zodiac.log.model.entity.LogError logError = new org.zodiac.log.model.entity.LogError();
/*服务信息、环境、异常类型*/
logError.setParams(org.zodiac.boot.error.ErrorType.SCHEDULER.getType());
logError.setServiceId(applicationInfoProperties.getName());
logError.setEnv(applicationInfoProperties.getEnvType());
logError.setRequestUri(serviceContext.getRequestId());
/*堆栈信息*/
org.zodiac.boot.error.ErrorUtil.initErrorInfo(error, logError);
Map event = Colls.map(16);
event.put(org.zodiac.log.constants.EventConstants.EVENT_LOG, logError);
eventPublisher.publishEvent(new org.zodiac.log.event.ErrorLogApplicationEvent(event));
}
}
}