天天看點

閑談 :怎麼玩好java元件的配置注入

作者:搬山道猿
閑談 :怎麼玩好java元件的配置注入

一. 前言

經曆過元件多個版本的疊代後,應該會發現,随着工具的不斷演進,能搜尋到的配置方式可能大多數都過時了,那麼如何根據自己的版本快速的找到配置方式呢?

有時候官方文檔裡面能給我們正确答案,或者網上正好有對應版本的資料,這些都不在本次的讨論範圍内。

本次思考的就是,如何在缺失這些的情況下快速的進行配置。以MongoDB 來學習一下 :

二. 解決方式

2.1 方法一 : 入口類 向下查找

首先 ,作為工具類的軟體,底層可能會有變動,但是對外的接口通常是不會有大的變化的
java複制代碼// 在高版本裡面  MongoDbFactory 已經過時了 >> 
@Bean
public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory, MappingMongoConverter converter) {
    MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory, converter);
    mongoTemplate.setReadPreference(ReadPreference.secondaryPreferred());
    return mongoTemplate;
}
           
  • 以上是一個 MongoDB 入口類的配置, MongoDB 隻要不發生大的疊代,MongoTemplate 這個入口類是不會有太大的變化

但是抄過來後,會馬上發現 MongoDbFactory 過時了,這裡說明我們已經找到關鍵點了 :我們需要一個新的 Factory

閑談 :怎麼玩好java元件的配置注入

點開 MongoTemplate 就知道需要一個 MongoDatabaseFactory , 通過實作類就能快速找到我們應該建立哪個類了 :

  • xxxBuilder : 好東西 , 通常都是官方提供的配置類,用于幫助建立執行個體,例如 RestTemplateBuilder,就可以快速建立 RestTemplate
  • xxxFactory : Client的建立類 ,也是比較核心的建立類
  • xxxSupport : 這種通常是最後的支援類,一般都是實際的業務,這種類可配置的點就很局限
  • xxxClient :通常基于這個調用遠端元件,一般配置這個Bean就能實作對應的遠端調用了
  • xxxConverter : 最常見的就是做資料映射,把DTO的資料轉換成元件需要的資料格式
  • Simplexxx : 這個字首是個很明顯提示,說明基礎的功能用它就沒錯了。
然後再往上找一找,就很容易找到對應 MongoClientSettings 類 ,裡面神奇的發現了一個 Builder :
java複制代碼MongoClientSettings.Builder builder = MongoClientSettings.builder();

// 設定伺服器位址
builder.applyToClusterSettings(clusterSettingsBuilder ->
        clusterSettingsBuilder.hosts(Arrays.asList(new ServerAddress(localhost, port))));

// .... 省略
 MongoClientSettings settings = builder.build();

// 建立MongoClient用戶端 , 最後建立一個 Factory
MongoClient client = MongoClients.create(settings);
return new SimpleMongoClientDatabaseFactory(client, database);
           

2.2 方法二 : 回報式-針對提供了配置項,但是缺少或者不知道配置的場景

這種方案在我配置 Sharding 的時候效果非常好,最直接的表現就是,每次啟動缺少配置時,都會有相關的回報。

java複制代碼org.apache.shardingsphere.infra.exception.ShardingSphereException: Can not route tables for `[t_blog]`, please make sure the tables are in same schema.
    at org.apache.shardingsphere.sharding.route.engine.type.unconfigured.ShardingUnconfiguredTablesRoutingEngine.route
           

首先,進代碼去找原因 ,這裡不難發現第一個線索,沒有 tableRule ,導緻表名沒有正确的分表

閑談 :怎麼玩好java元件的配置注入

正常情況下,我們不應該進到第三步裡面,那麼就網上找,為什麼我的 rule 不存在

閑談 :怎麼玩好java元件的配置注入

流程不複雜,通過6步就快速找到了配置類,後續按照配置類進行配置即可,熟練情況下,可能十幾分鐘就能解決一個配置問題。

2.3 方法三 : 由下到上 - 針對 Client 對應不上,有微小版本差異的情況

這種方式和上面的類似,也是找到對應的下層入口,可能這裡會有一些模糊,怎麼知道下層入口?

除了報錯的回報式,最好的方式就是直接看最終的源碼包,以 ES 為例 :

  • 第一步 : 找 Jar 包 ,如果是需要調用外部元件的 ,直接看對應的 Client
閑談 :怎麼玩好java元件的配置注入

但是一般的Client都會做脫Spring處理,這裡的東西是沒辦法直接注入的

  • 第二步 : 找到對應的 Spring 包
閑談 :怎麼玩好java元件的配置注入

這裡可能會有疑惑,我都找到了 Spring 包,為什麼還要找底層,我先走第二步,再往下不就完事了嗎?

以 ES 進行舉例就是因為 ES 的變動太頻繁了,我們可能隻能從ES官方找到對應的 Client 版本,但是不太好去找這個 Client 應該對應哪個 Spring 版本。

  • 第三步 :參考 Configuration 仿寫

這個有一定難度,主要在于串通流程。

這個方法一般隻針對具有微小版本差導緻跑不起來的情況。

2.4 方案四 : 彎道超車,直接搜尋 AutoConfiguration 類

一般常用的配置在Spring AutoConfiguration 包中都會有定義,我們可以嘗試從這個包中直接進行配置 ,

但是這種方案的前提是你的 Configuration 能和對應元件比對正确。

當然,通常Spring在寫這些配置類的時候,也是基于接口進行的開發,從某種形式上說也是為了避免這類版本偏差大的問題。

但是你碰到 Elastic 這種小版本 = 大變動的元件,那就沒辦法了。

總結

東西不多,主要是思考和總結。

感覺沒有把那種想法描述清楚 ,還是得靠意會。

這些年不過是自己寫Demo還是做技術調研,都涉及到這種配置不知道咋搞的場景。這些方式也是慢慢摸索出來的,也許也和經驗多了有關,但是方法論多多少少還是有點用處的。