簡體   English   中英

將MongoTemplate傳遞給Custom Repository實現

[英]Passing MongoTemplate to Custom Repository implementation

Project配置為使用多個MongoTemplate

Mongo Ref被傳遞為

@EnableMongoRepositories(basePackages={"com.mypackage.one"}, mongoTemplateRef="mongoTemplateOne")

對於com.mypackage.one包中的存儲庫

@EnableMongoRepositories(basePackages={"com.mypackage.two"}, mongoTemplateRef="mongoTemplateTwo")

對於com.mypackage.two包中的存儲庫

對於標准存儲庫,它工作正常。 但對於我需要自定義行為的場景,我定義了myRepoCustomImpl以及我的自定義行為需求。

問題 :我需要訪問類似標准存儲庫的MongoTemplate

例如,如果MyRepoMyRepoCustom接口擴展為

@Repository
interface MyRepo extends MongoRepository<MyEntity, String>, MyRepoCustom{}

MyRepoCustomImpl

@Service
    public class MyRepoCustomImpl implements MyRepoCustom{
        @Autowired
        @Qualifier("mongoTemplateOne")
        MongoTemplate mongoTmpl;

        @Override
        MyEntity myCustomNeedFunc(String arg){
            // MyImplemenation goes here
        }

}

如果MyRepocom.mypackage.one包中, mongoTemplateOne將被myRepo使用,所以應該有一些方法讓MyRepoCustomImpl知道它也應該使用mongoTemplateOne ,每當我在mongoTemplateRefMyRepo進行更改時,就像

@EnableMongoRepositories(basePackages={"com.mypackage.one"}, mongoTemplateRef="mongoTemplateThree")

現在我需要在MyRepoCustomImpl對@Qualifier進行更改! 自定義行為有很多回購,因此它變得繁瑣乏味。

問題:相反,沒有任何方法可以根據它擴展到的回購自動注入或解決使用的MongoTemplate?

MongoTemplate不被暴露MongoRepository接口。 他們可能會暴露MongoTemplate @Bean的名稱,這可以為您的問題提供解決方案。 但是,鑒於他們沒有,我將在下面提供一個可能適合您需求的示例。

首先, mongoTemplateRef指的是要使用的@Bean名稱 ,它不指定MongoTemplate的名稱。

您需要提供每個MongoTemplate @Bean ,然后在@EnableMongoRepositories注釋中引用它。

由於您使用的是spring-boot,因此您可以利用MongoDataAutoConfiguration類。 請看看它在這里做了什么https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data /mongo/MongoDataAutoConfiguration.java

最簡單的例子就是這樣。

package: com.xyz.repo(此實現依賴於MongoDataAutoConfiguration提供的配置)

@Configuration
@EnableMongoRepositories(basePackages={"com.xyz.repo"}) //mongoTemplateRef defaults to mongoTemplate
public class XyzRepoConfiguration {

}

public abstract class BaseRepo {
    @Autowired
    MongoTemplate mongoTemplate;
}

@Service
public class MyRepoCustomImpl extends BaseRepo implements MyRepoCustom {    
    @Override
    MyEntity myCustomNeedFunc(String arg){
        // access to this.mongoTemplate is present
    }
}

包: com.abc.repo

@Configuration
@EnableMongoRepositories(basePackages={"com.abc.repo"}, mongoTemplateRef=AbcRepConfiguration.TEMPLATE_NAME)
public class AbcRepoConfiguration {
    public static final String TEMPLATE_NAME = "mongoTemplateTwo";

    @Bean(name="mongoPropertiesTwo")
    @ConfigurationProperties(prefix="spring.data.mongodb2")
    public MongoProperties mongoProperties() {
        return new MongoProperties();
    }

    @Bean(name="mongoDbFactoryTwo")
    public SimpleMongoDbFactory mongoDbFactory(MongoClient mongo, @Qualifier("mongoPropertiesTwo") MongoProperties mongoProperties) throws Exception {
        String database = this.mongoProperties.getMongoClientDatabase();
        return new SimpleMongoDbFactory(mongo, database);
    }

    @Bean(name=AbcRepoConfiguration.TEMPLATE_NAME)
    public MongoTemplate mongoTemplate(@Qualifier("mongoDbFactoryTwo") MongoDbFactory mongoDbFactory, MongoConverter converter) throws UnknownHostException {
        return new MongoTemplate(mongoDbFactory, converter);
    }
}

public abstract class BaseRepo {
    @Autowired
    @Qualifier(AbcRepoConfiguration.TEMPLATE_NAME)
    MongoTemplate mongoTemplate;
}

@Service
public class MyRepoCustomImpl extends BaseRepo implements MyRepoCustom {    
    @Override
    MyEntity myCustomNeedFunc(String arg){
        // access to this.mongoTemplate is present
    }
}

com.xyz.repo將依托spring.data.mongodb屬性中application.properties com.abc.repo將依托spring.data.mongodb2內性能application.properties

我以前沒有使用過AbcRepoConfiguration.TEMPLATE_NAME方法,但它是在我的IDE中編譯的。

如果您需要任何澄清,請告訴我。

MongoTemplate不會在您的存儲庫類中注入,而是在spring-data-mongodb更深入,因此您無法從存儲庫中獲取它。 看看你會學到很多東西的代碼。

因此,除非您禁用spring-boot自動配置和組件發現並自行配置它,否則不能根據repo擴展注入bean,但這比僅更改@Qualifier名稱要長得多。 您的IDE調用可以輕松地幫助您,您可能會后悔禁用自動配置。

抱歉讓人失望。

您可以使用以下示例。

1)

package com.johnathanmarksmith.mongodb.example;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * Date:   6/28/13 / 10:40 AM
 * Author: Johnathan Mark Smith
 * Email:  john@johnathanmarksmith.com
 * <p/>
 * Comments:
 *  This main really does not have to be here but I just wanted to add something for the demo..
 *
 */


public class MongoDBApp {

    static final Logger logger = LoggerFactory.getLogger(MongoDBApp.class);

    public static void main(String[] args) {
        logger.info("Fongo Demo application");

        ApplicationContext context = new AnnotationConfigApplicationContext(MongoConfiguration.class);




        logger.info("Fongo Demo application");
    }
}

2)

package com.johnathanmarksmith.mongodb.example;

import com.mongodb.Mongo;
import com.mongodb.ServerAddress;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

import java.util.ArrayList;


/**
 * Date:   5/24/13 / 8:05 AM
 * Author: Johnathan Mark Smith
 * Email:  john@johnathanmarksmith.com
 * <p/>
 * Comments:
 * <p/>
 * This is a example on how to setup a database with Spring's Java Configuration (JavaConfig) style.
 * <p/>
 * As you can see from the code below this is easy and a lot better then using the old style of XML files.
 * <p/>
 * T
 */

@Configuration
@EnableMongoRepositories
@ComponentScan(basePackageClasses = {MongoDBApp.class})
@PropertySource("classpath:application.properties")
public class MongoConfiguration extends AbstractMongoConfiguration {


    @Override
    protected String getDatabaseName() {
        return "demo";
    }



    @Override
    public Mongo mongo() throws Exception {
        /**
         *
         * this is for a single db
         */

        // return new Mongo();


        /**
         *
         * This is for a relset of db's
         */

        return new Mongo(new ArrayList<ServerAddress>() {{ add(new ServerAddress("127.0.0.1", 27017)); add(new ServerAddress("127.0.0.1", 27027)); add(new ServerAddress("127.0.0.1", 27037)); }});

    }

    @Override
    protected String getMappingBasePackage() {
        return "com.johnathanmarksmith.mongodb.example.domain";
    }

}

3)

package com.johnathanmarksmith.mongodb.example.repository;


import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;

import com.johnathanmarksmith.mongodb.example.domain.Person;


/**
 * Date:   6/26/13 / 1:22 PM
 * Author: Johnathan Mark Smith
 * Email:  john@johnathanmarksmith.com
 * <p/>
 * Comments:
 * <p/>
 * This is my Person Repository
 */


@Repository
public class PersonRepository {

    static final Logger logger = LoggerFactory.getLogger(PersonRepository.class);

    @Autowired
    MongoTemplate mongoTemplate;

    public long countUnderAge() {
        List<Person> results = null;

        Query query = new Query();
        Criteria criteria = new Criteria();
        criteria = criteria.and("age").lte(21);

        query.addCriteria(criteria);
        //results = mongoTemplate.find(query, Person.class);
        long count = this.mongoTemplate.count(query, Person.class);

        logger.info("Total number of under age in database: {}", count);
        return count;
    }

    /**
     * This will count how many Person Objects I have
     */
    public long countAllPersons() {
        // findAll().size() approach is very inefficient, since it returns the whole documents
        // List<Person> results = mongoTemplate.findAll(Person.class);

        long total = this.mongoTemplate.count(null, Person.class);
        logger.info("Total number in database: {}", total);

        return total;
    }

    /**
     * This will install a new Person object with my
     * name and random age
     */
    public void insertPersonWithNameJohnathan(double age) {
        Person p = new Person("Johnathan", (int) age);

        mongoTemplate.insert(p);
    }

    /**
     * this will create a {@link Person} collection if the collection does not already exists
     */
    public void createPersonCollection() {
        if (!mongoTemplate.collectionExists(Person.class)) {
            mongoTemplate.createCollection(Person.class);
        }
    }

    /**
     * this will drop the {@link Person} collection if the collection does already exists
     */
    public void dropPersonCollection() {
        if (mongoTemplate.collectionExists(Person.class)) {
            mongoTemplate.dropCollection(Person.class);
        }
    }
}

4)

package com.johnathanmarksmith.mongodb.example.domain;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

/**
 * Date:   6/26/13 / 1:21 PM
 * Author: Johnathan Mark Smith
 * Email:  john@johnathanmarksmith.com
 * <p/>
 * Comments:
 * <p/>
 * This is a Person object that I am going to be using for my demo
 */


@Document
public class Person {

    @Id
    private String personId;

    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getPersonId() {
        return personId;
    }

    public void setPersonId(final String personId) {
        this.personId = personId;
    }

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(final int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person [id=" + personId + ", name=" + name
                + ", age=" + age + "]";
    }

}

https://github.com/JohnathanMarkSmith/spring-fongo-demo

您可以直接在服務類中注入MongoTemplate和MongoOperations。

嘗試自動連接它們然后你應該很好。

更新:

沒有使用適當的限定符自動裝配(因為你有兩個存儲庫),這是不可能的。 作為Custom類,所有這些都與存儲庫不同。 如果你只有一個存儲庫,那么mongotemplate的autowire就足夠了,否則你必須在impl中提供限定符,因為創建了兩個MongoTempalte bean。

暫無
暫無

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

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