AnnotationConfigServletWebServerApplicationContext - 上下文初始化期间遇到异常 - 取消刷新尝试

问题描述 投票:0回答:1

如果我在 LocalCosmosDBConfig.java 中取消注释 cosmosAsyncClient 方法,则会收到以下警告。如果我在同一文件中取消注释 cosmosConfig 方法,则会收到类似的警告。应用程序是使用java、akka框架和azure cosmos DB开发的。应用程序最终在警告后抛出以下错误,甚至无法启动。

CosmosDBConfig.java

@Slf4j
@Configuration
@ConditionalOnProperty("condition")
public abstract class CosmosDBConfig extends AbstractCosmosConfiguration {

    protected final CosmosProperties cosmosProperties;

    protected CosmosDBConfig(CosmosProperties cosmosProperties) {
        this.cosmosProperties = cosmosProperties;
    }

    @Override
    public CosmosConfig cosmosConfig() {
        return CosmosConfig.builder()
            .enableQueryMetrics(cosmosProperties.isQueryMetricsEnabled())
            .responseDiagnosticsProcessor(
                responseDiagnostics -> log.info("{} Response Diagnostics {}",
                    getClassName(), responseDiagnostics
                ))
            .build();
    }

    protected CosmosClientBuilder cosmosClientBuilder() {
        CosmosClientBuilder builder = createCosmosClientBuilder();
        setCosmosCredentials(builder);
        return builder;
    }

    @Override
    public CosmosAsyncClient cosmosAsyncClient(CosmosClientBuilder cosmosClientBuilder) {
        return CosmosFactory.createCosmosAsyncClient(cosmosClientBuilder);
    }

    protected void setCosmosCredentials(CosmosClientBuilder builder) {
        if (StringUtils.hasText(getKey())) {
            log.info("Connecting to Cosmos DB using Azure Key Credentials");
            builder.credential(new AzureKeyCredential(getKey()));
        } else {
            log.info("Connecting to Cosmos DB using Azure Token Credentials");
            builder.credential(new DefaultAzureCredentialBuilder().build());
        }
    }

    protected String getClassName() {
        return this.getClass().getSimpleName().replaceAll("\\$.*", "");
    }

    // Children classes will need to implement creation of cosmosClientBuilder with required properties needed for its unique connection
    abstract CosmosClientBuilder createCosmosClientBuilder();

    // Children classes will need to implement how to retrieve its unique connection's key
    abstract String getKey();
}

LocalCosmosDBConfig.java

@Slf4j
@Configuration
@ConditionalOnProperty("condition")
@EnableReactiveCosmosRepositories(basePackages = "com.example.repository",
    reactiveCosmosTemplateRef = "localDatabaseTemplate")
public class LocalCosmosDBConfig extends CosmosDBConfig {

    private static final String LOCAL_COSMOS_CLIENT_BUILDER = "localCosmosClientBuilder";
    private static final String LOCAL_COSMOS_ASYNC_CLIENT = "localCosmosAsyncClient";
    private static final String LOCAL_COSMOS_CONFIG = "localCosmosConfig";

    @Value("${azure.cosmos.regions}")
    private List<String> regions;

    @Value("${azure.cosmos.endpoint-discovery-enabled}")
    private boolean endpointDiscoveryEnabled;

    public LocalCosmosDBConfig(CosmosProperties cosmosProperties) {
        super(cosmosProperties);
    }

    @Override
    protected CosmosClientBuilder createCosmosClientBuilder() {
        log.info("Building {} Cosmos DB Connection for: {}", getClassName(),
            cosmosProperties.getLocalUri()
        );

        return new CosmosClientBuilder().endpoint(cosmosProperties.getLocalUri())
            .gatewayMode(new GatewayConnectionConfig())
            .preferredRegions(regions)
            .endpointDiscoveryEnabled(endpointDiscoveryEnabled);
    }

    @Override
    protected String getKey() {
        return cosmosProperties.getLocalKey();
    }

    @Override
    @Primary
    @Bean(LOCAL_COSMOS_CLIENT_BUILDER)
    public CosmosClientBuilder cosmosClientBuilder() {
        return super.cosmosClientBuilder();
    }

//  @Override
//  @Primary
//  @Bean(LOCAL_COSMOS_ASYNC_CLIENT)
//  public CosmosAsyncClient cosmosAsyncClient(
//      @Qualifier(LOCAL_COSMOS_CLIENT_BUILDER) CosmosClientBuilder cosmosClientBuilder) {
//      log.info("Building {} Cosmos Async Client for: {}", getClassName(), cosmosProperties.getLocalUri());
//      return super.cosmosAsyncClient(cosmosClientBuilder);
//  }

//  @Override
//  @Primary
//  @Bean(LOCAL_COSMOS_CONFIG)
//  public CosmosConfig cosmosConfig() {
//      return super.cosmosConfig();
//  }

    @Bean
    public ReactiveCosmosTemplate localDatabaseTemplate(
//      @Qualifier(LOCAL_COSMOS_ASYNC_CLIENT) CosmosAsyncClient cosmosAsyncClient,
//      @Qualifier(LOCAL_COSMOS_CONFIG) CosmosConfig cosmosConfig,
        CosmosAsyncClient cosmosAsyncClient,
        CosmosConfig cosmosConfig,
        MappingCosmosConverter mappingCosmosConverter) {
        return new ReactiveCosmosTemplate(cosmosAsyncClient, cosmosProperties.getLocalDatabase(), cosmosConfig,
            mappingCosmosConverter
        );
    }

    @Override
    protected String getDatabaseName() {
        return cosmosProperties.getLocalDatabase();
    }

    @Bean
    public CosmosAsyncContainer buildCloudBufferAsyncContainer(
//      @Qualifier(LOCAL_COSMOS_ASYNC_CLIENT) CosmosAsyncClient cosmosAsyncClient
        CosmosAsyncClient cosmosAsyncClient
    ) {
        CosmosAsyncDatabase database = cosmosAsyncClient.getDatabase(this.getDatabaseName());
        return database.getContainer(VehicleCloudEventsContainerName);
    }
}

[警告] - [org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext] - 上下文初始化期间遇到异常 - 取消刷新尝试:org.springframework.beans.factory.BeanCreationException:创建名称为“cosmosAsyncClient”的 bean 时出错在类路径资源 [com/example/dispatcher/configuration/LocalCosmosDBConfig.class] 中:在类 [com.example.dispatcher.configuration.LocalCosmosDBConfig] 上找不到匹配的工厂方法:工厂 bean 'localCosmosDBConfig';工厂方法“cosmosAsyncClient()”。检查具有指定名称的方法是否存在并且它是非静态的。

[错误] - [akka.actor.SupervisorStrategy] - 创建名为“defaultValidator”的 bean 时出错:当该工厂的单例处于销毁状态时,不允许创建单例 bean(不要在销毁方法实现中从 BeanFactory 请求 bean! ) akka.actor.ActorInitializationException:akka://dispatcher/user/outboundStreamActor-1:创建期间出现异常,根本原因消息:[创建名称为“defaultValidator”的 bean 时出错:该工厂的单例正在销毁时不允许创建单例 bean(不要在 destroy 方法实现中从 BeanFactory 请求 bean!)]

akka azure-cosmosdb
1个回答
0
投票

在我发布问题的当天修复了这个问题,但现在在 stackoverflow.com 上回答。不重写方法解决了问题。这是工作代码。

CosmosDBConfig.java

public abstract class CosmosDBConfig extends AbstractCosmosConfiguration {
    protected static final String MAPPING_COSMOS_CONVERTER = "mappingCosmosConverter";

    @Override
    @Bean(MAPPING_COSMOS_CONVERTER)
    public MappingCosmosConverter mappingCosmosConverter(CosmosMappingContext cosmosMappingContext) {
        // object mapper
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        mapper.registerModule(JsonFormat.getCloudEventJacksonModule(true, false));
        mapper.registerModule(new JavaTimeModule());
        mapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);
        return new MappingCosmosConverter(cosmosMappingContext, mapper);
    }
}

LocalCosmosDBConfig.java

@RequiredArgsConstructor
@Configuration
@Slf4j
@ConditionalOnProperty("dispatcher.inbound-vehicle.enabled")
@EnableReactiveCosmosRepositories(basePackages = "com.gm.ultifi.rs.dispatcher.repository.local", reactiveCosmosTemplateRef = "localDatabaseTemplate")
public class LocalCosmosDBConfig extends CosmosDBConfig {
    private static final String LOCAL_COSMOS_CLIENT_BUILDER = "localCosmosClientBuilder";
    private static final String LOCAL_COSMOS_ASYNC_CLIENT = "localCosmosAsyncClient";
    private static final String LOCAL_COSMOS_CONFIG = "localCosmosConfig";
    private final @Qualifier("defaultAzureCredential") TokenCredential defaultAzureCredential;
    @Value("${cosmos.local.source.database.endpoint}")
    private String uri;
    @Value("${cosmos.local.source.database.name}")
    private String dbName;

    @Primary
    @Bean(LOCAL_COSMOS_CLIENT_BUILDER)
    public CosmosClientBuilder getCosmosClientBuilder() {
        log.info("Building Cosmos DB Connection for: {}", uri);
        var cosmosClientBuilder = new CosmosClientBuilder()
                .endpoint(uri)
                .gatewayMode(new GatewayConnectionConfig());
        setAzureCredentials(cosmosClientBuilder);
        return cosmosClientBuilder;
    }

    private void setAzureCredentials(CosmosClientBuilder cosmosClientBuilder) {
        log.info("Connecting to Cosmos DB using Managed Identity Token Credentials");
        cosmosClientBuilder.credential(defaultAzureCredential);
    }

    @Primary
    @Bean(LOCAL_COSMOS_ASYNC_CLIENT)
    public CosmosAsyncClient getCosmosAsyncClient(
            @Qualifier(LOCAL_COSMOS_CLIENT_BUILDER) CosmosClientBuilder cosmosClientBuilder) {
        log.info("Building {} Cosmos Async Client for: {}", "LocalCosmosDBConfig", uri);
        return super.cosmosAsyncClient(cosmosClientBuilder);
    }

    @Primary
    @Bean(LOCAL_COSMOS_CONFIG)
    public CosmosConfig getCosmosConfig() {
        return super.cosmosConfig();
    }

    @Bean
    public ReactiveCosmosTemplate localDatabaseTemplate(
            @Qualifier(LOCAL_COSMOS_ASYNC_CLIENT) CosmosAsyncClient cosmosAsyncClient,
            @Qualifier(LOCAL_COSMOS_CONFIG) CosmosConfig cosmosConfig,
            @Qualifier(MAPPING_COSMOS_CONVERTER) MappingCosmosConverter mappingCosmosConverter) {
        return new ReactiveCosmosTemplate(cosmosAsyncClient, dbName, cosmosConfig,
                mappingCosmosConverter
        );
    }

    @Override
    public String getDatabaseName() {
        return dbName;
    }
}

GlobalCosmosDBConfig.java

@RequiredArgsConstructor
@Configuration
@Slf4j
@ConditionalOnProperty("dispatcher.inbound-vehicle.enabled")
@EnableReactiveCosmosRepositories(basePackages = "com.gm.ultifi.rs.dispatcher.repository.global", reactiveCosmosTemplateRef = "globalDatabaseTemplate")
public class GlobalCosmosDBConfig extends CosmosDBConfig {
    private static final String GLOBAL_COSMOS_CLIENT_BUILDER = "globalCosmosClientBuilder";
    private static final String GLOBAL_COSMOS_ASYNC_CLIENT = "globalCosmosAsyncClient";
    private static final String GLOBAL_COSMOS_CONFIG = "globalCosmosConfig";
    private final @Qualifier("defaultAzureCredential") TokenCredential defaultAzureCredential;
    @Value("${cosmos.global.source.database.endpoint}")
    private String uri;
    @Value("${cosmos.global.source.database.name}")
    private String dbName;
    @Value("${cosmos.pref-regions}")
    private String regions;

    @Bean(GLOBAL_COSMOS_CLIENT_BUILDER)
    public CosmosClientBuilder getCosmosClientBuilder() {
        log.info("Building Cosmos DB Connection for: {}", uri);
        var cosmosClientBuilder = new CosmosClientBuilder()
                .endpoint(uri)
                .preferredRegions(Arrays.asList(regions.split(",")))
                .endpointDiscoveryEnabled(true)
                .gatewayMode(new GatewayConnectionConfig());
        setAzureCredentials(cosmosClientBuilder);
        return cosmosClientBuilder;
    }

    private void setAzureCredentials(CosmosClientBuilder cosmosClientBuilder) {
        log.info("Connecting to Cosmos DB using Managed Identity Token Credentials");
        cosmosClientBuilder.credential(defaultAzureCredential);
    }

    @Bean(GLOBAL_COSMOS_ASYNC_CLIENT)
    public CosmosAsyncClient getCosmosAsyncClient(
            @Qualifier(GLOBAL_COSMOS_CLIENT_BUILDER) CosmosClientBuilder cosmosClientBuilder) {
        log.info("Building {} Cosmos Async Client for: {}", "GlobalCosmosDBConfig", uri);
        return super.cosmosAsyncClient(cosmosClientBuilder);
    }

    @Bean(GLOBAL_COSMOS_CONFIG)
    public CosmosConfig getCosmosConfig() {
        return super.cosmosConfig();
    }

    @Bean
    public ReactiveCosmosTemplate globalDatabaseTemplate(
            @Qualifier(GLOBAL_COSMOS_ASYNC_CLIENT) CosmosAsyncClient cosmosAsyncClient,
            @Qualifier(GLOBAL_COSMOS_CONFIG) CosmosConfig cosmosConfig,
            @Qualifier(MAPPING_COSMOS_CONVERTER) MappingCosmosConverter mappingCosmosConverter) {
        return new ReactiveCosmosTemplate(cosmosAsyncClient, dbName, cosmosConfig,
                mappingCosmosConverter
        );
    }

    @Override
    public String getDatabaseName() {
        return dbName;
    }

    @Bean
    public CosmosAsyncContainer buildCloudBufferAsyncContainer(
            @Qualifier(GLOBAL_COSMOS_ASYNC_CLIENT) CosmosAsyncClient cosmosAsyncClient) {
        CosmosAsyncDatabase database = cosmosAsyncClient.getDatabase(getDatabaseName());
        return database.getContainer(VehicleCloudEventsContainerName);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.