Spring 비동기 처리 @Async

Spring 비동기 처리 @Async

SpringFramework에서 비동기로 처리해야 하는 상황이 생겨서 샘플 작성하는김에

블로그에 올리게되었음.


예를 들어 서비스하고 있는 사이트가 로그인을 하면 메인페이지로 이동된다. 메인페이지엔 이런저런 많은 정보들을 가져오는 상황 그런데 그곳에 시간이 좀 걸리는 작업을 추가하게 되어 메인페이지 로딩시간이 길어지게 되었다. 그래서 오래걸리는 작업은 비동기로 처리하여 해결.

시작에 앞서 동기/비동기 개념을 알아보도록 하겠다.

[이미지펌]


동기방식 : 그림에서 보이는 바와 같이 요청처리1이 처리가 완료된 후 요청처리2가 요청을 받아 처리 할 수 있다.

비동기방식 : 요청처리1이 처리완료 되지않아도 요청처리2가 요청을받아 처리한다.


1. 우선 Maven dependency를 추가한다.

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>		 
    <version>4.1.1.RELEASE</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>		 
    <version>4.11</version>
    <scope>test</scope>
</dependency> 


2. 프레임워크 환경파일에 설정 추가

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"	
    xmlns:task="http://www.springframework.org/schema/task" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd         
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
    http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd">

    <task:annotation-driven />	

</beans>


3. AsyncTest 파일작성

package egovframework.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;


/**
 * xxxxxx 관한 controller 클래스를 정의한다.
 * @author 개발팀 hyunjo
 * @since 2017. 9. 29. 
 * @version 1.0
 * @see
 *
 * <pre>
 * << 개정이력(Modification Information) >>
 *   
 *   수정일      수정자           수정내용
 *  -------    --------    ---------------------------
 *   2017. 9. 29.   hyunjo          최초 생성
 *   
 * </pre>
 */
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(
     locations = {"file:src/main/resources/egovframework/spring/com/**/*.xml",
    		 "file:src/main/webapp/WEB-INF/config/egovframework/**/*.xml"
     }
)
public class AsyncTest {
	
	@Autowired
	AsyncService asyncService;
	
	@Test
	public void asyncTest() throws InterruptedException {		
        //비동기 호출
		asyncService.async();
        //동기 호출
		asyncService.normal();
	}	

}


4. AsyncService 파일작성

package egovframework.test;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

/**
 * xxxxxx 관한 controller 클래스를 정의한다.
 * @author 개발팀 hyunjo
 * @since 2017. 9. 29. 
 * @version 1.0
 * @see
 *
 * <pre>
 * << 개정이력(Modification Information) >>
 *   
 *   수정일      수정자           수정내용
 *  -------    --------    ---------------------------
 *   2017. 9. 29.   hyunjo          최초 생성
 *   
 * </pre>
 */
@Service
public class AsyncService {
	
	/**
	 * @throws InterruptedException 
	 * @desc : 동기
	 */
	public void normal() throws InterruptedException {
		System.out.println("2번 ============= 동기 시작 ===========");
		Thread.sleep(4000);
		System.out.println("2번 ============= 동기 종료 ===========");
	}

	
	/**
	 * @throws InterruptedException 
	 * @desc : 비동기
	 */
	@Async
	public void async() throws InterruptedException {		
		System.out.println("1번 ============= 비동기 시작 ===========");
		Thread.sleep(2000);
		System.out.println("1번 ============= 비동기 종료 ===========");
	}
}



5. 테스트

테스트를 위해 JUnit Test를 선택합니다.



JUnit 테스트가 정상적으로 되었습니다.



로그확인



6. 설명

비동기 호출을 시작하고 바로 동기 호출을 합니다.

비동기가 종료되고 동기가 종료 됩니다.

동기방식이였다면 비동기가 종료될때까지 기다렸다가 동기가 호출되었을것입니다.