Java @Groovy中的异步不是异步

Java @Groovy中的异步不是异步,java,asynchronous,groovy,spring-boot,Java,Asynchronous,Groovy,Spring Boot,我的任务是使数据库写入异步。表面上听起来很简单,但我在网上得到的信息并没有那么有用,我从同事那里听到的是“异步很棘手”。所以,我希望得到一些比“玩一玩,直到你让它工作”更有用的东西。我的代码/调用如下所示:` @EnableAsync @SpringCloudApplication //To run as a FAT JAR: //public class Application { // Only extend when running as WAR public class Applicat

我的任务是使数据库写入异步。表面上听起来很简单,但我在网上得到的信息并没有那么有用,我从同事那里听到的是“异步很棘手”。所以,我希望得到一些比“玩一玩,直到你让它工作”更有用的东西。我的代码/调用如下所示:`

@EnableAsync
@SpringCloudApplication
//To run as a FAT JAR:
//public class Application {
// Only extend when running as WAR
public class Application extends SpringBootServletInitializer {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }} 

public class MyClass{
    public void asyncCall(){
        if(1==1){
            DatabaseWriter.testAsync();
            System.out.println("past DatabaseWriter.testAsync() method");
            return;
        }
    }}

public class DatabaseWriter {
    @Async
    public static Future<Object> testAsync(){
        Thread.sleep(10000);
        println ("end of DatabaseWriter.testAsync() method");
        return null;
    }}

显然,原始方法调用正在等待testAsync()方法的返回。我正在寻找我做错了什么的方向。

@Async注释只适用于来自spring上下文的bean,因为spring围绕Async方法创建代理。因此,如果您使用新关键字创建bean:

new DatabaseWriter();
或者,如果将@Async注释放在静态方法上,它将不起作用,因为将有原始方法而不是代理

这个例子很有效。要启动应用程序,只需运行main方法

@SpringBootApplication
@EnableAsync
public class Application extends AsyncConfigurerSupport {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

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

@Component
class AppRunner implements CommandLineRunner {

    public static final Logger logger = LoggerFactory.getLogger(AppRunner2.class);
    @Autowired
    private DatabaseWriter writer;

    @Override
    public void run(String... args) throws Exception {
        logger.info("---  start ---");
        writer.testAsync();
        logger.info("--- stop ---");
    }
}

@Component
class DatabaseWriter {
    @Async
    public Future<Object> testAsync() throws InterruptedException {
        Thread.sleep(5000);
        AppRunner.logger.info("end of DatabaseWriter.testAsync() method");
        return null;
    }
}


并且将看到@Async不起作用。

在WyMuT CoCHa和一些进一步的研究之间,我发现问题不仅仅在于@Async注释,而是带有该注释的类必须是一个bean,因此调用类没有创建带有“new”关键字的实例。我仍然不完全理解,但这让我更接近,我的代码也能正常工作。
@SpringBootApplication
@EnableAsync
public class Application extends AsyncConfigurerSupport {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

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

@Component
class AppRunner implements CommandLineRunner {

    public static final Logger logger = LoggerFactory.getLogger(AppRunner2.class);
    @Autowired
    private DatabaseWriter writer;

    @Override
    public void run(String... args) throws Exception {
        logger.info("---  start ---");
        writer.testAsync();
        logger.info("--- stop ---");
    }
}

@Component
class DatabaseWriter {
    @Async
    public Future<Object> testAsync() throws InterruptedException {
        Thread.sleep(5000);
        AppRunner.logger.info("end of DatabaseWriter.testAsync() method");
        return null;
    }
}
writer.testAsync();
   new DatabaseWriter().testAsync();