Class RoutingMailer

java.lang.Object
io.leandev.appfuse.mail.RoutingMailer
All Implemented Interfaces:
Mailer

public class RoutingMailer extends Object implements Mailer

寄信當下解析目標的 Mailer(比照 Spring 的 routing DataSource 模式)

職責邊界

本類別不認得任何 entity、不碰持久化。郵件設定由消費端經 MailerSpecProvider 交出 MailerSpec;本類別負責把 spec 變成可用的 DirectMailer(連線、認證、政策、寄件者), 快取建構結果,並在每次寄信/組信當下解析「該用哪一個」。

消費端注入 Mailer 介面即可,不需要知道背後是動態解析還是單一設定——這正是 「框架的任務是簡化消費端的實作,設定怎麼存歸消費端」的落點。

解析順序

  1. provider 給得出當前範圍的 spec → 用它(依 spec 建構、快取)
  2. 給不出(或根本沒有 provider)→ 系統預設 Mailer(消費端組態依設定檔建立)
  3. 兩者皆無 → compose() / send(MimeMessage)MailUnavailableException

不提供 provider 的專案郵件功能照常可用,只是沒有 per-範圍設定。

快取與失效

快取鍵為 MailerSpec.id,並比對 MailerSpec.revision——指紋變了自動重建。 消費端因此不需要在異動設定後記得清快取(那是典型「忘了就靜默用舊憑證寄信」的陷阱)。

成本為零:解析本來就每次都問一次 provider,快取省的是 Mailer 的建構、不是查詢。

外寄政策

防火牆/白名單/debug/改寄/特殊訊息一律由建構時傳入的 MailOutboundPolicy 承載, 依 spec 建立的 Mailer 與系統預設 Mailer 走同一份政策(僅主旨前綴可由 spec 覆寫)。

  • Constructor Details

    • RoutingMailer

      public RoutingMailer(MailerSpecProvider specProvider, DirectMailer systemDefault, MailOutboundPolicy outboundPolicy)
      Parameters:
      specProvider - 郵件設定來源;null 表示本部署無範圍專屬設定
      systemDefault - 系統預設 Mailer;null 表示未配置系統郵件
      outboundPolicy - 環境層外寄政策(依 spec 建 Mailer 時套用)
  • Method Details

    • current

      public Optional<Mailer> current()
      解析當前範圍的預設 Mailer(provider → 系統預設 → empty)
    • named

      public Optional<Mailer> named(String configName)

      解析具名設定的 Mailer

      不 fallback 到系統預設——指名了某個設定卻悄悄用別的,會讓寄件身分與預期不符。

    • isAvailable

      public boolean isAvailable()
      當前範圍是否有可用的郵件服務
    • hasSystemDefault

      public boolean hasSystemDefault()
      系統預設 Mailer 是否已配置
    • compose

      public MimeMessageBuilder compose()
      Description copied from interface: Mailer
      組一封信(from 已預填為本 Mailer 的預設寄件者)
      Specified by:
      compose in interface Mailer
    • send

      public void send(jakarta.mail.internet.MimeMessage mimeMessage) throws org.springframework.mail.MailException
      Description copied from interface: Mailer
      寄出一封已組好的 MimeMessage(外寄政策——防火牆/改寄/特殊訊息——在此套用)
      Specified by:
      send in interface Mailer
      Throws:
      org.springframework.mail.MailException
    • testConnection

      public Mailer.MailConnectionTestResult testConnection()
      Description copied from interface: Mailer
      測試與郵件伺服器的連線
      Specified by:
      testConnection in interface Mailer
    • cacheSize

      public int cacheSize()
      快取中的 Mailer 數量
    • evict

      public void evict(String specId)

      丟棄指定設定的快取

      一般不需要呼叫——MailerSpec.revision 變更會自動觸發重建。保留給「外部憑證輪換 但 revision 未變」這類 provider 表達不出的情況。

    • evictAll

      public void evictAll()
      丟棄全部快取(平台維運動作)