不是銀趴~是@Import!

来源:https://www.cnblogs.com/cosimo/Undeclared/17956511
-Advertisement-
Play Games

首先我們要明確:@Import 註解是 Spring 提供的。 然後我們看一下該註解的官方註釋: Indicates one or more component classes to import — typically @Configuration classes. Provides functi ...


首先我們要明確:@Import 註解是 Spring 提供的。

然後我們看一下該註解的官方註釋:

Indicates one or more component classes to import — typically @Configuration classes.

Provides functionality equivalent to the <import/> element in Spring XML. Allows for importing @Configuration classes, ImportSelector and ImportBeanDefinitionRegistrar implementations, as well as regular component classes (as of 4.2; analogous to AnnotationConfigApplicationContext.register).

@Bean definitions declared in imported @Configuration classes should be accessed by using @Autowired injection. Either the bean itself can be autowired, or the configuration class instance declaring the bean can be autowired. The latter approach allows for explicit, IDE-friendly navigation between @Configuration class methods.

May be declared at the class level or as a meta-annotation.

If XML or other non-@Configuration bean definition resources need to be imported, use the @ImportResource annotation instead.

我們將其中我們關心的重要部分提取出來翻譯整理如下:

  • 該註解可導入一個或多個組件類——通常是Configuration類。

  • 允許導入@Configuration類、ImportSelector介面和ImportBeanDefinitionRegistrar介面的實現,以及普通類(從4.2版本開始)。

  • @Import註解可以在類上聲明,也可以作為元註解聲明在其他註解上。

那麼 @Import 註解到底有什麼作用和優勢呢?

記住下麵幾句話:

導入配置。

從各個地方、通過各種方式導入配置。

在你需要的時候,從各個地方、通過各種方式導入配置。

在你需要的時候,從各個地方、通過各種方式導入並改造成你喜歡的配置。


下麵我們通過示例講 4 種官方註釋給出的導入類型,分別是:

  • 普通類

  • @Configuration類

  • ImportSelector介面實現

  • ImportBeanDefinitionRegistrar介面實現

普通類

普通類不必啰嗦,有手就行。

public class Circle {
}
@Configuration
@Import({Circle.class})
public class MainConfig {
}

導入@Configuration類

我們建立三個不同的模塊,MainModule, Module1, Module2。

讓 MainModule 引入 Module1、Module2依賴。

在 MainModule 中創建 MainConfig 類如下:

@Configuration
@Import({Config1.class, Config2.class})
public class MainConfig {
}

很明顯,Config1,Config2 分別屬於2個模塊,如下:

@Configuration
public class Config1 {
    @Bean
    public String config1() {
        return "我是config1配置類!";
    }
}
@Configuration
public class Config2 {
    @Bean
    public String config2() {
        return "我是config2配置類!";
    }
}

在 MainModule 中創建測試類看是否生效:

@Test
void contextLoads() {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
    for (String name : context.getBeanDefinitionNames()) {
        System.out.println(String.format("%s->%s", name, context.getBean(name)));
    }
}

測試結果如下:

mainConfig->com.example.annotation.config.MainConfig$$EnhancerBySpringCGLIB$$a98d5b6a@55a609dd
com.example.module1.config1->com.example.module1.config.Config1$$EnhancerBySpringCGLIB$$72aca5d0@4afd21c6
config1->我是config1配置類!
com.example.module2.config2->com.example.module2.config.Config2$$EnhancerBySpringCGLIB$$72aca5d0@4afd21c6
config2->我是config2配置類!

ImportSelector介面實現

首先我們需要認識一下 ImportSelector 介面:

public interface ImportSelector {

    String[] selectImports(AnnotationMetadata importingClassMetadata);

    @Nullable
    default Predicate<String> getExclusionFilter() {
        return null;
    }
}

只有一個需要實現的方法:

selectImports

參數 AnnotationMetadata 是什麼?

翻譯為註解元數據。

有什麼用?

用來獲取被@Import標註的類上面所有的註解信息。

String[] 是什麼?

返回需要導入的類名的數組,可以是任何普通類,配置類。

上示例:

創建一個配置類

@Configuration
public class Config {
    @Bean
    public String name() {
        return "公眾號:JavaCode";
    }
}

定義一個ImportSelectors實現類

public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{
                Config.class.getName()
        };
    }
}

上述代碼中需要說明一下,Config.class.getName() 得到的是類的全類名,也就是[包名.類名],也就是com.example.annotation.pojo.Config。

導入MyImportSelector

@Import({MyImportSelector.class})
public class MainConfig {
}

這時候有人問了:

這裡怎麼沒有 @Configuration 註解?

沒關係哈,雖然 @Import 註解通常是與 @Configuration 註解一起使用的,但不是絕對必要的。

ImportBeanDefinitionRegistrar介面實現

首先我們還是先認識一下 ImportBeanDefinitionRegistrar 介面:

public interface ImportBeanDefinitionRegistrar {

    default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
        registerBeanDefinitions(importingClassMetadata, registry);
    }
    default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    }
}

可以看到只有2個方法,第一個方法調用第二個方法,所以我們就只看第二個方法就好了。

AnnotationMetadata 我們前邊說過了:

用來獲取被@Import標註的類上面所有的註解信息。

BeanDefinitionRegistry 呢?

它是一個介面,內部提供了註冊bean的各種方法,用於我們手動註冊bean。

上示例:

創建一個 Java 類

public class Rectangle {
    public void sayHi() {
        System.out.println("Rectangle sayHi()");
    }
}

創建 ImportBeanDefinitionRegistrar 實現類

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Rectangle.class);
        // 註冊一個名字叫做 rectangle 的 bean
        registry.registerBeanDefinition("rectangle", rootBeanDefinition);
    }
}

總結

第一種:

我們有什麼就可以導什麼。

第二種:

我們可以把分散的配置集中起來,更加清晰和有組織。

第三種:

除了我們模塊現有的配置,你只要能拿到類的全類名,就能註冊進來。

第四種:

我們不光能到處拿,我們還能拿來以後隨便改!

以上四種方式就實現了我們當初的豪言:

導入配置。

從各個地方、通過各種方式導入配置。

在你需要的時候,從各個地方、通過各種方式導入配置。

在你需要的時候,從各個地方、通過各種方式導入並改造成你喜歡的配置。


● 終於搞懂動態代理了!

● 學會@ConfigurationProperties月薪過三千

● 學一點關於JVM類載入的知識

● Java註解,看完就會用

● Java反射,看完就會用

● @Value是個什麼東西


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、從痛點中思考答案 痛點一:複雜系統的設計和邏輯碎片化散落,缺少沉澱導致系統後期維護、迭代以及架構升級都非常困難。 痛點二:由於新需求或新項目導致的系統的老舊邏輯梳理往往耗費大量人力,甚至造成人才的流失。 痛點三:多團隊共建場景下需要參與各方瞭解跨應用系統的整體設計,溝通效率低成本高、共建初期花費 ...
  • 第1章電腦組成與體繫結構 1. 電腦系統組成 電腦系統是一個硬體和軟體的綜合體,可以把它看成按功能劃分的多級層次結構。 系統軟體支持應用軟體的運行,為用戶開發應用軟體提供平臺,用戶可以使用它,但不能隨意修改它。常用的系統軟體有操作系統、語言處理程式、連接程式、診斷程式和資料庫管理系統等。 1. ...
  • C 語言中的文件讀取 要從文件讀取,可以使用 r 模式: FILE *fptr; // 以讀取模式打開文件 fptr = fopen("filename.txt", "r"); 這將使 filename.txt 打開以進行讀取。 在 C 中讀取文件需要一點工作。堅持住!我們將一步一步地指導您。 接下 ...
  • Bookinfo 應用 這個示例部署了一個用於演示多種 Istio 特性的應用,該應用由四個單獨的微服務構成。 如安裝了 Istio,說明已安裝 Bookinfo。 這個應用模仿線上書店的一個分類,顯示一本書的信息。 頁面上會顯示一本書的描述,書籍的細節(ISBN、頁數等),及書評。 Bookinf ...
  • 操作系統的主要功能是進行處理機與進程管理、存儲管理、設備管理、文件管理和作業管理的工作,本節討論操作系統是如何完成這些功能的。 ...
  • 轉載至我的博客 ,公眾號:架構成長指南 在金融系統中,我們會跟錢打交道,而保證在高併發下場景下,對賬戶餘額操作的一致性,是非常重要的,如果代碼寫的時候沒考慮併發一致性,就會導致資損,本人在金融行業幹了 8 年多,對這塊稍微有點經驗,所以這篇聊一下,如何在併發場景下,保證賬戶餘額的一致性 1. 扣款流 ...
  • Gorm 入門介紹與基本使用 目錄Gorm 入門介紹與基本使用一、ORM簡介1.1 什麼是ORM1.2 使用ORM的好處1.2.1 避免直接操作SQL語句1.2.2 提高代碼的可維護性1.2.3 跨資料庫相容性1.3 使用ORM的缺點1.3.1 學習成本1.3.2 性能開銷1.4 ORM解析過程1. ...
  • 第1部分:ABAP OOALV相關文章合集 序號 文章標題 01 ABAP OOALV-基本顯示 02 ABAP OOALV-排序、過濾 03 ABAP OOALV-合計、小計 04 ABAP OOALV-選擇模式、觸發事件 05 ABAP OOALV-隱藏列、修改列標題、添加圖標列、調整列位置 0 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...