Springboot移除自動配置Mongodb


最近由於項目開發需要,需要抽取一層MongoBaseDao:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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.data.mongodb.core.query.Update;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.List;

public abstract class MongoBaseDao<T> {

    private static final String ID_FIELD = "_id";

    private static final String DELETE_FIELD = "deleted";

    @Autowired
    @Qualifier("mongoTemplate")
    protected MongoTemplate mongoTemplate;

    //保存一個對象到mongodb
    public void save(T bean) {
        mongoTemplate.save(bean);
    }

    // 根據id刪除對象
    public void deleteById(T t) {
        mongoTemplate.remove(t);
    }

    // 通過條件查詢更新數據
    public void update(Query query, Update update) {
        mongoTemplate.updateMulti(query, update, this.getEntityClass());
    }

    // 根據id進行更新
    public void updateById(String id, T t) {
        Query query = new Query();
        query.addCriteria(Criteria.where(ID_FIELD).is(id));
        Update update = buildBaseUpdate(t);
        update(query, update);
    }

    // 查詢集合
    public List<T> findAll() {
        Query query = Query.query(Criteria.where(DELETE_FIELD).is(false));
        return mongoTemplate.find(query, this.getEntityClass());
    }

    // 通過id查詢一個實體
    public T findById(String id) {
        Query query = Query.query(Criteria.where(ID_FIELD).is(id).and(DELETE_FIELD).is(false));
        return mongoTemplate.findOne(query, this.getEntityClass());
    }

    private Update buildBaseUpdate(T t) {
        Update update = new Update();

        Field[] fields = t.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                Object value = field.get(t);
                if (value != null) {
                    update.set(field.getName(), value);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return update;
    }

    // 獲取需要操作的實體類class
    protected Class<T> getEntityClass() {
        return ((Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
    }

    public MongoTemplate getMongoTemplate() {
        return mongoTemplate;
    }

}

由於是通用的代碼,所以想放至common包中供其他服務依賴使用,此時出現了問題。部分服務依賴於common包中的部分內容,但並不需要連接mongo,此時這些項目啟動時會報錯:

01-07 15:21:15.657 INFO  -- [cluster-ClusterId{value='5c32fdebe4e45a2cdae06391', description='null'}-localhost:27017] org.mongodb.driver.cluster:76:[] []  Exception in monitor thread while connecting to server localhost:27017
com.mongodb.MongoSocketOpenException: Exception opening socket
    at com.mongodb.connection.SocketStream.open(SocketStream.java:63)
    at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:115)
    at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:113)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.ConnectException: Connection refused (Connection refused)
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at com.mongodb.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:57)
    at com.mongodb.connection.SocketStream.open(SocketStream.java:58)
    ... 3 common frames omitted

查了相關資料發現如果在springboot項目中存在spring-boot-starter-data-mongodb的依賴,springboot會在項目啟動時自動實例化一個mongo實例,因此需要在項目啟動時禁用mongo的自動配置。

看了網上說在Springboot啟動類上增加 @SpringBootApplication(exclude = MongoAutoConfiguration.class) 配置,但是我試了之后發現仍然報錯:

01-07 15:52:49.717 ERROR -- [main] o.s.b.d.LoggingFailureAnalysisReporter:42:[] []  

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method mongoDbFactory in org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration required a bean of type 'com.mongodb.MongoClient' that could not be found.
    - Bean method 'mongo' not loaded because auto-configuration 'MongoAutoConfiguration' was excluded


Action:

Consider revisiting the conditions above or defining a bean of type 'com.mongodb.MongoClient' in your configuration.

繼續查資料發現配置中還需要加入MongoDataAutoConfiguration.class才行,最終配置如:@SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class} ) ,項目可以正常啟動。

如果單獨只配置 @SpringBootApplication(exclude = MongoDataAutoConfiguration.class),仍然會出現最開始的報錯情況。

針對我的項目情況,還想到有另外一種方案可供實現:可以在common包中單獨抽取出common-mongo模塊供其他需要連接mongo的服務依賴。

 

參考資料:

  通用MongoDao:https://www.cnblogs.com/meisha/articles/3630036.html

  Mongo自動配置:https://blog.csdn.net/xuyw10000/article/details/72918360


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM