当前位置: 首页 > 知识库问答 >
问题:

Spring 3:如何从TaskExecutor调用@Async注释的方法

胡光霁
2023-03-14

我是Spring异步任务执行的新手,所以如果这听起来像个愚蠢的问题,请原谅我。

我读到,从Spring 3. x开始,在方法级别引入了@Async注释,以便异步调用该方法。我还了解到,我们可以在Spring配置文件中配置ThreadPoolTaskExecator。

我无法理解的是,如何从tak执行器调用@Async注释的方法让我们假设-AsyncTaskExecutor

早些时候,我们经常在课堂上做这样的事情:

@Autowired protected AsyncTaskExecutor executor;

然后

executor.submit(<Some Runnable or Callable task>)

我不能理解@Async注释方法和TaskExec导师之间的关系。

我试着在互联网上搜索了很多东西,但都找不到。

有人能举个例子吗。

共有3个答案

公羊玉泽
2023-03-14

在配置文件中,应该提到一个带有线程池名称的注释驱动任务,带有@Async(池名称)的方法将作为该池的一部分执行。这将为具有@Async注释的代理类创建一个代理类,并为每个线程执行它。

傅正阳
2023-03-14

完整示例

>

  • 配置Spring

    @Configuration        
    @EnableAsync        
    @ComponentScan("com.async")
    public class AppConfig {
    
        @Bean
        public AsyncManager asyncManger() {
            return new AsyncManager();
        }
    
        @Bean
        public AsyncExecutor asyncExecutor() {
            return new AsyncExecutor();
        }
    }
    

    创建了执行器类,我创建了执行器,以便Spring照顾线程管理。

    public class AsyncExecutor extends AsyncConfigurerSupport {
    
        @Override
        public Executor getAsyncExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(2);
            executor.setMaxPoolSize(2);
            executor.setQueueCapacity(500);
            executor.setThreadNamePrefix("Violation-");
            executor.initialize();
            return executor;
        }
    }
    

    创建一个经理。

    public class AsyncManager {
    
        @Autowired
        private AsyncService asyncService;
    
        public void doAsyncTask(){
            try {
                Map<Long, ViolationDetails> violation = asyncService.getViolation();
                if(!org.springframework.util.CollectionUtils.isEmpty(violation)){
                    violation.entrySet().forEach( violationEntry -> {System.out.println(violationEntry.getKey() +"" +violationEntry.getValue());});
                }
                System.out.println("do some async task");
            } catch (Exception e) {
            }
    
        }
    }
    

    配置您的服务类。

    @Service
    public class AsyncService {
    
        @Autowired
        private AsyncExecutor asyncExecutor;
    
        @Async
        public Map<Long,ViolationDetails> getViolation() {
            // TODO Auto-generated method stub
            List<Long> list = Arrays.asList(100l,200l,300l,400l,500l,600l,700l);
            Executor executor = asyncExecutor.getAsyncExecutor();
            Map<Long,ViolationDetails>  returnMap = new HashMap<>();
            for(Long estCode : list){
                ViolationDetails violationDetails = new ViolationDetails(estCode);
                returnMap.put(estCode, violationDetails);
                executor.execute((Runnable)new ViolationWorker(violationDetails));
            }
            return returnMap;       
        }
    }
    class ViolationWorker implements Runnable{
    
        private ViolationDetails violationDetails;
    
        public ViolationWorker(ViolationDetails violationDetails){
            this.violationDetails = violationDetails;
        }
    
        @Override
        public void run() {
            violationDetails.setViolation(System.currentTimeMillis());
            System.out.println(violationDetails.getEstablishmentID() + "    " + violationDetails.getViolation());
        }
    }
    

    模型。

    public class ViolationDetails {
        private long establishmentID;
        private long violation;
    
    
        public ViolationDetails(long establishmentID){
            this.establishmentID = establishmentID;
        }
    
        public long getEstablishmentID() {
            return establishmentID;
        }
        public void setEstablishmentID(long establishmentID) {
            this.establishmentID = establishmentID;
        }
        public long getViolation() {
            return violation;
        }
        public void setViolation(long violation) {
            this.violation = violation;
        }
    
    }
    

    测试运行

    public class AppTest {
        public static void main(String[] args) throws SQLException {
            AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
            ctx.register(AppConfig.class);
            ctx.refresh();
    
            AsyncManager task= ctx.getBean(AsyncManager.class);
            task.doAsyncTask();
        }
    }
    

  • 桓嘉谊
    2023-03-14

    下面是一个使用@Async的示例:

    @Async
    void doSomething() {
        // this will be executed asynchronously
    }
    

    现在从另一个类调用该方法,它将异步运行。如果需要返回值,请使用Future

    @Async
    Future<String> returnSomething(int i) {
        // this will be executed asynchronously
    }
    

    @AsyncTaskExecutor之间的关系是@Async在幕后使用TaskExecutor。从文档中:

    默认情况下,在方法上指定@Async时,将使用的执行器是提供给注释驱动元素的执行器,如上所述。但是,当需要指示在执行给定方法时应使用除默认值以外的执行器时,可以使用@Async注释的value属性。

    因此,要设置默认执行器,请将其添加到Spring配置中

    <task:annotation-driven executor="myExecutor" />
    

    或者使用特定的执行器进行一次使用尝试

    @Async("otherExecutor")
    

    看见http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/scheduling.html#scheduling-注释支持异步

     类似资料:
    • 我有两个模块,一个从rest模板调用另一个。(管理员调用notifServer)notifServer有一个用Async注释的方法。我想在该方法中抛出一个异常,但管理员获取响应太快,并且无法在admin中捕获异常方法。 我是spring和@Async进程的新成员。我已经尝试将响应主体从NotifServer映射到C的CompletableFuture。类 。但我仍然没有得到错误响应。 此代码来自管

    • 我在Spring Boot应用程序中使用应该异步运行的方法之一做了一个类。因为我读的方法应该是注释,而且我还必须运行一个bean。但是在Spring手册中http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html我没有找到任何信息或示例,如何在没有XML配置的情况下使用注释运行。

    • 下面的@Retryable代码适用于直接调用方法的情况,但通过@Async annotated method调用Retryable方法会引发异常。有什么建议吗? 这是我的服务课 这是Junit测试类 这里是Spring Boot应用程序类 例外如下。请对此提出任何建议。 retryWithException-0

    • 问题内容: 我在Spring Boot应用程序中使用一种应该异步运行的方法来做一个类。当我阅读方法时,应该加上注释,而且我还必须运行一个bean。但是在Spring手册http://docs.spring.io/spring/docs/current/spring- framework- reference/html/scheduling.html中, 我找不到任何信息或示例如何在没有XML配置的

    • 我有一个由tomcat运行的前端,我的后端处理由Mule运行。 例如, 你好世界html 你好世界js公司 我的触发器。Java语言 招呼xml 我的结果一直以错误的形式返回,这意味着它在JavaScript级别失败。 不太确定出了什么问题。 Tomcat正在本地主机8080上运行。