[英]Spring Boot unable to scan MongoRepository
I have a persistance interface that implements MongoRepository
interface that looks as follows:我有一个实现
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> {
}
Despite this, I keep getting the following error:尽管如此,我仍然收到以下错误:
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.
I have tried many solutions (custom @ComponentScan
, using @Service
instead of @Component
, etc.) I found on the internet but none could help me solve the problem, can someone explain to me what is wrong and how I should fix this?我尝试了很多解决方案(自定义
@ComponentScan
,使用@Service
而不是@Component
等)我在互联网上找到但没有一个可以帮助我解决问题,有人可以向我解释什么是错误的以及我应该如何解决这个问题?
Note: The directory structure is as follows (this is not the full directory structure, but I think this should be enough to get an idea):注意:目录结构如下(这不是完整的目录结构,但我想这应该足够了解了):
org.prithvidiamond1
|
+--BotApplication.java
|
+--DB
|
+--Repository
|
+--ServerRepository.java
BotApplication.java
looks as follows: 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;
}
}
Edit: Here is a link to a repository with all the code: https://github.com/prithvidiamond1/DiamondBot/tree/springboot-restructure编辑:这是一个包含所有代码的存储库的链接: https ://github.com/prithvidiamond1/DiamondBot/tree/springboot-restructure
use annotation @Autowired with the constructor of BotApplication class as shown below -使用注释@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 的扫描。
You have Created Repository
bean (ServerRepository)within your application.您已经在应用程序中创建了
Repository
bean (ServerRepository)。
But in your BotApplication
component (which itself is a bean), you are not telling spring to inject dependency of Repository
bean (ie Dependancy Injection).但是在您的
BotApplication
组件(它本身是一个 bean)中,您并没有告诉 spring 注入Repository
bean 的依赖项(即 Dependancy Injection)。
Such a dependancy injection can be achieved by constructor , field-based or setter based methodologies.这种依赖注入可以通过构造函数、基于字段或基于设置器的方法来实现。
You can either remove ServerRepository serverRepository
from public BotApplication(ServerRepository serverRepository, Logger logger)
constructor & just use :您可以从
public BotApplication(ServerRepository serverRepository, Logger logger)
构造函数中删除ServerRepository serverRepository
& 只需使用:
@Autowired
private final ServerRepository serverRepository;
Or as other answer suggested, use @Autowired in Constructor itself and remove field ServerRepository serverRepository
:或者作为其他答案建议,在构造函数本身中使用 @Autowired 并删除字段
ServerRepository serverRepository
:
`
@Autowired
public BotApplication(ServerRepository serverRepository, Logger logger)
`
Please note, here, this.serverRepository = serverRepository;
请注意,这里
this.serverRepository = serverRepository;
is also not required in constructor as dependency injection will take care of this.在构造函数中也不需要,因为依赖注入会解决这个问题。
The problem is that you are using the primary source class( BotApplication.class
) for executing custom code during start-up.问题是您正在使用主要源类(
BotApplication.class
)在启动期间执行自定义代码。
public static void main(String[] args) {
ApplicationContext AppContext = SpringApplication.run(BotApplication.class, args);
}
public BotApplication(DiscordServerRepository serverRepository, Logger logger){
...
appRuntime(logger);
}
In the SpringApplication.run
method you need to pass only classes which provide beans definitions.在
SpringApplication.run
方法中,您只需要传递提供 bean 定义的类。 These are @Configuration classes.这些是@Configuration类。 It is not a good place for using repositories or any startup code.
这不是使用存储库或任何启动代码的好地方。
See the best practices Running code after Spring Boot starts查看最佳实践Spring Boot 启动后运行代码
I describe one of the best solutions: ApplicationRunner我描述了最好的解决方案之一: ApplicationRunner
BotApplication
class must implement ApplicationRunner
interface. BotApplication
类必须实现ApplicationRunner
接口。 The interface is used to indicate that a bean should run when it is contained within a SpringApplication
.SpringApplication
中时应该运行。run
method.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);
}
}
Main.class
to the SpringApplication.run
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.