springboot mongodb配置解析
前言
由於以前使用mongo都是簡單的本地裸奔,根本沒有設定過使用者密碼,昨天收到運維同事反饋說伺服器被挖礦木馬攻擊了,嚇得趕緊在docker裡面開啟認證,但是設定完後問題來了,開發同事又說不能用配置檔案如下
spring:
data:
mongodb:
host: 127.0.0.1
port: 27017
username: sunny
password: 123456
database: admin
看起來很ok但是在啟動boot的時候在會連線兩次(別問我為什麼是兩次,boot原始碼還沒有看多少),第一次是失敗了,但是第二次成功了,但是讀取資料時候又用的是mongoTemplate
uri
方式配置了,下面介紹boot怎麼解析它
配置檔案(yml)
spring:
data:
mongodb:
uri: mongodb://localhost:27017/file
對應的java程式碼是
@ConfigurationProperties(prefix = "spring.data.mongodb")
public class MongoProperties {
public static final String DEFAULT_URI = "mongodb://localhost/test" ;
// 預設uri=
public String determineUri() {
return (this.uri != null ? this.uri : DEFAULT_URI);
}
....
// 關鍵程式碼 idea ctrl+g 169 就可以看到
public String getMongoClientDatabase() {
if (this.database != null) {
return this.database;
}
return new MongoClientURI(determineUri()).getDatabase();
}
}
// 讀取yml檔案字首為(spring.data.mongodb)
由原始碼可以看出這裡如果uri=null則使用DEFAULT_URI
,然後進入MongoClientURI
類
public class MongoClientURI {
private final ConnectionString proxied;
private final MongoClientOptions.Builder builder;
/**
* Creates a MongoURI from the given string.
* 從給定的字串建立一個MongoURI
* @param uri the URI
*/
public MongoClientURI(final String uri) {
this(uri, new MongoClientOptions.Builder());
}
/**
* Mongo database URI. Cannot be set with host, port and credentials.
*/
public MongoClientURI(final String uri, final MongoClientOptions.Builder builder) {
this.builder = notNull("builder", builder);
proxied = new ConnectionString(uri);
}
}
到這裡了就先看new MongoClientOptions.Builder()
方法
@Immutable
public class MongoClientOptions {
/**
* Creates a Builder for MongoClientOptions, getting the appropriate system properties *for initialization.
* 這裡MongoClientOptions建立一個構建器,並且設定一些系統屬性
*/
public Builder() {
/*設定心跳頻率,在叢集中*/ heartbeatFrequency(Integer.parseInt(System.getProperty("com.mongodb.updaterIntervalMS", "10000")));
/*最小心跳頻率*/ minHeartbeatFrequency(Integer.parseInt(System.getProperty("com.mongodb.updaterIntervalNoMasterMS", "500")));
/*設定用於群集心跳的連線的連線超時*/ heartbeatConnectTimeout(Integer.parseInt(System.getProperty("com.mongodb.updaterConnectTimeoutMS", "20000")));
/*socket 連結超時*/ heartbeatSocketTimeout(Integer.parseInt(System.getProperty("com.mongodb.updaterSocketTimeoutMS", "20000")));
/*可接受的延遲差 15秒*/ localThreshold(Integer.parseInt(System.getProperty("com.mongodb.slaveAcceptableLatencyMS", "15")));
}
}
System.getProperty(xxxx)可以在jvm裡面設定或者直接在boot啟動方法裡面設定。
看到這裡後發現使用了一個proxied(代理)繼續往下看
public class ConnectionString {
/**
* Creates a ConnectionString from the given string.
*
* @param connectionString the connection string
* @since 3.0
*/
public ConnectionString(final String connectionString) {
this.connectionString = connectionString;
//這裡可以看出支援兩種協議:mongodb://和mongodb+srv://
boolean isMongoDBProtocol = connectionString.startsWith(MONGODB_PREFIX);
boolean isSRVProtocol = connectionString.startsWith(MONGODB_SRV_PREFIX);
if (!isMongoDBProtocol && !isSRVProtocol) {
throw new IllegalArgumentException(format("The connection string is invalid. "
+ "Connection strings must start with either '%s' or '%s", MONGODB_PREFIX, MONGODB_SRV_PREFIX));
}
// 擷取協議頭,eg:sunny:[email protected]:27007/file?connectTimeoutMS=400000
String unprocessedConnectionString;
if (isMongoDBProtocol) {
unprocessedConnectionString = connectionString.substring(MONGODB_PREFIX.length());
} else {
unprocessedConnectionString = connectionString.substring(MONGODB_SRV_PREFIX.length());
}
// 分割出使用者和主機資訊 eg:sunny:[email protected]:27007
String userAndHostInformation;
int idx = unprocessedConnectionString.lastIndexOf("/");
if (idx == -1) {
if (unprocessedConnectionString.contains("?")) {
throw new IllegalArgumentException("The connection string contains options without trailing slash");
}
userAndHostInformation = unprocessedConnectionString;
unprocessedConnectionString = "";
} else {
//userAndHostInformation=sunny:[email protected]:27007
userAndHostInformation = unprocessedConnectionString.substring(0, idx);
// unprocessedConnectionString=file?connectTimeoutMS=400000
unprocessedConnectionString = unprocessedConnectionString.substring(idx + 1);
}
// Split the user and host information
String userInfo;
String hostIdentifier;
String userName = null;
char[] password = null;
idx = userAndHostInformation.lastIndexOf("@");
if (idx > 0) {
// userInfo=sunny:123456
userInfo = userAndHostInformation.substring(0, idx);
// hostIdentifier=127.0.0.1:27007
hostIdentifier = userAndHostInformation.substring(idx + 1);
// 判斷userInfo是否包含@和:出現次數大於1
int colonCount = countOccurrences(userInfo, ":");
if (userInfo.contains("@") || colonCount > 1) {
throw new IllegalArgumentException("The connection string contains invalid user information. "
+ "If the username or password contains a colon (:) or an at-sign (@) then it must be urlencoded");
}
if (colonCount == 0) {
userName = urldecode(userInfo);
} else {
// idx=5
idx = userInfo.indexOf(":");
// userName=sunny
userName = urldecode(userInfo.substring(0, idx));
//passpword=123456
password = urldecode(userInfo.substring(idx + 1), true).toCharArray();
}
} else {
hostIdentifier = userAndHostInformation;
}
// 驗證host
List<String> unresolvedHosts = unmodifiableList(parseHosts(asList(hostIdentifier.split(",")), isSRVProtocol));
this.hosts = isSRVProtocol ? resolveHostFromSrvRecords(unresolvedHosts.get(0)) : unresolvedHosts;
// 解析引數
String nsPart;
idx = unprocessedConnectionString.indexOf("?");
if (idx == -1) {
nsPart = unprocessedConnectionString;
unprocessedConnectionString = "";
} else {
// nsPart=file 獲取資料庫名稱
nsPart = unprocessedConnectionString.substring(0, idx);
// unprocessedConnectionString=connectTimeoutMS=400000
unprocessedConnectionString = unprocessedConnectionString.substring(idx + 1);
}
if (nsPart.length() > 0) {
nsPart = urldecode(nsPart);
idx = nsPart.indexOf(".");
// 是否指定集合
if (idx < 0) {
database = nsPart;
collection = null;
} else {
database = nsPart.substring(0, idx);
collection = nsPart.substring(idx + 1);
}
} else {
database = null;
collection = null;
}
/*資料庫健康連結 mongodb+srv 協議才使用*/
String txtRecordsQueryParameters = isSRVProtocol ? resolveAdditionalQueryParametersFromTxtRecords(unresolvedHosts.get(0)) : "";
/*連結引數 connectTimeoutMS=400000*/
String connectionStringQueryParamenters = unprocessedConnectionString;
Map<String, List<String>> connectionStringOptionsMap = parseOptions(connectionStringQueryParamenters);
Map<String, List<String>> txtRecordsOptionsMap = parseOptions(txtRecordsQueryParameters);
//判斷是否設定 authsource、replicaset
if (!ALLOWED_OPTIONS_IN_TXT_RECORD.containsAll(txtRecordsOptionsMap.keySet())) {
throw new MongoConfigurationException(format("A TXT record is only permitted to contain the keys %s, but the TXT record for "
+ "'%s' contains the keys %s", ALLOWED_OPTIONS_IN_TXT_RECORD, unresolvedHosts.get(0), txtRecordsOptionsMap.keySet()));
}
Map<String, List<String>> combinedOptionsMaps = combineOptionsMaps(txtRecordsOptionsMap, connectionStringOptionsMap);
if (isSRVProtocol && !combinedOptionsMaps.containsKey("ssl")) {
combinedOptionsMaps.put("ssl", singletonList("true"));
}
translateOptions(combinedOptionsMaps);
credential = createCredentials(combinedOptionsMaps, userName, password);
warnOnUnsupportedOptions(combinedOptionsMaps);
}
}
完結
mongo這塊程式碼是臨時看的,可能沒有太認真,如果有誤請指出,還有就是mongodb+srv 協議沒有使用過,有使用經驗的歡迎留言交流,謝謝
相關推薦
springboot mongodb配置解析
官網配置 前言 由於以前使用mongo都是簡單的本地裸奔,根本沒有設定過使用者密碼,昨天收到運維同事反饋說伺服器被挖礦木馬攻擊了,嚇得趕緊在docker裡面開啟認證,但是設定完後問題來了,開發同事又說不能用配置檔案如下 spring: data:
Springboot +Mongodb配置
1. MongoDB在pom.xml檔案中的依賴 springboot 版本 2.0.7 <dependency> <groupId>org.springframework.boot</groupId> <artifactId&g
解析SpringBoot中配置檔案(.yml/.yaml)
解析SpringBoot中配置檔案(.yml/.yaml) springBoot配置檔案的載入有先後順序為: 1.application.yml 2.application.yaml 3.application.properoties 後加載的會把先載入的給覆蓋掉 #普通資料的配置
SpringBoot應用配置常用相關檢視解析器
SpringBoot的自動裝配裝配了檢視解析器了嗎? SpringBoot使用JSP SpringBoot中使用Thymeleaf SpringBoot中使用Freemark SpringBoot的自動裝配裝配了檢視解析器了嗎? 我們可以看到SpringBoot自動裝配的WebMvcAutoConf
SpringBoot自動配置註解原理解析
1. SpringBoot啟動主程式類: 1 @SpringBootApplication 2 public class DemoApplication { 3 public static void main(String[] args) { 4 5 SpringApp
springboot原始碼解析:自己實現一個springboot自動配置
上兩篇將到了springboot自動配置和條件註解是如何實現,這篇在前兩篇的基礎上自己實現一個springboot的自動配置,用到條件註解。 需求:加入自己手寫的jar。直接就可以使用StringRedisTemplate。 1.新建一個maven專案,pom.xml如下:
SpringBoot-自動配置原始碼解析
接著上一篇部落格《 SpringBoot-快速搭建WEB工程》提出的需要分析的三個方面:我們來深入的探究SpringBoot是如何在沒有一個配置檔案的情況下為我們啟動好一個完整的WEB工程的,首先我們從@SpringBootApplication 開始這裡的分析
解析springboot裏的pom文件和對應配置解析(一)
driver font xmlns 配置解析 ng- idata rod 4.0 sna 利用Idea的默認設置創建springboot項目,pom文件的結構如下 <?xml version="1.0" encoding="UTF-8"?> <pr
案例解析:springboot自動配置未生效問題定位(條件斷點)
Spring Boot在為開發人員提供更高層次的封裝,進而提高開發效率的同時,也為出現問題時如何進行定位帶來了一定複雜性與難度。但Spring Boot同時又提供了一些診斷工具來輔助開發與分析,如spring-boot-starter-actuator。本文分享一個基於actuator與IDE
springboot自動配置原始碼解析
springboot版本:2.1.6.RELEASE SpringBoot 自動配置主要通過 @EnableAutoConfiguration, @Conditional, @EnableConfigurationProperties&nb
我是如何做到springboot自動配置原理解析
一前言 springboot 2.0.0版本分析,整體的自動配置流程如下: 具體配置參考官方文件:springboot-doc 二 @SpringBootApplication 核心註解@SpringBootConfiguration其實就是@Configuration註解,表示是個配置類;@Enable
【轉】MongoDB配置文件說明
details 5.0 key 第一個 pen log data 端口 this 啟動MongoDB有2種方式,一是直接指定配置參數,二是指定配置文件。這裏先介紹配置文件,啟動方式如下: mongod --config /etc/mongodb.conf 配置如下:ve
nginx+gridfs+mongodb 配置訪問png圖片顯示無法加載問題
nginx配置文件 做了 nginx配置 副本 server port 問題 模塊 bject 上傳文件後,瀏覽器中請求:http://<nginx server ip>:<port>/gfs/<my file> 瀏覽器出現“無法
mongodb配置和基本操作
特性 服務 win done service 基本 添加 close english MongoDB3.0新特性WiredTigerMMAPv1可插拔引擎API基於web的可視化管理工具 查看版本號mongod --version啟動數據庫 mongod --dbpath
nginx 1.12 配置解析php
alt 配置解析 cgi fast file lan try_files 技術 cati server { listen 80; server_name foo.com; root /path; index index.html index
附4 springboot源碼解析-run
chang tee fsmc lang hfs mcc beijing isa dma %E5%85%B3%E4%BA%8E%E7%BA%BF%E6%80%A7%E6%A8%A1%E5%9E%8B%E4%BD%A0%E5%8F%AF%E8%83%BD%E8%BF%98%E4
SSM整理筆記3——配置解析
repos gen bject sep scope resource att 2.x 處理 github:https://github.com/lakeslove/SSM 項目的目錄結構如下 首先,配置web.xml <?xml version="1.0" enc
第十二章 springboot + mongodb(復雜查詢)
參考 參數 iter extends lec con display itl dad 簡單查詢:使用自定義的XxxRepository接口即可。(見 第十一章 springboot + mongodb(簡單查詢)) 復雜查詢:使用MongoTemplate以及一些查詢
第十一章 springboot + mongodb(簡單查詢)
req all bool pan 可能 set 如果 創建 使用 1、mongodb在mac上的安裝 下載mongodb,https://www.mongodb.org/ 解壓縮到一個指定文件夾,如:/Users/enniu1/Desktop/zjg/mongodb
springboot RabbitMQ 配置
接收 handle mes 客戶端 fin ng- 技術 msg framework 引用自 http://www.cnblogs.com/ityouknow/p/6120544.html 自己留一份 記錄一下 RabbitMQ 即一個消息隊列,主要是用來實現應