如何让spring boot@Async与Java 8协同工作
我正在尝试异步调用一个方法。但不知怎么的,它不起作用。有人能帮我解决这个问题吗 我的主要切入点是:如何让spring boot@Async与Java 8协同工作,java,spring,multithreading,spring-boot,java-8,Java,Spring,Multithreading,Spring Boot,Java 8,我正在尝试异步调用一个方法。但不知怎么的,它不起作用。有人能帮我解决这个问题吗 我的主要切入点是: @SpringBootApplication @EnableAsync public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); AsyncService asyncS
@SpringBootApplication
@EnableAsync
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
AsyncService asyncService = new AsyncService();
asyncService.asyncMethod();
asyncService.asyncMethod();
}
}
异步服务:
@Component
public class AsyncService {
@Async
public void asyncMethod(){
log.info("starting...");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("ending...");
}
}
最后,在日志中,我希望:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.2.RELEASE)
2019-02-13 17:52:41.548 INFO 85734 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication on mntbden00122972 with PID 85734 (/Users/h3560/demo/target/classes started by h3560 in /Users/h3560/demo)
2019-02-13 17:52:41.550 INFO 85734 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default
2019-02-13 17:52:42.084 INFO 85734 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 0.76 seconds (JVM running for 1.329)
2019-02-13 17:52:42.086 INFO 85734 --- [ main] com.example.demo.services.AsyncService : starting...
2019-02-13 17:52:44.088 INFO 85734 --- [ main] com.example.demo.services.AsyncService : ending...
2019-02-13 17:52:44.089 INFO 85734 --- [ main] com.example.demo.services.AsyncService : starting...
2019-02-13 17:52:46.091 INFO 85734 --- [ main] com.example.demo.services.AsyncService : ending...
@Async
是spring的注释,应用于代理上的public
方法(这就是为什么它们需要是公共的)。自我调用不起作用
在您的示例中,您没有使用spring的依赖项注入机制,因此没有创建代理。要绕过它,您需要在执行之前从中生成一个@Bean
(通过使用@Component
对其进行注释)和@Autowire
它:
@SpringBootApplication
@EnableAsync
public class DemoApplication {
@Autowired
AsyncService asyncService;
public someMethod() {
SpringApplication.run(DemoApplication.class, args);
asyncService.asyncMethod();
asyncService.asyncMethod();
}
}
使用这个spring,AOP可以将组件包装到代理中,并异步执行该方法。您遇到的问题是如何通过
new
操作符手动实例化对象。这不会让框架有机会将对象包装到代理中。如果要使用异步方法,必须使用SpringDI工厂方法、@Autowired
(或@Inject
)或使用XML配置
如果你这样做,你可以制作
System.out.println(obj.getClass())
,看看注入DI的引擎盖下的bean不是你在那里使用的类,而是一个代理类。你在上下文中有Executor
类型的bean吗?没有,这是一个来自start.spring.io的全新演示项目。您可以在一个配置文件中创建一个吗?我将在答案中键入你是如何做的,因为它在这里不合适/看起来很难看。我试图理解为什么这不起作用。如果我没有提供我的执行器,Spring会提供一个简单的执行器。你可以列出你的bean,看看它是否在上下文中。我见过一些情况,春天不会提供它应该有的豆子。或者它可能定义了一个执行器,其池大小为1。值得一试。这不是重复我的回答吗?一切都已经准备好了,不完全是这样。答案是同步的。