简体   繁体   中英

SpringData-MongoDB: No qualifying bean of type available

I'm trying to structure a project to connect to MongoDB using Spring Data as below: SpringMongoConfig.java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;

import com.mongodb.MongoClient;

@Configuration
public class SpringMongoConfig {

    @Bean
    public MongoDbFactory mongoDbFactory() throws Exception {
        return new SimpleMongoDbFactory(new MongoClient("127.0.0.1"), "ReconInput");
    }

    @Bean
    public MongoTemplate mongoTemplate() throws Exception {

        MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());

        return mongoTemplate;

    }
}

ReconInputRepository.java :

@Repository
public interface ReconInputRepository extends MongoRepository<ReconInput, String> {
    public List<ReconInput> findByReportingDate(String reportingDate);
}

ReconInputService.java

public interface ReconInputService {
    public List<ReconInput> getInputByReportingDate(String reportingDate);
}

ReconInputServiceImpl.java

@Service
public class ReconInputServiceImpl implements ReconInputService {

    @Autowired
    private ReconInputRepository reconInputRepository;  
    public List<ReconInput> getInputByReportingDate(String reportingDate) {
        return reconInputRepository.findByReportingDate(reportingDate);
    }   
}

App.java

public class App 
{
    public static void main( String[] args )
    {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringMongoConfig.class);       
        ReconInputService reconInputService = ctx.getBean(ReconInputService.class);
        List<ReconInput> inputData = reconInputService.getInputByReportingDate("2017 Nov 20");
        System.out.println(inputData.get(0).getReportId());
    }
}

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>ups.mongodb</groupId>
    <artifactId>MongoConnection</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>MongoConnection</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>5.0.1.RELEASE</spring.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver -->
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>3.5.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-mongodb -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-mongodb</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>

    </dependencies>
</project>

When I run the project, it throw an exception:

No qualifying bean of type 'ups.mongo.service.ReconInputService' available.

Please help me any suggestion for this error. Thank you !

Update 1

Added @ComponentScan(basePackages = "ups.mongo") to SpringMongoConfig.java . Then I got new issue: Error creating bean with name 'ReconInputService': Unsatisfied dependency expressed through field 'reconInputRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'ups.mongo.repository.ReconInputRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Update 2

Instead of using Spring Data MongoRepository . I replaced ReconInputRepository.java that extends from Spring data by implement it by myself as below :

ReconInputRepository.java

public interface ReconInputRepository {

    public List<ReconInput> findByReportingDate(String reportingDate);
}

ReconInputRepositoryImpl.java

@Repository
public class ReconInputRepositoryImpl implements ReconInputRepository {

    @Autowired
    MongoTemplate mongoTemplate;

    public List<ReconInput> findByReportingDate(String reportingDate) {
        List<ReconInput> reconInputList = null;
        Query searchUserQuery = new Query(Criteria.where("reportingDate").is(reportingDate));
        reconInputList = mongoTemplate.find(searchUserQuery, ReconInput.class);
        return reconInputList;
    }
}

Then it work correctly.

My Summary The issue may come from Spring does not support inject interface - as @amdg suggest (but work in spring boot - I have no idea why, if someone know that please leave me some comment).

Reference: Spring interface injection example

Update 3

At last, I found the most simple way to make it correctly. All I need to do is adding @EnableMongoRepositories({ "ups.mongo.repository" }) to the SpringMongoConfig.java

由于您在 ReconInputServiceImpl 上注释了 @Service 所以请在主类中添加 ReconInputServiceImpl.class

ReconInputService reconInputService = ctx.getBean(ReconInputServiceImpl.class);

As I suspected, you mix plain old Spring with Spring Boot and want to get Spring Boot effect.

In order to use Spring Boot you should update your dependencies to use Spring Boot Starters.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>ups.mongodb</groupId>
    <artifactId>MongoConnection</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>MongoConnection</name>
    <url>http://maven.apache.org</url>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>    
</project>

Then just add your config in the root package of your app (presumably it's ups.mongo ):

@SpringBootApplication
@EnableMongoRepositories
public class App 
{
    public static void main( String[] args )
    {
        ConfigurableApplicationContext ctx = SpringApplication.run(App.class, args);       
        ReconInputService reconInputService = ctx.getBean(ReconInputService.class);
        List<ReconInput> inputData = reconInputService.getInputByReportingDate("2017 Nov 20");
        System.out.println(inputData.get(0).getReportId());
    }
}

In this case, you do not even need SpringMongoConfig.class. Instead, add the following config in your application.properties :

spring.data.mongodb.host=127.0.0.1
spring.data.mongodb.port=27017
spring.data.mongodb.database=demo

You can annotate your ReconInputServiceImpl class as @Service("reconInputService") .

You can then access it as follows.

ReconInputService reconInputService = ctx.getBean("reconInputService",ReconInputService.class);
    ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringMongoConfig.class);       

If you use above constructor, DI container will only load bean definitions from SpringMongoConfig class.

If You want DI container to scan all bean definitions recursively for a particular base package please use this constructor instead

AnnotationConfigApplicationContext(java.lang.String... basePackages)

I have previously added only spring-data-mongodb package which kept me busying debugging for "No qualifying bean for some repository".

After adding spring-boot-starter-data-mongodb , everything is handled by spring.

application.yaml

spring:
  data:
    mongodb:
      uri: mongodb://username:password@localhost:27017
      database: test

pom.xml

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.data</groupId>
  <artifactId>spring-data-mongodb</artifactId>
</dependency>

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