Spring 에서@Async 는 비동기 임 무 를 수행 하 는 방법 을 설명 합 니 다.

13946 단어 Spring@Async주해
머리말
업무 처리 중 일부 업 무 는 비동기 적 인 방식 을 사용 하 는 것 이 더욱 합리적이다.예 를 들 어 특정한 업무 논리 에서 일부 데 이 터 를 redis 캐 시 에 저장 하면 캐 시 는 보조 적 인 기능 일 뿐 성공 이나 실 패 는 주 업무 에 근본 적 인 영향 을 주지 않 습 니 다.이 과정 은 비동기 적 인 방법 으로 진행 할 수 있 습 니 다.
Spring 에 서 는 방법 에@Async 주 해 를 설정 하여 다른 방법 으로 호출 할 수 있 습 니 다.즉,이 방법 은 호출 시 즉시 되 돌아 오 며,이 방법의 실제 집행 은 Spring 의 TaskExecutor 에 게 맡 기 는 것 이다.
코드 예제
프로젝트 는 일반적인 Spring 프로젝트 입 니 다.Spring 의 프로필:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  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.xsd
  http://www.springframework.org/schema/task
  http://www.springframework.org/schema/task/spring-task.xsd">

 <!--     -->
 <context:component-scan base-package="com.lzumetal.ssm"/>

 <!--           TaskExecutor -->
 <task:executor id="myexecutor" pool-size="5" />
 <task:annotation-driven executor="myexecutor"/>

</beans>

두 서비스 클래스:

package com.lzumetal.ssm.anotation.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 *   Service
 */
@Service
public class BusinessService {

 private static final Logger log = LoggerFactory.getLogger(BusinessService.class);

 @Autowired
 private CacheService cacheService;


 public void doBusiness() {
  log.error("start to deal with our business");
  cacheService.cacheData();
  log.error("comlete service operation");
 }

 /**
  *             
  */
 public void doBusinessWithAsyncReturn() throws ExecutionException, InterruptedException {
  log.error("start to deal with our business");
  Future<String> future = cacheService.cacheDataWithReturn();
  log.error(future.get()); //future.get()       
  log.error("comlete service operation");
 }
}

package com.lzumetal.ssm.anotation.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;

import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 *     
 */
@Service
public class CacheService {

 private static final Logger log = LoggerFactory.getLogger(CacheService.class);


 @Async(value = "myexecutor") //       TaskExecutor
 public void cacheData() {
  try {
   TimeUnit.SECONDS.sleep(3L);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  log.error("success store the result to cache");
 }


 @Async
 public Future<String> cacheDataWithReturn() {
  try {
   TimeUnit.SECONDS.sleep(3L);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  log.error("success store the result to cache");
  //         AsyncResult     
  return new AsyncResult<>("Async operation success");
 }
}

테스트 클래스:

package com.lzumetal.ssm.anotation.test;

import com.lzumetal.ssm.anotation.service.BusinessService;
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 java.util.concurrent.TimeUnit;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-context.xml"})
public class MainTest {


 @Autowired
 private BusinessService businessService;


 @Test
 public void test() throws InterruptedException {
  businessService.doBusiness();
  //         ,                  
  TimeUnit.SECONDS.sleep(5L);  
 }

 @Test
 public void testAsyncReturn() throws Exception {
  businessService.doBusinessWithAsyncReturn();
  TimeUnit.SECONDS.sleep(5L);
 }

}

test()방법 을 실행 한 결과:
22:20:33,207  INFO main support.DefaultTestContextBootstrapper:260 - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
22:20:33,226  INFO main support.DefaultTestContextBootstrapper:209 - Could not instantiate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [javax/servlet/ServletContext]
22:20:33,227  INFO main support.DefaultTestContextBootstrapper:187 - Using TestExecutionListeners: [org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@100fc185, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@643b1d11 , org.springframework.test.context.support.DirtiesContextTestExecutionListener@2ef5e5e3 , org.springframework.test.context.transaction.TransactionalTestExecutionListener@36d4b5c , org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@6d00a15d]22:20:33,324   INFO main xml.XmlBeanDefinitionReader:317 - Loading XML bean definitions from class path resource [spring-context.xml]
22:20:33,585  INFO main support.GenericApplicationContext:583 - Refreshing org.springframework.context.support.GenericApplicationContext@4f7d0008 : startup date [Wed May 30 22:20:33 CST 2018]; root of context hierarchy
22:20:33,763  INFO main concurrent.ThreadPoolTaskExecutor:165 - Initializing ExecutorService
22:20:33,766  INFO main support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:325 - Bean 'myexecutor' of type [org.springframework.scheduling.config.TaskExecutorFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
22:20:33,767  INFO main support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:325 - Bean 'myexecutor' of type [org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
22:20:34,107 ERROR main service.BusinessService:24 - start to deal with our business
22:20:34,113 ERROR main service.BusinessService:26 - comlete service operation
22:20:37,166 ERROR myexecutor-1 service.CacheService:28 - success store the result to cache
22:20:39,117  INFO Thread-0 support.GenericApplicationContext:984 - Closing org.springframework.context.support.GenericApplicationContext@4f7d0008 : startup date [Wed May 30 22:20:33 CST 2018]; root of context hierarchy
22:20:39,118  INFO Thread-0 concurrent.ThreadPoolTaskExecutor:203 - Shutting down ExecutorService
testasyncReturn()방법 을 실행 한 결과:
21:38:16,908  INFO main support.DefaultTestContextBootstrapper:260 - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
21:38:16,926  INFO main support.DefaultTestContextBootstrapper:209 - Could not instantiate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [javax/servlet/ServletContext]
21:38:16,927  INFO main support.DefaultTestContextBootstrapper:187 - Using TestExecutionListeners: [org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@100fc185, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@643b1d11 , org.springframework.test.context.support.DirtiesContextTestExecutionListener@2ef5e5e3 , org.springframework.test.context.transaction.TransactionalTestExecutionListener@36d4b5c , org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@6d00a15d]21:38:17,025   INFO main xml.XmlBeanDefinitionReader:317 - Loading XML bean definitions from class path resource [spring-context.xml]
21:38:17,263  INFO main support.GenericApplicationContext:583 - Refreshing org.springframework.context.support.GenericApplicationContext@4f7d0008 : startup date [Wed May 30 21:38:17 CST 2018]; root of context hierarchy
21:38:17,405  INFO main concurrent.ThreadPoolTaskExecutor:165 - Initializing ExecutorService
21:38:17,407  INFO main support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:325 - Bean 'myexecutor' of type [org.springframework.scheduling.config.TaskExecutorFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
21:38:17,407  INFO main support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:325 - Bean 'myexecutor' of type [org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
21:38:17,692 ERROR main service.BusinessService:35 - start to deal with our business
21:38:20,833 ERROR myexecutor-1 service.CacheService:39 - success store the result to cache
21:38:20,834 ERROR main service.BusinessService:37 - Async operation success
21:38:20,835 ERROR main service.BusinessService:38 - comlete service operation
21:38:25,838  INFO Thread-0 support.GenericApplicationContext:984 - Closing org.springframework.context.support.GenericApplicationContext@4f7d0008 : startup date [Wed May 30 21:38:17 CST 2018]; root of context hierarchy
21:38:25,839  INFO Thread-0 concurrent.ThreadPoolTaskExecutor:203 - Shutting down ExecutorService
@Async 사용 주의 점
  • 반환 값:반환 값 을 직접 void 로 되 돌려 주지 마 십시오.반환 값 이 필요 합 니 다.AsyncResult 또는 CompletableFuture
  • 실행 기 를 사용자 정의 하고 지정 할 수 있 습 니 다.예 를 들 어@Async("otherExecutor")
  • @Async 는 서로 다른 클래스 로 호출 해 야 합 니 다.A 류―>B 류.C 방법()(@Async 주석 은 B 류/방법 에서)같은 클래스 에서 호출 되면 동기 화 됩 니 다.예 를 들 어 A 류.B()―>A 류.@Async C().()4567918)
  • @Async 도 클래스 에 추가 할 수 있 습 니 다.이 클래스 의 모든 방법 은 비동기 로 실행 되 고 방법 상의 주 해 는 클래스 의 주 해 를 덮어 씁 니 다.보통 이렇게 안 써 요!4567918)
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
  • 좋은 웹페이지 즐겨찾기