Spring

스프링 부트 @Async 비동기 예제

기록만이살길 2020. 6. 16. 21:23
반응형

스프링 부트 @Async 비동기 예제

스프링 부트 비동기 예제

우리는 일반적으로 동기 방식으로 메소드를 호출합니다. 어떤 경우에는 비동기 적으로 메소드를 호출해야합니다. @AsyncSpring Boot를 사용할 때 비동기 적으로 메소드를 호출하는 데 도움이 될 수 있습니다.

사용하기 전에 시작 클래스 @Async를 추가해야합니다 @EnableAsync. main class등에 한번만 작성을하고 사용하고자하는 메소드위에 @Async 비동기 어노테이션을 사용하게되면 자동으로 그 메소드는 비동기로 동작하게됩니다. 아래는 예제입니다. 스프링부트는 다른 의존성없이 아래와같이 어노테이션만 추가하게되면 동작합니다.

@Controller
@EnableAsync
@EnableAutoConfiguration
@ComponentScan(basePackages = "com.henryxi.async")
public class SimpleController {

    @Autowired
    private MyService myService;

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    @ResponseBody
    public String hello(HttpServletRequest request) {
        myService.hello();
        return "finish";
    }

    public static void main(String[] args) {
        SpringApplication.run(SimpleController.class, args);
    }
}

MyService컨트롤러에 주입 합니다. 이 서비스에는 @Async어노테이션 이있는 비동기 메소드가 있습니다.

@Service
public class MyService {

    @Async
    public void hello() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("finish!!");
    }
}

이 비동기 방법에서는 프로그램을 3 초 동안 절전 모드로 설정합니다. 따라서 비동기 메서드의 작동 방식을보다 명확하게 확인할 수 있습니다.

이 앱을 시작하고이 URL (localhost : 8080 / hello)을 방문하십시오. 요청한 페이지가 즉시 반환됩니다. 3 초 후에 비동기 메소드의 로그가 백그라운드의 콘솔에 출력됩니다.

비동기 주석을 추가하는 메소드의 경우 호출 될 때 동기식으로 호출되지 않습니다. 스프링 프레임 워크에는 비동기 메소드 및 태스크 호출을 담당하는 특정 스레드 풀이 있습니다. ExecutorConfig정의 된 스레드 풀 크기에 대한 클래스를 만들 수 있습니다 .

@Configuration
@EnableAsync
public class ExecutorConfig {

    private static final Logger logger = LoggerFactory.getLogger(ExecutorConfig.class);

    @Bean(name = "threadPoolExecutor")
    public Executor asyncServiceExecutor() {
        logger.info("start asyncServiceExecutor");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(5);
        executor.setQueueCapacity(99999);
        executor.setThreadNamePrefix("async-service-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}

이 스레드 풀을 사용하려면로 변경 @Asyc해야 @Async("threadPoolExecutor")합니다. 이 앱을 다시 실행하고 URL에 액세스하십시오. 출력은 다음과 같습니다.

......
2019-02-02 11:53:03.685  INFO 1488 --- [           main] com.henryxi.async.ExecutorConfig         : start asyncServiceExecutor
2019-02-02 11:53:03.687  INFO 1488 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 
2019-02-02 11:53:03.691  INFO 1488 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService  'threadPoolExecutor'
2019-02-02 11:53:03.796  INFO 1488 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@67f639d3: startup date [Sat Feb 02 11:53:02 CST 2019]; root of context hierarchy
2019-02-02 11:53:03.837  INFO 1488 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/hello],methods=[GET]}" onto public java.lang.String com.henryxi.async.SimpleController.hello(javax.servlet.http.HttpServletRequest)
2019-02-02 11:53:03.839  INFO 1488 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2019-02-02 11:53:03.839  INFO 1488 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2019-02-02 11:53:03.866  INFO 1488 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-02-02 11:53:03.866  INFO 1488 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-02-02 11:53:03.894  INFO 1488 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-02-02 11:53:04.014  INFO 1488 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2019-02-02 11:53:04.060  INFO 1488 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2019-02-02 11:53:04.063  INFO 1488 --- [           main] com.henryxi.async.SimpleController       : Started SimpleController in 1.928 seconds (JVM running for 2.502)
2019-02-02 11:53:05.382  INFO 1488 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2019-02-02 11:53:05.383  INFO 1488 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2019-02-02 11:53:05.394  INFO 1488 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 11 ms
async-service-1:finish!!
반응형