일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- java Optional
- vscode
- AWS S3
- 창업형인간되기
- ssh
- github CI/CD
- java null 처리
- AWS ssh
- optional
- CI/CD
- java stream
- 자바 스트림
- 비주얼 스튜디오 코드
- spring multi thread
- 스트림 예제
- Visual Studio Code
- 창업 마인드
- 창업
- AWS EC2
- @async
- AWS 프로젝트 올리기
- AWS 프로젝트
- AWS 키페어
- 마인드
- AWS
- dockerfile
- 창업형인간
- 라이프해킹스쿨
- spring async
- Optional 사용법
- Today
- Total
Wookim
spring Async(비동기, 멀티스레드) 메소드 적용하기(2) 본문
지난 시간에 간단하게 주의점과 적용 레벨에 대해 알아보았다.
https://wookim789.tistory.com/52
이번 시간엔 구체적인 내용과 예제 코드를 통해 공부해 보자.
설정 파일 작업하기
지난 시간에 메소드를 비동기 처리하기 위한 레벨에 대해 설명했다.
2가지 레벨에 대해 각각의 가장 기본적인 설정 파일들을 작성해 보자.
1. method 단위 설정 파일
@Configuration
@EnableAsync
public class SpringAsyncConfig {
@Bean(name = "threadPoolTaskExecutor")
public Executor threadPoolTaskExecutor() {
return new ThreadPoolTaskExecutor();
}
}
https://www.baeldung.com/spring-async
위와 같이 굉장히 기본적인 설정파일을 하나 생성했다.
어노테이션부터 살펴보자.
@Configuration
클래스가 하나 이상의 @Bean 메소드를 선언하고
Spring 컨테이너가 런타임에 Bean 정의 및 서비스 요청을 생성하기 위해 처리 할 수 있음을 나타냅니다.
옛날에는 bean 객체들을 xml 파일에 관리 했는데,
해당 어노테이션을 이용하면 xml이 아닌 java파일로 bean을 등록 및 설정 관리할수 있다. (by wookim)
@EnableAsync
Spring의 <task : *> XML 네임 스페이스에있는
기능과 유사한 Spring의 비동기 메서드 실행 기능을 활성화합니다.
다음과 같이 @Configuration 클래스와 함께 사용하여
전체 Spring 애플리케이션 컨텍스트에 대한 주석 기반 비동기 처리를 가능하게합니다.
간단하게 설명하자면 해당 설정 파일에 비동기 메소드 실행기능을 사용하겠다고 명시하는것! (by wookim)
@Bean(name = "threadPoolTaskExecutor")
JavaConfig가 이러한 메소드를 발견하면 해당 메소드를 실행하고
반환 값을 BeanFactory 내에서 Bean으로 등록합니다.
기본적으로 Bean 이름은 메소드 이름과 동일합니다
해당 어노테이션이 적용된 메소드가 리턴하는 객체를 스프링에서 관리하는 Bean 객체로 등록하겠다고 보면 된다.
name은 빈 객체의 이름을 직접 설정하고 싶을 때 사용하면 된다. (by wookim)
Executor
이 인터페이스는 스레드 사용, 예약 등에 대한 세부 정보를 포함하여 각 작업이 실행되는 방식의 메커니즘에서 작업 제출을 분리하는 방법을 제공합니다.
일반적으로 스레드를 명시 적으로 생성하는 대신 Executor가 사용됩니다. (new Thread x)
일반적으로 작업은 호출자의 스레드가 아닌 다른 스레드에서 실행됩니다.
많은 Executor 구현은 작업을 예약하는 방법과시기에 대해 일종의 제한을 부과합니다. (비동기 실행)
그러나 Executor 인터페이스는 반드시 비동기 실행을 요구하지는 않습니다.
가장 간단한 경우 실행자는 제출 된 작업을 호출자의 스레드에서 즉시 실행할 수 있습니다. (동기 실행도 가능)
이 패키지에 제공된 Executor 구현은 보다 광범위한 인터페이스 인 ExecutorService를 구현합니다.
ThreadPoolExecutor 클래스는 확장 가능한 스레드 풀 구현을 제공합니다.
Executors 클래스는 이러한 Executors에 편리한 팩토리 메서드를 제공합니다.
출처 https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executor.html
해석이 좀 난해하다. 중요한 점만 집고 넘어가자
1. 직접 Thread 인스턴스를 만들지 말고 Excutor 인터페이스와 그 구현체를 이용하자.
2. 메소드를 호출한 스레드에서 작업을 처리 가능하다. (단일 스레드 - 동기)
3. 메소드를 호출한 스레드와 별개의 스레드에서 처리 가능하다. (다중 스레드 - 비동기)
4. 스레드에 대한 다양한 설정을 할 수 있다.
(by wookim)
이렇게 메소드 단위 설정을 마쳤고
사용 예제를 살펴 보자
@Async("threadPoolTaskExecutor")
public void asyncMethodWithConfiguredExecutor() {
System.out.println("Execute method with configured executor - "
+ Thread.currentThread().getName());
}
@Async("설정 파일의 빈 객체 이름")
해당 어노테이션은 적용된 메소드가 비동기 메소드로 실행됨을 의미한다.
메소드 단위로 설정했기 때문에 @Async 어노테이션에 설정 파일에서 선언한 빈객체의 이름을 넘겨줘야 한다.
2. application 단위 설정 파일
@Configuration
@EnableAsync
public class SpringAsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
return new ThreadPoolTaskExecutor();
}
}
https://www.baeldung.com/spring-async
위 소스에서 가장 눈여겨 보아야 하는 것 2가지
1. AsyncConfigure 인터페이스를 구현(implements)
2. getAsyncExcutor 메소드를 재정의(@Override)
메소드 단위는 빈객체를 직접 설정했지만
어플리케이션 단위 레벨에서는 AsyncConfigure 인터페이스와 getAsyncExcutor() 함수를 재정의 했다.
해당 함수는 application 전반적으로 Executor 객체를 리턴한다.
어플리케이션 전반적으로 메소드에 @Async 어노테이션을 적용하면
별다른 설정없이(@Async 어노테이션에 빈객체 이름을 넣는 등) 비동기 호출이 가능하다.
Exception Handling
이번엔 에러 핸들링을 하기위한 예제 코드이다.
에러 클래스를 정의하는 이유는 다음과 같다.
비동기 메소드가 Futrue 타입을 반환하면 Future.get() 메소드로 예외처리가 간단해진다.
(해당 메소드 호출 시 스레드의 실패 여부에 따라 예외가 발생하는 것으로 예상됨)
하지만 비동기 메소드의 리턴 타입이 void이면
호출한 스레드에 비동기 스레드의 예외가 전파되지 않는다.
따라서 아래의 예제와 같은 예외 클래스를 만들어야 한다.
public class CustomAsyncExceptionHandler
implements AsyncUncaughtExceptionHandler {
@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);
}
}
}
위 코드의 특징을 보자
1. AsyncUncaughtExceptionHandler 인터페이스를 구현했다.
2. hanldeUncaughtException() 메소드를 재정의 했다.
hanldeUncaughtException 해당 메소드는 포착되지 않은 비동기 예외가있을 때 호출된다.
이제 예외 클래스를 위의 비동기 설정 파일에 메소드 재정의(오버라이드) 해줘야 한다.
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new CustomAsyncExceptionHandler();
}
'programming language > Java' 카테고리의 다른 글
spring application 실행 환경 분리 (프로파일) (0) | 2021.07.09 |
---|---|
스프링 부트 swagger 3 적용하기 (0) | 2021.07.09 |
spring Async(비동기, 멀티스레드) 메소드 적용하기(1) (0) | 2021.05.18 |
날짜 및 시간 정규식 예제(yyyy-MM-dd hh:mm:ss) (4) | 2021.05.12 |
Spring DTO class의 특정 컬럼이 매핑 되지 않는 문제 (0) | 2021.05.03 |