https://stackoverflow.com/questions/48006956/custom-asyncuncaughtexceptionhandler
비동기 코드는 별도의 스레드에서 실행됩니다(따라서 @ComponentScan새 스레드를 보고 초기화하기 위해).
기본적으로 모든 빈은 싱글톤입니다(자세한 내용은 봄의 빈 범위 참조). 새 스레드가 다른 컨테이너에서 실행되기 때문입니다. 서비스 빈에 대한 참조를 가져오지 않으므로 null이 됩니다.
왜 @ComponentScan처리 하지 않았습니까? 구성 요소 스캔은 대부분 패키지의 하위 집합을 스캔하는 것이며 서비스는 다른 패키지에 정의될 수 있습니다.
솔루션: @ApplicationScope어노테이션을 사용하여 서비스 Bean 애플리케이션 범위를 만드십시오 .
@EnableAsync
@EnableScheduling
@Configuration
public class AsyncConfig implements AsyncConfigurer {
CustomAsyncExceptionHandler customAsyncExceptionHandler;
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setThreadNamePrefix("kang-");
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
//return new CustomAsyncExceptionHandler();
return this.customAsyncExceptionHandler;
}
@Autowired
public void setCustomAsyncExceptionHandler(CustomAsyncExceptionHandler customAsyncExceptionHandler) {
this.customAsyncExceptionHandler = customAsyncExceptionHandler;
}
//
//
// @Override
// public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
// return this.customAsyncExceptionHandler;
// }
@Bean
public ThreadPoolTaskScheduler configureTasks() {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(10);
threadPoolTaskScheduler.setThreadNamePrefix("kang-scheduled-");
threadPoolTaskScheduler.initialize();
return threadPoolTaskScheduler;
}
}
@Component @ApplicationScope
public class CustomAsyncExceptionHandler
implements AsyncUncaughtExceptionHandler {
@Autowired
private Glovar glovar;
@Autowired
private CrescomAiService crescomAiService;
@Override
public void handleUncaughtException(
Throwable throwable, Method method, Object... obj) {
System.out.println("Exception message - " + throwable.getMessage());
System.out.println("Method name - " + method.getName());
for (Object param : obj) {
System.out.println("Parameter value - " + param);
}
glovar.synchronizedList.remove(glovar.synchronizedList.size() - 1);
glovar.errorCount.incrementAndGet();
try {
//System.out.println("why?");
crescomAiService.serverSentProgress();
} catch (IOException e) {
e.printStackTrace();
}
}
}
https://www.baeldung.com/spring-bean-scopes
@Singleton vs @ApplicationScope
4.3. 적용 범위
응용 프로그램의 범위는의 라이프 사이클에 대한 빈 인스턴스 생성 의 ServletContext를.
이것은 싱글톤 스코프 와 유사 하지만 빈의 스코프와 관련하여 매우 중요한 차이가 있습니다.
빈이 애플리케이션 범위일 때 빈 의 동일한 인스턴스는 동일한 ServletContext 에서 실행되는 여러 서블릿 기반 애플리케이션에서 공유되는 반면 싱글톤 범위의 빈은 단일 애플리케이션 컨텍스트로만 범위가 지정됩니다.
애플리케이션 범위로 빈을 생성해 보겠습니다 .
https://stackoverflow.com/questions/44361580/is-there-application-scope-in-spring
https://stackoverflow.com/questions/26832051/singleton-vs-applicationscope/27848417