Amazon web services Spring Boot@Async不工作

Amazon web services Spring Boot@Async不工作,amazon-web-services,spring-boot,asynchronous,Amazon Web Services,Spring Boot,Asynchronous,我希望uploadImage方法在文件上传到AWS后完成,而scanFile方法仍在后台异步运行 @RestController public class EmailController { @PostMapping("/upload") @ResponseStatus(HttpStatus.OK) public void uploadImage(@RequestParam MultipartFile photos) { awsAPIService.upl

我希望
uploadImage
方法在文件上传到AWS后完成,而
scanFile
方法仍在后台异步运行

@RestController
public class EmailController {
    @PostMapping("/upload")
    @ResponseStatus(HttpStatus.OK)
    public void uploadImage(@RequestParam MultipartFile photos) {
        awsAPIService.uploadImage(photos);
    }
}

...
@Service
public class AwsAPIService {
    public void uploadImage(MultipartFile file) {
        try {
            File fileToUpload = this.convertMultiPartToFile(file);
            String fileName = this.generateFileName(file);
            s3client.putObject(new PutObjectRequest(AWS_S3_QUARANTINE_BUCKET_NAME,fileName, fileToUpload));
            fileToUpload.delete();
            // start scan file
            scanFile();
        } ...
    }

    @Async
    public void scanFile() {
        log.info("Start scanning");
        String queueUrl = sqs.getQueueUrl("bucket-antivirus").getQueueUrl();
        List<Message> messages = sqs.receiveMessage(new ReceiveMessageRequest().withQueueUrl(queueUrl)
                .withWaitTimeSeconds(20)).getMessages();
        for (Message message : messages) {
        // delete message
        ...
         }
     }
}


...
@EnableAsync
public class AppConfig {
    @Bean
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setMaxPoolSize(2);
        taskExecutor.setQueueCapacity(200);
        taskExecutor.afterPropertiesSet();
        return taskExecutor;
    }
}
@RestController
公共类电子邮件控制器{
@后映射(“/upload”)
@ResponseStatus(HttpStatus.OK)
public void uploadImage(@RequestParam MultipartFile photos){
上传图片(照片);
}
}
...
@服务
公共类自动售货机{
公共无效上载映像(多部分文件){
试一试{
File fileToUpload=this.convertMultiPartToFile(文件);
字符串文件名=this.generateFileName(文件);
s3client.putObject(新的PutObjectRequest(AWS_S3_隔离_BUCKET_名称、文件名、fileToUpload));
fileToUpload.delete();
//启动扫描文件
扫描文件();
} ...
}
@异步的
公共void扫描文件(){
日志信息(“开始扫描”);
字符串queueUrl=sqs.getQueueUrl(“bucket antivirus”).getQueueUrl();
List messages=sqs.receiveMessage(new ReceiveMessageRequest().withQueueUrl(queueUrl)
.withWaitTimeSeconds(20)).getMessages();
用于(消息:消息){
//删除消息
...
}
}
}
...
@使能同步
公共类AppConfig{
@豆子
公共任务执行器任务执行器(){
ThreadPoolTaskExecutor taskExecutor=新的ThreadPoolTaskExecutor();
taskExecutor.setMaxPoolSize(2);
taskExecutor.setQueueCapacity(200);
taskExecutor.AfterPropertieSet();
返回任务执行器;
}
}

但这似乎仍在同步运行。这里的问题是什么?

默认情况下
@Async
和其他Spring方法级别的注释,如
@Transactional
只在外部的bean-to-bean方法调用上工作。同一bean中从
uploadImage()
scanFile()
的内部方法调用不会触发实现Spring行为的代理。根据Spring文档:

在代理模式(这是默认模式)下,只截获通过代理传入的外部方法调用。这意味着自调用,实际上是目标对象内调用目标对象另一个方法的方法,即使调用的方法标记为@Transactional,在运行时也不会导致实际事务。此外,代理必须完全初始化以提供预期的行为,因此您不应在初始化代码中依赖此功能,即@PostConstruct


您可以将AspectJ配置为在内部方法调用上启用注释,但重构代码通常更容易。

谢谢,我可以问一下,我应该如何重构代码,使其成为
scanFile
方法的外部调用吗?@Cosaic一种方法是从
@Controller
调用
awsapiersevice.scanFile()
,就在
awsAPIService.uploadImage(photos)
之后。为什么通过将其从服务类移动到控制器类,不再将其视为内部调用?@Cosaic内部调用在同一个bean中的方法之间进行,两个不同bean之间的任何调用都是外部的。如果我在异步方法中添加另一个方法调用,这个方法是异步的吗?我是否仍应为该方法添加
@async