引言

創(chuàng)新互聯(lián)是專業(yè)的工農(nóng)網(wǎng)站建設公司,工農(nóng)接單;提供成都網(wǎng)站建設、網(wǎng)站建設,網(wǎng)頁設計,網(wǎng)站設計,建網(wǎng)站,PHP網(wǎng)站建設等專業(yè)做網(wǎng)站服務;采用PHP框架,可快速的進行工農(nóng)網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!
在業(yè)務處理中,有些業(yè)務使用異步的方式更為合理。比如在某個業(yè)務邏輯中,把一些數(shù)據(jù)存入到redis緩存中,緩存只是一個輔助的功能,成功或者失敗對主業(yè)務并不會產(chǎn)生根本影響,這個過程可以通過異步的方法去進行。
Spring中通過在方法上設置@Async注解,可使得方法被異步調(diào)用。也就是說該方法會在調(diào)用時立即返回,而這個方法的實際執(zhí)行交給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"/> <!-- 執(zhí)行異步任務的線程池TaskExecutor --> <task:executor id="myexecutor" pool-size="5" /> <task:annotation-driven executor="myexecutor"/> </beans>
兩個Service類:
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;
/**
* 業(yè)務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");
}
/**
* 獲取異步方法執(zhí)行的返回值
*/
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") //指定執(zhí)行任務的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();
//不讓主線程過早結束,否則控制臺看不到異步方法中的輸出內(nèi)容
TimeUnit.SECONDS.sleep(5L);
}
@Test
public void testAsyncReturn() throws Exception {
businessService.doBusinessWithAsyncReturn();
TimeUnit.SECONDS.sleep(5L);
}
}
執(zhí)行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
執(zhí)行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的使用注意點
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
網(wǎng)頁名稱:Spring中@Async注解執(zhí)行異步任務的方法
網(wǎng)站地址:http://chinadenli.net/article44/jigiee.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作、網(wǎng)站設計公司、域名注冊、微信小程序、手機網(wǎng)站建設、網(wǎng)站設計
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)