【问题标题】:Using JNOSQL (CDI Library) with Spring Boot - Bean not found将 JNOSQL(CDI 库)与 Spring Boot 一起使用 - 找不到 Bean
【发布时间】:2021-07-30 14:35:11
【问题描述】:

设置

我正在处理一个Spring Boot 项目,我们希望在该项目中使用DynamoDB
我们不想直接使用AWS 库,而是使用JNOSQL;此 API 允许通过选择不同的驱动程序轻松切换数据库,我们将来可能会这样做。

在我们的项目中,我按照this tutorial 中的说明和Key-Value DB (here) 的官方文档创建了一个小型独立配置类来测试库。

文档显示,一旦配置了数据库,我应该能够 @ProducesBucketManager,这将允许我在我的数据库服务中 @InjectKeyValueTemplate 写入数据库。

这些是CDI注解,我不太熟悉;这就是说,我知道@Inject是Spring可以理解的,而@Produces可能不是这种情况,可以用@Bean代替

问题

只要遵循文档,每当我尝试运行应用程序时,Spring 都会抱怨找不到 KeyValueTemplate bean:

Field template in com.max.backend.service.TestEntryService required a bean of type 'jakarta.nosql.mapping.keyvalue.KeyValueTemplate' that could not be found.

理所当然:我为BucketManager 声明一个bean,而不是KeyValueTemplate
请注意,the docs 显示了一个示例应用程序,其中创建了一个 SeContainer,鉴于我正在使用 Spring,我认为我不需要它。

我的预感

我认为这可能与 CDI 与 Spring 有关,当我 @Produces BucketManager 时,库以某种方式为 KeyValueTemplate 创建了一个 bean,但 Spring 看不到这个 bean。

理想情况下,我想要么完全使用 Spring,完全避免 CDI,要么找到一个全面且最小的解决方案来利用 KeyValueTemplate

我很惊讶我在网上没有找到太多关于这个的内容,这是一个非常成熟且有用的库,我发现 Spring 中的用法并不多。
如果你知道类似的库春天,请告诉我!!

我的代码

注意:KeyValue db(不适用于 Spring)的 JNOSQL 演示的完整示例,请参见 here

相关依赖build.gradle

 // Spring
 implementation 'org.springframework.boot:spring-boot-starter-web'
 compile group: 'org.springframework.boot', name: 'spring-boot-starter-validation', version: '2.3.5.RELEASE'

 // JNOSQL
 implementation group: 'org.eclipse.jnosql.artemis', name: 'artemis-key-value', version: '1.0.0-b1'
 implementation group: 'org.eclipse.jnosql.diana', name: 'dynamodb-driver', version: '1.0.0-b1'
 
 // JSON parsing
 implementation group: 'javax.json.bind', name: 'javax.json.bind-api', version: '1.0'
 implementation group: 'org.eclipse', name: 'yasson', version: '1.0.4'
 implementation group: 'org.glassfish', name: 'javax.json', version: '1.1'

 // For CDI (needed primarily for annotations)
 implementation group: 'javax', name: 'javaee-web-api', version: '8.0'

配置 MaxDatabase.java

package com.max.backend.service.jnosql;


import jakarta.nosql.Settings;
import jakarta.nosql.keyvalue.BucketManager;
import org.eclipse.jnosql.diana.dynamodb.keyvalue.DynamoDBBucketManagerFactory;
import org.eclipse.jnosql.diana.dynamodb.keyvalue.DynamoDBKeyValueConfiguration;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import java.util.HashMap;
import java.util.Map;

@Configuration
@ApplicationScoped
public class MyDatabase {

    private DynamoDBKeyValueConfiguration configuration;
    private DynamoDBBucketManagerFactory managerFactory;

    @PostConstruct
    public void initialize() {
        // Set up the DB
        configuration = new DynamoDBKeyValueConfiguration();
        Map<String, Object> settings = new HashMap<>();
        settings.put("dynamodb.endpoint", "http://localhost:8073");
        settings.put("dynamodb.region", "eu-west-1");
        settings.put("dynamodb.awsaccesskey", "myLocalKeyId");
        settings.put("dynamodb.secretaccess", "myLocalSecretAccessKey");
        managerFactory = configuration.get(Settings.of(settings));
    }

    @Produces // use @Bean instead?
    public BucketManager getManager() {
        return managerFactory.getBucketManager("initiatives");
    }
}

服务

package com.max.backend.service;

import com.max.backend.model.TestEntry;
import jakarta.nosql.mapping.keyvalue.KeyValueTemplate;
import org.springframework.stereotype.Service;

import javax.inject.Inject;
import java.util.Optional;

@Service
public class TestEntryService {

    @Inject
    private KeyValueTemplate template;

    public void put(TestEntry user) {
        template.put(user);
    }

    public Optional<TestEntry> find(String id) {
        return template.get(id, TestEntry.class);
    }
}

TestEntry 只是一个小 POJO,与我这里面临的问题无关)

【问题讨论】:

  • 在 Java 类中编写数据库配置是对过去 Spring 以 XML bean 声明为中心的回归。感谢上帝,那些日子已经一去不复返了!这仍然是一件事,但通常由框架在幕后完成。当然,除非你喜欢打字。在这种情况下,所有这些旧功能仍包含在 SB 中。

标签: java spring spring-boot spring-mvc jnosql


【解决方案1】:

我相信错误说明了一切,您需要创建@Bean KeyValueTemplate。请参阅https://docs.spring.io/spring-data/keyvalue/docs/current/reference/html/#key-value.template-configuration 以获取快速示例。

如您所想,Spring 中不需要 SeContainer。它是 CDI 的 WildFly 实现。但是,不是 WildFly 方面的专家,我相信该示例显示了如何使用 KeyValueTemplate keyValueTemplate = container.select(KeyValueTemplate.class).get(); 完成 CDI 配置(这与上面 URL 示例中的 @Beans 相同)

【讨论】:

    【解决方案2】:

    继续对事件的描述,我有一种感觉,你可能没有意识到你正在艰难地做事。

    也就是说,您不需要为数据库编写 Java 代码。 Spring Boot 提供了一项几乎与您尝试实现的功能完全相同的功能。虽然我对 JNOSQL 的经验很少,但我曾经构建过 Android 应用程序,所以我对 gradle 语法非常熟悉。

    因此,我可以自信地说,Spring Boot 原生的解决方案的工作量大致相同。

    我可以告诉你,使用 here 所见的 application.properties 文件将花费你每个数据库的四行代码,只要你保持基本配置。从那里开始,我们的想法是根据需要添加指令,并由您自行决定,因为我确信它也在 JNOSQL 中。

    看看上面的链接。我有一种感觉,一旦您意识到该功能在 Spring 中可用,您就会决定使用它。

    The first two videos linked here (and creator) are excellent sources on the subject.

    第二个其实是15视频播放列表,显示实际深度 内置配置系统。

    而且这些文件不只是配置数据库。事实上,Spring Boot 目前在微服务前端如此受欢迎的原因之一是因为所有配置都可以在一个配置文件中列出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-29
      • 2022-01-26
      • 2022-11-10
      • 2021-06-09
      • 2013-03-02
      • 2020-05-03
      • 2018-12-13
      • 2018-10-01
      相关资源
      最近更新 更多