Java Spring@EnableAsync打破了bean的初始化顺序?

Java Spring@EnableAsync打破了bean的初始化顺序?,java,spring,spring-boot,flyway,spring-async,Java,Spring,Spring Boot,Flyway,Spring Async,我想在SpringBoot应用程序中引入@Async方法(用于并行发送邮件)。 但是,当我将@EnableAsync注释放在应用程序的主@Configuration类(用@SpringBootApplication注释)上时,Flyway DB迁移会在执行DataSourceInitializer(为我的测试运行schema.sql和data.sql)之前执行 涉及“应迁移”数据库表的第一个操作失败 删除@EnableAsync会使一切恢复正常。为什么会发生这种情况?我如何解决(或解决问题) 更

我想在SpringBoot应用程序中引入
@Async
方法(用于并行发送邮件)。 但是,当我将
@EnableAsync
注释放在应用程序的主
@Configuration
类(用
@SpringBootApplication
注释)上时,Flyway DB迁移会在执行
DataSourceInitializer
(为我的测试运行schema.sql和data.sql)之前执行

涉及“应迁移”数据库表的第一个操作失败

删除
@EnableAsync
会使一切恢复正常。为什么会发生这种情况?我如何解决(或解决问题)

更新更多发现:
@enablesync(mode=AdviceMode.ASPECTJ)
保持数据库设置的原始顺序,但是
@Async
方法与调用线程在同一线程上运行。我还看到,Bean“objectPostProcessor”是在
@enablesync
不存在或使用
@enablesync(mode=AdviceMode.ASPECTJ)
时早期创建的(第三个Bean)。当只使用
@EnableAsync
时,这个bean的创建要晚得多

更新2虽然我还无法创建一个复制问题的最小项目,但当我在下面注释掉
@EnableWebSocketMessageBroker
时,我发现在受影响的应用程序中恢复了正确的数据库设置顺序:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer
{ 
  ...
}

如果存在
@EnableWebSocketMessageBroker
,Bean“webSocketConfig”是创建的第一个Bean(根据信息级控制台输出)。

结果是,在我的应用程序中同时存在
@enablesync
@EnableWebSocketMessageBroker
导致了所描述的效果

删除其中一个后,恢复了预期的行为,在这种情况下,
DataSourceInitializerPostProcessor
在flyway迁移发生之前创建了
DataSourceInitializer
,它触发了schema.sql和data.sql的执行

当两个注释都存在时,名为
internalAsyncAnnotationProcessor
BeanPostProcessor
的注册发生在注册
DataSourceInitializePostProcessor
之前

问题的原因是注册
internalAsyncAnnotationProcessor
导致创建
dataSource
bean作为副作用。这种副作用是由spring为执行
@Async
方法而寻找要使用的
TaskExecutor
bean引起的。spring意外地获取了
clientInboundChannelExecutor
bean,该bean由于
@EnableWebSocketMessageBroker
而存在。使用这个bean导致了
WebSocketMessagingAutoConfiguration
的实例化,它创建了
objectMapper
bean(用于json序列化),该bean使用依赖于
数据源的DAO存储库的服务。所有这些豆子都被创造出来了

因为当时甚至没有注册
DataSourceInitializerPostProcessor
DataSourceInitializer
是在flyway迁移发生之后创建的

@EnableAsync
的javadoc说明如下:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer
{ 
  ...
}
默认情况下,SimpleAsyncTaskExecutor将用于处理异步方法调用。此外,具有void返回类型的带注释方法不能将任何异常传输回调用方。默认情况下,仅记录此类未捕获的异常

我假设将创建一个
SimpleAsyncTaskExecutor
来运行
@Async
方法,但是spring选择了一个具有匹配类型的现有bean

因此,这个问题的解决方案是实现
异步配置器
,并提供我自己的
执行器
。这在
@EnableAsync
的javadoc中也有建议:

要自定义所有这些,请实施AsyncConfigurer并提供: *通过getAsyncExecutor()方法创建您自己的执行器,以及 *通过getAsyncUncaughtExceptionHandler()方法创建您自己的AsyncUncaughtExceptionHandler


通过此调整,DB设置再次按预期执行。

Flyway是否有任何错误?如何确保async stuff仅在迁移完成后运行?请查看我的更新。实际上,迁移似乎很好,整个数据库稍后会重新创建。我不理解这个问题。在尝试使用数据库之前,需要运行迁移代码。为什么要“异步”运行它?不,我不想异步运行任何数据库内容。我想做的异步工作是发送电子邮件。但是,当我在主配置上引入
@EnableAsync
时,迁移是在数据库设置之前尝试的。让我知道问题的哪一部分让人困惑,我会尽力纠正。症状不一样,但我想知道是否是由