我正在spring-boot 2中测试@Async
,并遵循了一些在线教程
我的配置类:
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(5);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("Async Process-");
executor.initialize();
return executor;
}
}
我的控制器片段:
@GetMapping("/test/async")
public void testAsync() {
System.err.println("Thread in controller: " + Thread.currentThread().getName());
TestAsyncClazz clazz = new TestAsyncClazz();
clazz.testAsyncMethod();
}
我的<code>TestAsyncClass</code>:
public class TestAsyncClazz {
@Async
public void testAsyncMethod(){
System.err.println("Running async: "+ Thread.currentThread().getName());
}
}
当我检查打印行时,它显示我的两个方法都在同一个线程上运行,并且它没有使用threadNamePrefix<code>Async Process-
Thread in controller: http-nio-8080-exec-2
Running async: http-nio-8080-exec-2
我做错了什么?我误会什么了吗?
发生这种情况是因为您在使用new
实例化自己的类上调用async方法:
TestAsyncClazz clazz = new TestAsyncClazz();
clazz.testAsyncMethod();
如果您这样做,Spring就没有机会使用必要的代理类来装饰实例,该代理类提供了异步运行方法的实际功能。
这只会以您在Springbeans上期望的方式工作——换句话说,不要自己实例化TestAsyncClazz
;定义类的Springbean实例,将该bean自动连接到控制器中,然后调用bean上的方法。
示例:
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(5);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("Async Process-");
executor.initialize();
return executor;
}
// Define a Spring bean of type TestAsyncClazz
@Bean
public TestAsyncClazz testAsyncClazz() {
return new TestAsyncClazz();
}
}
@Controller
public class MyController {
// Inject the bean here
@Autowired
private TestAsyncClazz testAsyncClass;
@GetMapping("/test/async")
public void testAsync() {
System.err.println("Thread in controller: " +
Thread.currentThread().getName());
// Use the bean instead of instantiating the class yourself
testAsyncClass.testAsyncMethod();
}
}