日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring Boot - 自动装配中的不可忽视的@Import

發(fā)布時(shí)間:2025/3/21 javascript 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Boot - 自动装配中的不可忽视的@Import 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • Pre
  • 四種處理方式
  • 從@SpringBootApplication注解說起
    • @SpringBootApplication組合注解說明
      • @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited
      • @SpringBootCon?guration
      • @EnableAutoConfiguration
      • @ComponentScan
    • @EnableAutoConfiguration
      • @AutoConfigurationPackage
      • @Import(AutoConfigurationImportSelector.class)
  • @Import源碼
    • @Import 普通組件
    • @Import 實(shí)現(xiàn)了ImportSelector接口的組件 (類的全限定類名)
    • @Import 實(shí)現(xiàn)了ImportBeanDefinitionRegistrar接口的組件
  • 最佳實(shí)踐 @EnableXXX
    • 【自定義注解 @EnableArtisan】
    • 將AppConfig.java添加@EnableArtisan
  • 源碼

Pre

Spring Boot - 自動(dòng)配置實(shí)現(xiàn)原理


四種處理方式

在使用 Spring Boot 時(shí),@Import 也是一個(gè)非常常見的注解,可以用來動(dòng)態(tài)創(chuàng)建 Bean。

在 @Import 注解的屬性中可以設(shè)置需要引入的類名,例如 @AutoConfigurationPackage 注解上的 @Import(AutoConfigurationPackages.Registrar.class)。根據(jù)該類的不同類型,Spring 容器針對 @Import 注解有以下四種處理方式:

  • 如果該類實(shí)現(xiàn)了 ImportSelector 接口,Spring 容器就會(huì)實(shí)例化該類,并且調(diào)用其 selectImports 方法;
  • 如果該類實(shí)現(xiàn)了 DeferredImportSelector 接口,則 Spring 容器也會(huì)實(shí)例化該類并調(diào)用其 selectImports方法。DeferredImportSelector 繼承了 ImportSelector,區(qū)別在于 DeferredImportSelector 實(shí)例的 selectImports 方法調(diào)用時(shí)機(jī)晚于 ImportSelector 的實(shí)例,要等到 @Configuration 注解中相關(guān)的業(yè)務(wù)全部都處理完了才會(huì)調(diào)用;
  • 如果該類實(shí)現(xiàn)了 ImportBeanDefinitionRegistrar 接口,Spring 容器就會(huì)實(shí)例化該類,并且調(diào)用其 registerBeanDefinitions 方法;
  • 如果該類沒有實(shí)現(xiàn)上述三種接口中的任何一個(gè),Spring 容器就會(huì)直接實(shí)例化該類。

我們來搞一搞@Import吧


從@SpringBootApplication注解說起

我們都知道 啟動(dòng)一個(gè)SpringBoot應(yīng)用 無須各種的配置文件,無須各種繁雜的pom依賴,一個(gè)main方法,就能run起來了。

與其他框架整合也相當(dāng)方便,使用EnableXXXXX注解就可以完成整合

那SpringBoot是如何實(shí)現(xiàn)自動(dòng)配置的????


@SpringBootApplication組合注解說明

@SpringBootApplication: Spring Boot應(yīng)用標(biāo)注在某個(gè)類上說明這個(gè)類是SpringBoot的主配置類,SpringBoot需要運(yùn)行這個(gè)類的main方法來啟動(dòng)SpringBoot應(yīng)用

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited

注解說明:

  • @Target(ElementType.TYPE) 設(shè)置當(dāng)前注解可以標(biāo)記在哪
  • @Retention(RetentionPolicy.RUNTIME) 當(dāng)注解標(biāo)注的類編譯以什么方式保留。 RetentionPolicy.RUNTIME 會(huì)被jvm加載
  • @Documented java doc 會(huì)生成注解信息
  • @Inherited 是否會(huì)被繼承

更詳細(xì)的請參考我以前寫的一篇博文: Java-Java5.0注解解讀


@SpringBootCon?guration

Spring Boot的配置類 , 標(biāo)注在某個(gè)類上,表示這是一個(gè)Spring Boot的配置類


@EnableAutoConfiguration

開啟自動(dòng)配置功能 , @EnableAutoCon?guration告訴SpringBoot開啟自動(dòng)配置,會(huì)自動(dòng)去加載自動(dòng)配置類


@ComponentScan

相當(dāng)于在spring.xml 配置中<context:comonent-scan> 但是并沒有指定basepackage,如果沒有指定spring底層會(huì)自動(dòng)掃描當(dāng)前配置類所有在的包


@EnableAutoConfiguration

SpringBootApplication注解中最重要的一個(gè)注解就是 @EnableAutoConfiguration.

@AutoConfigurationPackage

將當(dāng)前配置類所在包保存在BasePackages的Bean中。供Spring內(nèi)部使用

使用了@Import注解 保存掃描路徑, 注冊

那看下 org.springframework.boot.autoconfigure.AutoConfigurationPackages.Registrar


@Import(AutoConfigurationImportSelector.class)

關(guān)鍵點(diǎn)!

可以看到,在@EnableAutoConfiguration注解內(nèi)也使用到了@Import注解來完成導(dǎo)入配置的功能


那都用它,我們來搞搞@Import吧


@Import源碼


@Import表示要導(dǎo)入的一個(gè)或多個(gè)@Configuration類

我們來看下value方法源碼中的注釋: Configuration,ImportSelector,ImportBeanDefinitionRegistrar 或者是一個(gè)普通的組件

那分別來看下如何使用吧

POM 核心 有個(gè)context就夠了

<dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.18</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.6.RELEASE</version></dependency></dependencies>

@Import 普通組件

@Import({ 要導(dǎo)入的組件 } )

【模擬第三方框架提供的】

package com.artisan.configuration;import com.artisan.beans.Artisan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;/*** @author 小工匠* @version 1.0* @description: 自定義的配置類 類比第三方的配置類* @date 2021/5/22 8:50* @mark: show me the code , change the world*/@Configuration public class ArtisanConfig {@Beanpublic Artisan artisan() {Artisan artisan = new Artisan();artisan.setName("小工匠");artisan.setAge(18);return artisan;} }

【模擬Spring自己的】

/*** 系統(tǒng)當(dāng)前加載的配置類*/@Configuration @Import({ArtisanConfig.class}) // @Import(ArtisanImportSelector.class) //@Import(ArtisanRegistrar.class) //@EnableArtisan public class AppConfig { }

將AppConfig.java添加注解 @Import({ArtisanConfig.class}) , 將第三方的配置類導(dǎo)入到Bean容器中 , 本質(zhì)上就是導(dǎo)入 一個(gè)Configuration配置類組件

【測試類】

public class Main {public static void main(String[] args) {AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);Artisan artisan = ctx.getBean(Artisan.class);System.out.println(artisan);} }

【測試結(jié)果】


@Import 實(shí)現(xiàn)了ImportSelector接口的組件 (類的全限定類名)

【ImportSelector接口 返回全限定名】

package com.artisan.impt;import org.springframework.context.annotation.ImportSelector; import org.springframework.core.type.AnnotationMetadata;/*** @author 小工匠* @version 1.0* @description: TODO* @date 2021/5/22 9:25* @mark: show me the code , change the world*/ public class ArtisanImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {return new String[]{"com.artisan.beans.Artisan"};} }

【AppConfig - @Import(ArtisanImportSelector.class)】

/*** 系統(tǒng)當(dāng)前加載的配置類*/@Configuration //@Import({ArtisanConfig.class})@Import(ArtisanImportSelector.class) //@Import(ArtisanRegistrar.class) //@EnableArtisan public class AppConfig { }

測試

ArtisanSelector返回的類的全限定類名,即為導(dǎo)入到容器中的組件全類名


@Import 實(shí)現(xiàn)了ImportBeanDefinitionRegistrar接口的組件

【ImportBeanDefinitionRegistrar 接口】

package com.artisan.impt;import com.artisan.beans.Artisan; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.type.AnnotationMetadata;/*** @author 小工匠* @version 1.0* @description: TODO* @date 2021/5/22 9:28* @mark: show me the code , change the world*/ public class ArtisanRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(Artisan.class);builder.setScope(BeanDefinition.SCOPE_SINGLETON);builder.addPropertyValue("name", "小工匠Registrar");builder.addPropertyValue("age", "18");registry.registerBeanDefinition("artisan", builder.getBeanDefinition());} }

【AppConfig - @Import(ArtisanRegistrar.class) 】

/*** 系統(tǒng)當(dāng)前加載的配置類*/@Configuration //@Import({ArtisanConfig.class}) // @Import(ArtisanImportSelector.class) @Import(ArtisanRegistrar.class) //@EnableArtisan public class AppConfig { }

【測試】

ImportBeanDefinitionRegistrar類似于ImportSelector用法,只不過這種用法能自定義化注冊,往容器內(nèi)注入一個(gè)BeanDefinition,然后BeanDeiniton在容器內(nèi)轉(zhuǎn)為一個(gè)實(shí)例bean。


最佳實(shí)踐 @EnableXXX

【自定義注解 @EnableArtisan】

package com.artisan.annotation;import com.artisan.configuration.ArtisanConfig; import com.artisan.impt.ArtisanImportSelector; import com.artisan.impt.ArtisanRegistrar; import org.springframework.context.annotation.Import;import java.lang.annotation.*;@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented// @Import({ArtisanConfig.class}) @Import({ArtisanImportSelector.class}) 都可以 @Import({ArtisanRegistrar.class}) public @interface EnableArtisan {}

將AppConfig.java添加@EnableArtisan

【測試結(jié)果】


源碼

https://github.com/yangshangwei/boot2/tree/master/spring_maven

總結(jié)

以上是生活随笔為你收集整理的Spring Boot - 自动装配中的不可忽视的@Import的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。