首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring无法扫描MongoRepository

Spring无法扫描MongoRepository
EN

Stack Overflow用户
提问于 2022-07-18 16:44:22
回答 4查看 116关注 0票数 1

我有一个实现MongoRepository接口的持久接口,如下所示:

代码语言:javascript
复制
package org.prithvidiamond1.DB.Repositories;

import org.prithvidiamond1.DB.Models.SomeModel;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ServerRepository extends MongoRepository<SomeModel, String> {
}

尽管如此,我仍然得到以下错误:

代码语言:javascript
复制
Exception encountered during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'botApplication': 
Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type 'org.prithvidiamond1.DB.Repositories.ServerRepository' available: expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations: {}


PPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in org.prithvidiamond1.BotApplication required a bean of type 'org.prithvidiamond1.DB.Repositories.ServerRepository' that could not be found.


Action:

Consider defining a bean of type 'org.prithvidiamond1.DB.Repositories.ServerRepository' in your configuration.

我尝试过许多解决方案(自定义@ComponentScan、使用@Service而不是@Component等)。我在网上发现,但没有人能帮我解决这个问题,有人能不能向我解释一下是怎么回事,我该如何解决这个问题?

注意:目录结构如下(这不是完整的目录结构,但我认为这应该足够了解):

代码语言:javascript
复制
org.prithvidiamond1
   |
   +--BotApplication.java
   |
   +--DB
      |
      +--Repository
      |
      +--ServerRepository.java

BotApplication.java看起来如下:

代码语言:javascript
复制
package org.prithvidiamond1;

import org.jc.api.Api;
import org.jc.api.ApiBuilder;
import org.jc.api.entity.server.Server;
import org.prithvidiamond1.DB.Models.Server;
import org.prithvidiamond1.DB.Repositories.ServerRepository;
import org.slf4j.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.Collection;

@Component
public class BotApplication {
    private final Api api;
    private final ServerRepository serverRepository;

    public BotApplication(ServerRepository serverRepository, Logger logger){
        String botToken = System.getenv().get("BOT_TOKEN");

        this.api = new ApiBuilder();

        this.serverRepository = serverRepository;

        appRuntime(logger);
    }

    public void appRuntime(Logger logger){
        logger.info("Bot has started!");

        // Handling server entries in the database
        if (this.serverRepository.findAll().isEmpty()) {
            logger.trace("server data repository empty, initializing data repository...");
            Collection<Server> servers = api.getServers();
            for (Server server : servers) {
                this.serverRepository.save(new Server(String.valueOf(server.getId())));
            }
            logger.trace("server data repository initialized");
        }
    }

    @Bean
    public Api getApi() {
        return this.api;
    }
}

编辑:下面是一个包含所有代码的存储库的链接:https://github.com/prithvidiamond1/DiamondBot/tree/springboot-restructure

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2022-07-20 21:30:22

问题在于您正在使用主源类(BotApplication.class)在启动过程中执行自定义代码。

代码语言:javascript
复制
    public static void main(String[] args) {
        ApplicationContext AppContext = SpringApplication.run(BotApplication.class, args);
    }

    public BotApplication(DiscordServerRepository serverRepository, Logger logger){
        ...
        appRuntime(logger);
    }

它不是一个使用存储库或任何启动代码的好地方。

SpringApplication.run方法中,只需要传递提供bean定义的类。这些是@配置类。

参见最佳实践在Spring启动后运行代码

我描述了最好的解决方案之一: ApplicationRunner

  1. BotApplication类必须实现ApplicationRunner接口。该接口用于指示当bean包含在SpringApplication中时,它应该运行。 在run方法中执行所有启动代码。
代码语言:javascript
复制
@Component
public class BotApplication implements ApplicationRunner {
    private final DiscordApi api;
    private final DiscordServerRepository serverRepository;

    private final Logger logger;

    public BotApplication(DiscordServerRepository serverRepository, Logger logger){
        String botToken = System.getenv().get("BOT_TOKEN");
        this.logger = logger;
        this.serverRepository = serverRepository;
        this.api = new DiscordApiBuilder()
                .setToken(botToken)
                .setAllIntents()
                .setWaitForServersOnStartup(true)
                .setWaitForUsersOnStartup(true)
                .login().exceptionally(exception -> {    // Error message for any failed actions from the above
                    logger.error("Error setting up DiscordApi instance!");
                    logger.error(exception.getMessage());
                    return null;
                })
                .join();
    }

    public void appRuntime(Logger logger){
        logger.info("Bot has started!");

        // Handling server entries in the database
        if (this.serverRepository.findAll().isEmpty()) {
            logger.trace("Bot server data repository empty, initializing data repository...");
            Collection<Server> servers = api.getServers();
            for (Server server : servers) {
                this.serverRepository.save(new DiscordServer(String.valueOf(server.getId()), Main.defaultGuildPrefix));
            }
            logger.trace("Bot server data repository initialized");
        }
    }

    @Bean
    public DiscordApi getApi() {
        return this.api;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        appRuntime(logger);
    }
}
  1. Main.class传递给SpringApplication.run
代码语言:javascript
复制
@SpringBootApplication
@EnableMongoRepositories
public class Main {
    public static void main(String[] args) {
        ApplicationContext AppContext = SpringApplication.run(Main.class, args);
    }
}
票数 1
EN

Stack Overflow用户

发布于 2022-07-18 18:30:50

类的构造函数中使用注解@Autowired,如下所示-

代码语言:javascript
复制
@Autowired
public BotApplication(ServerRepository serverRepository, Logger logger){
        String botToken = System.getenv().get("BOT_TOKEN");

        this.api = new ApiBuilder();

        this.serverRepository = serverRepository;

        appRuntime(logger);
    }
票数 0
EN

Stack Overflow用户

发布于 2022-07-18 18:40:54

您需要在主应用程序类之上使用@EnableMongoRepositories来启用对mongo存储库bean的扫描。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73025814

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档