国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 開(kāi)發(fā) > Java > 正文

Spring中@Async注解執(zhí)行異步任務(wù)的方法

2024-07-14 08:41:10
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

引言

在業(yè)務(wù)處理中,有些業(yè)務(wù)使用異步的方式更為合理。比如在某個(gè)業(yè)務(wù)邏輯中,把一些數(shù)據(jù)存入到redis緩存中,緩存只是一個(gè)輔助的功能,成功或者失敗對(duì)主業(yè)務(wù)并不會(huì)產(chǎn)生根本影響,這個(gè)過(guò)程可以通過(guò)異步的方法去進(jìn)行。

Spring中通過(guò)在方法上設(shè)置@Async注解,可使得方法被異步調(diào)用。也就是說(shuō)該方法會(huì)在調(diào)用時(shí)立即返回,而這個(gè)方法的實(shí)際執(zhí)行交給Spring的TaskExecutor去完成。

代碼示例

項(xiàng)目是一個(gè)普通的Spring的項(xiàng)目,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í)行異步任務(wù)的線(xiàn)程池TaskExecutor --> <task:executor id="myexecutor" pool-size="5" /> <task:annotation-driven executor="myexecutor"/></beans>

兩個(gè)Service類(lèi):

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è)務(wù)Service */@Servicepublic 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()方法是會(huì)阻塞的  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;/** * 緩存服務(wù) */@Servicepublic class CacheService { private static final Logger log = LoggerFactory.getLogger(CacheService.class); @Async(value = "myexecutor") //指定執(zhí)行任務(wù)的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");  //返回的結(jié)果需要通過(guò)AsyncResult這個(gè)類(lèi)包裝  return new AsyncResult<>("Async operation success"); }}

測(cè)試類(lèi):

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();  //不讓主線(xiàn)程過(guò)早結(jié)束,否則控制臺(tái)看不到異步方法中的輸出內(nèi)容  TimeUnit.SECONDS.sleep(5L);   } @Test public void testAsyncReturn() throws Exception {  businessService.doBusinessWithAsyncReturn();  TimeUnit.SECONDS.sleep(5L); }}

執(zhí)行test()方法的結(jié)果:

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()方法的結(jié)果:

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的使用注意點(diǎn)

  1. 返回值:不要返回值直接void;需要返回值用AsyncResult或者CompletableFuture
  2. 可自定義執(zhí)行器并指定例如:@Async("otherExecutor")
  3. @Async必須不同類(lèi)間調(diào)用: A類(lèi)—>B類(lèi).C方法()(@Async注釋在B類(lèi)/方法中),如果在同一個(gè)類(lèi)中調(diào)用,會(huì)變同步執(zhí)行,例如:A類(lèi).B()—>A類(lèi).@Async C()。
  4. @Async也可以加到類(lèi),表示這個(gè)類(lèi)的所有方法都是異步執(zhí)行,并且方法上的注解會(huì)覆蓋類(lèi)上的注解。但一般不這么用!

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VeVb武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到JAVA教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 莒南县| 合作市| 石家庄市| 乌拉特中旗| 垣曲县| 金门县| 许昌县| 山东| 榕江县| 禹州市| 德格县| 青阳县| 云林县| 齐齐哈尔市| 镇原县| 山阴县| 东乡县| 聊城市| 余庆县| 阿图什市| 井冈山市| 龙岩市| 五台县| 卫辉市| 濮阳县| 台中市| 微山县| 丰镇市| 牟定县| 金门县| 波密县| 栖霞市| 大邑县| 赣榆县| 水富县| 吴桥县| 拉萨市| 西充县| 栖霞市| 酒泉市| 鹤山市|