简体   繁体   中英

Spring can't autowire class

I have the following Spring @Configuration:

@Bean
@Qualifier("mongo")
public MongoFacade mongo(Environment env){
    final String host = env.getProperty("database.host");
    final MongoClient mongoClient = new MongoClient(host);
    return new MongoFacade(mongoClient, "test-db");
}

@Bean
public MessageStore<Event> eventStore(@Qualifier("mongo") MongoFacade mongo, ObjectMapper mapper) {
    return new MongoMessageStore<>(mongo, mapper);
}

When I launch my application an exception is thrown and the cause is:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'eventStore' defined in it.m.MyConfiguration: Unsatisfied dependency expressed through constructor argument with index 0 of type [base.backend.persistence.impl.mongo.MongoFacade]: : No qualifying bean of type [base.backend.persistence.impl.mongo.MongoFacade] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Qualifier(value=mongo)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [base.backend.persistence.impl.mongo.MongoFacade] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Qualifier(value=mongo)}

MongoFacade class is a real class, and don't implements interfaces, I've also tried to remove the Environment dependency from the method, but still doesn't work.

Removing the @Qualifier annotation the error is:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [base.backend.persistence.impl.mongo.MongoFacade] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

MongoFacade is a simple facade for MongoClient class that works with my PersistenceId class:

public class MongoFacade {

public static final String DEFAULT_NAME = "default";

private final MongoClient mongo;
private final String defaultName;

public MongoFacade(MongoClient mongoClient) {
    this(mongoClient, DEFAULT_NAME);
}
public MongoFacade(MongoClient mongoClient, String defaultName) {
    this.mongo = mongoClient;
    this.defaultName = defaultName;
}

public Document findOne(PersistenceId id){
    final MongoCollection<Document> collection = collection(id);
    final String documentId = documentId(id);

    return collection.find(eq("_id", documentId)).first();
}

public UpdateResult updateOne(PersistenceId id, Document update) {
    final MongoCollection<Document> collection = collection(id);
    final String documentId = documentId(id);

    return collection.updateOne(eq("_id", documentId), update);
}

The environment can be injected as a field instead of the constructor also I would suggest using method calls instead of auto wiring for the dependencies.

Something like the following

@Autowired
private Environment env;

@Bean
public MongoFacade mongoFacade(){
    final String host = env.getProperty("database.host");
    final MongoClient mongoClient = new MongoClient(host);
    return new MongoFacade(mongoClient, "test-db");
}

@Bean
public MessageStore<Event> eventStore(ObjectMapper mapper) {
    return new MongoMessageStore<>(mongoFacade(), mapper);
}

Edit: Added Spring Boot MongoDB config

From the comments it is clear you are using Spring Boot, this already auto configures a MongoClient for you. Instead of doing it yourself you can reduce your configuration a little further. (Se also MongoAutoConfiguration ).

In your application.properties add

spring.data.mongodb.host=<value of current database.host>

or if it is a full URI

spring.data.mongodb.uri=<value of current database.host>

Then change your configuration class.

@Bean
public MongoFacade mongoFacade(MongoClient mongoClient){
    return new MongoFacade(mongoClient, "test-db");
}

@Bean
public MessageStore<Event> eventStore(ObjectMapper mapper) {
    return new MongoMessageStore<>(mongoFacade(null), mapper);
}

Spring Boot will now construct a MongoClient .

can you please use @Service instead of @qualifier while declaring bean definition

@Service("mongo")
public MongoFacade mongoFacade()

let me know if it worked for you or not .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM