簡體   English   中英

Spring Boot 無法掃描 MongoRepository

[英]Spring Boot unable to scan MongoRepository

我有一個實現MongoRepository接口的持久性接口,如下所示:

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> {
}

盡管如此,我仍然收到以下錯誤:

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等)我在互聯網上找到但沒有一個可以幫助我解決問題,有人可以向我解釋什么是錯誤的以及我應該如何解決這個問題?

注意:目錄結構如下(這不是完整的目錄結構,但我想這應該足夠了解了):

org.prithvidiamond1
   |
   +--BotApplication.java
   |
   +--DB
      |
      +--Repository
      |
      +--ServerRepository.java

BotApplication.java如下所示:

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

使用注釋@Autowired和 BotApplication 類的構造函數,如下所示 -

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

        this.api = new ApiBuilder();

        this.serverRepository = serverRepository;

        appRuntime(logger);
    }

您需要在主應用程序類之上使用 @EnableMongoRepositories 來啟用對 mongo 存儲庫 bean 的掃描。

您已經在應用程序中創建了Repository bean (ServerRepository)。

但是在您的BotApplication組件(它本身是一個 bean)中,您並沒有告訴 spring 注入Repository bean 的依賴項(即 Dependancy Injection)。

這種依賴注入可以通過構造函數、基於字段或基於設置器的方法來實現。

您可以從public BotApplication(ServerRepository serverRepository, Logger logger)構造函數中刪除ServerRepository serverRepository & 只需使用:

@Autowired
private final ServerRepository serverRepository;

或者作為其他答案建議,在構造函數本身中使用 @Autowired 並刪除字段ServerRepository serverRepository

`
@Autowired
public BotApplication(ServerRepository serverRepository, Logger logger)
`

請注意,這里this.serverRepository = serverRepository; 在構造函數中也不需要,因為依賴注入會解決這個問題。

問題是您正在使用主要源類( BotApplication.class )在啟動期間執行自定義代碼。

    public static void main(String[] args) {
        ApplicationContext AppContext = SpringApplication.run(BotApplication.class, args);
    }

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

SpringApplication.run方法中,您只需要傳遞提供 bean 定義的類。 這些是@Configuration類。 這不是使用存儲庫或任何啟動代碼的好地方。
查看最佳實踐Spring Boot 啟動后運行代碼

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

  1. BotApplication類必須實現ApplicationRunner接口。 該接口用於指示 bean 在包含在SpringApplication中時應該運行。
    run方法中執行所有啟動代碼。
@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
@SpringBootApplication
@EnableMongoRepositories
public class Main {
    public static void main(String[] args) {
        ApplicationContext AppContext = SpringApplication.run(Main.class, args);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM