我正在春季靴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();
}
我的TestAsyncClass
:
public class TestAsyncClazz {
@Async
public void testAsyncMethod(){
System.err.println("Running async: "+ Thread.currentThread().getName());
}
}
当我检查打印行时,它表明我的两个方法都在同一线程上运行,并且没有使用threadNamePrefix Async Process-
:
Thread in controller: http-nio-8080-exec-2
Running async: http-nio-8080-exec-2
我做错了什么?我误会了吗?
答案 0 :(得分:1)
发生这种情况是因为您正在使用new
实例化自己的类上调用async方法:
TestAsyncClazz clazz = new TestAsyncClazz();
clazz.testAsyncMethod();
如果采用这种方式,Spring将没有机会用必要的代理类来装饰实例,该代理类提供了异步运行方法的实际功能。
这只会按照您对Spring bean的预期方式工作-换句话说,不要自己实例化TestAsyncClazz
;定义该类的Spring bean实例,将该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();
}
}