[英]Application won't start as MongoOperations bean is not defined
I'm working through the book Learning Spring Boot 2.0, Second Edition
but using Spring Boot 2.5.6
so I suspect my issue might be related to me having to do things slightly with the different version.我正在阅读《 Learning Spring Boot 2.0, Second Edition
》一书,但使用Spring Boot 2.5.6
,所以我怀疑我的问题可能与我不得不对不同的版本稍微做一些事情有关。
I have this class:我有这个 class:
@Component
public class InitDatabase {
@Bean
CommandLineRunner init(MongoOperations operations) {
return args -> {
operations.dropCollection(Image.class);
operations.insert(new Image("1", "learning-spring-boot-cover.jpg"));
operations.insert(new Image("2", "learning-spring-boot-2nd-edition-cover.jpg"));
operations.insert(new Image("3", "bazinga.png"));
operations.findAll(Image.class).forEach(image -> System.out.println(image.toString()));
};
}
}
When I run my application I get this error:当我运行我的应用程序时,我收到此错误:
2021-11-25 12:26:42.870 DEBUG 71010 --- [ main] osbdLoggingFailureAnalysisReporter: Application failed to start due to an exception 2021-11-25 12:26:42.870 DEBUG 71010 --- [main] osbdLoggingFailureAnalysisReporter:应用程序因异常而无法启动
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.data.mongodb.core.MongoOperations' available: expected at least 1 bean which qualifies as autowire candidate. org.springframework.beans.factory.NoSuchBeanDefinitionException:没有“org.springframework.data.mongodb.core.MongoOperations”类型的合格 bean:预计至少有 1 个符合自动装配候选资格的 bean。 Dependency annotations: {} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1790) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1346) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.ConstructorResolver.createArgumentA Dependency annotations: {} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1790) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory .support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1346) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.12.jar:5.3 .12] 在 org.springframework.beans.factory.support.ConstructorResolver.createArgumentA rray(ConstructorResolver.java:791) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.Z93F725A07423FE1C889F448B33D21F rray(ConstructorResolver.java:791) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541) ~[spring-beans -5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.3.12.jar:5.3.12] at org .springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean( AbstractAutowireCapableBeanFactory.Z93F725A07423FE1C889F448B33D21F 46Z:582) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.AbstractBeanFactory. 46Z:582) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.12 .jar:5.3.12] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.12.jar:5.3.12] at org. springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory .java:333) ~[spring-beans-5.3.12.jar:5.3.12] 在 org.springframework.beans.factory.support.AbstractBeanFactory。 getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.12.jar:5.3.12] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.12.jar:5.3.12] at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:64) getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.12.jar:5.3.12] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans -5.3.12.jar:5.3.12] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.12.jar:5.3.12] at org.springframework .context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.12.jar:5.3.12] at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext. java:64) ~[spring-boot-2.5.6.jar:2.5.6] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-2.5.6.jar:2.5.6] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[spring-boot-2.5.6.jar:2.5.6] at org.springframework.boot.SpringApplication.run(SpringApplication.java:338) ~[spring-boot-2.5.6.jar:2.5.6] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-2.5.6.jar:2.5.6] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332) ~[spring-boot-2.5.6.jar:2.5.6] at com.paulcarron.learningspringboot.le ~[spring-boot-2.5.6.jar:2.5.6] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-2.5.6.jar:2.5.6] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[spring-boot-2.5.6.jar:2.5.6] at org.springframework.boot.SpringApplication.run(SpringApplication.java:338) ~ [spring-boot-2.5.6.jar:2.5.6] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-2.5.6.jar:2.5.6] at org .springframework.boot.SpringApplication.run(SpringApplication.java:1332)~[spring-boot-2.5.6.jar:2.5.6]在Z4D236D9A25D102C5.DALE6ECARD1 arningspringboot.LearningSpringBootApplication.main(LearningSpringBootApplication.java:12) ~[classes/:na] arningspringboot.LearningSpringBootApplication.main(LearningSpringBootApplication.java:12) ~[classes/:na]
2021-11-25 12:26:42.870 ERROR 71010 --- [ main] osbdLoggingFailureAnalysisReporter: 2021-11-25 12:26:42.870 错误 71010 --- [主要] osbdLoggingFailureAnalysisReporter:
APPLICATION FAILED TO START应用程序无法启动
Description:描述:
Parameter 0 of method init in com.paulcarron.learningspringboot.learningspringboot.InitDatabase required a bean of type 'org.springframework.data.mongodb.core.MongoOperations' that could not be found. com.paulcarron.learningspringboot.learningspringboot.InitDatabase 中方法 init 的参数 0 需要一个 'org.springframework.data.mongodb.core.MongoOperations' 类型的 bean。
Action:行动:
Consider defining a bean of type 'org.springframework.data.mongodb.core.MongoOperations' in your configuration.考虑在你的配置中定义一个 'org.springframework.data.mongodb.core.MongoOperations' 类型的 bean。
This is my build.gradle
:这是我的build.gradle
:
plugins {
id 'org.springframework.boot' version '2.5.6'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.paulcarron.learningspringboot'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb-reactive'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.synchronoss.cloud:nio-multipart-parser:1.1.0'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'javax.persistence:javax.persistence-api:2.2'
}
test {
useJUnitPlatform()
}
My understanding is that I don't need to activate the with @EnableReactiveMongoRepositories
as this is done automatically if Reactive MongoDB or Spring DataMongoDB 2.0+ are on the classpath.我的理解是,我不需要使用@EnableReactiveMongoRepositories
激活,因为如果 Reactive MongoDB 或 Spring DataMongoDB 2.0+ 在类路径上,这是自动完成的。
Is there any obvious reason why this is not working?这不起作用有什么明显的原因吗?
I guess you're trying to init your database on the startup.我猜你正试图在启动时初始化你的数据库。
You can leverage the spring internal event mechanism.您可以利用 spring 内部事件机制。 When your application is ready, spring triggers the event ApplicationReadyEvent
当您的应用程序准备就绪时,spring 会触发事件ApplicationReadyEvent
You can listen to this event and init your collection:您可以收听此事件并初始化您的收藏:
@Component
public class DataInit implements ApplicationListener<ApplicationReadyEvent> {
private final MongoOperations operations;
public DataInit(MongoOperations operations) {
this.operations = operations;
}
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
// init data
}
}
If you want to know more about spring events --> https://www.baeldung.com/spring-events如果您想了解更多关于 spring 事件的信息 --> https://www.baeldung.com/spring-events
MongoOperations
is the interface for interacting with Mongo in a blocking manner. MongoOperations
是以阻塞方式与 Mongo 交互的接口。 ReactiveMongoOperations
is the interface for interacting with Mongo in a reactive manner. ReactiveMongoOperations
是用于以响应方式与 Mongo 交互的接口。
As you're using WebFlux ( spring-boot-starter-webflux
), it would appear that you want to build a reactive application.当您使用 WebFlux ( spring-boot-starter-webflux
) 时,您似乎想要构建一个反应式应用程序。 If so, you should replace your use of MongoOperations
with ReactiveMongoOperations
.如果是这样,你应该用ReactiveMongoOperations
替换你对MongoOperations
的使用。 The, if you want to build a blocking, Servlet-based web application would be to switch to spring-boot-starter-data-mongodb
and spring-boot-starter-web
.如果您想构建一个阻塞的、基于 Servlet 的 web 应用程序,则需要切换到spring-boot-starter-data-mongodb
和spring-boot-starter-web
。
I want to preload data and read that it was best to do this using a blocking API because when launching an application there is a risk of a thread lock issue when both the web container and my loader are starting up.我想预加载数据并读到最好使用阻塞的 API 来执行此操作,因为在启动应用程序时,当 web 容器和我的加载器正在启动时,存在线程锁定问题的风险。 The book I'm using is for an older veriosn of both Spring Boot and MongoDB.我正在使用的这本书适用于 Spring Boot 和 MongoDB 的旧版本。
It seems that the version of spring-boot-starter-data-mongodb-reactive
that the book used contained MongoOperations
but this was then split out.似乎本书使用的spring-boot-starter-data-mongodb-reactive
版本包含MongoOperations
但随后被拆分。 See this .看到这个。
To use this I added implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
to my class path.为了使用它,我将implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
添加到我的 class 路径中。
If there wasn't the issue of thread lock I could have used ReactiveMongoOperations
instead.如果没有线程锁的问题,我可以使用ReactiveMongoOperations
代替。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.