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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ImportBeanDefinitionRegistrar向容器中注册bean

發布時間:2025/3/15 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ImportBeanDefinitionRegistrar向容器中注册bean 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、ImportBeanDefinitionRegistrar

我們先來看看ImportBeanDefinitionRegistrar是個什么鬼,點擊進入ImportBeanDefinitionRegistrar源碼,如下所示。

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

由源碼可以看出,ImportBeanDefinitionRegistrar本質上是一個接口。在ImportBeanDefinitionRegistrar接口中,有一個registerBeanDefinitions()方法,通過registerBeanDefinitions()方法,我們可以向Spring容器中注冊bean實例。Spring官方在動態注冊bean時,大部分套路其實是使用ImportBeanDefinitionRegistrar接口。所有實現了該接口的類都會被ConfigurationClassPostProcessor處理,ConfigurationClassPostProcessor實現了BeanFactoryPostProcessor接口,進一步實現了BeanDefinitionRegistryPostProcessor。該接口主要功能是參與BeanFactory的建造,主要功能如下: 解析加了@Configuration的配置類 解析@ComponentScan掃描的包 解析@ComponentScans掃描的包,解析@Bean,@Import ,@PreopertySource。所以ImportBeanDefinitionRegistrar中動態注冊的bean是優先于依賴其的bean初始化的,也能被aop、validator等機制處理。

  • 實現了ImportBeanDefinitionRegistrar的類,在refresh的invokeBeanFactoryPostProcessors階段,調用到最后,會調用到registerBeanDefinitios

ImportBeanDefinitionRegistrar調用鏈

二、使用方法

ImportBeanDefinitionRegistrar需要配合@Import注解,@Import注解導入實現了ImportBeanDefinitionRegistrar接口的類。

  • ImportBeanDefinitionRegistrar實例
  • 既然ImportBeanDefinitionRegistrar是一個接口,那我們就創建一個MyImportBeanDefinitionRegistrar類,實現ImportBeanDefinitionRegistrar接口,如下所示。

    public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar{/*** AnnotationMetadata: 當前類的注解信息* BeanDefinitionRegistry:BeanDefinition注冊類* 通過調用BeanDefinitionRegistry接口的registerBeanDefinition()方法,可以將所有需要添加到容器中的bean注入到容器中。*/@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {boolean dao1= registry.containsBeanDefinition("com.myImportBeanDefinitionRegistrar.MyDao1");boolean dao2= registry.containsBeanDefinition("com.myImportBeanDefinitionRegistrar.MyDao2");if (dao2 && dao1){BeanDefinition beanDefinition = new RootBeanDefinition(MyDao3.class);registry.registerBeanDefinition("myDao3", beanDefinition);}} } public class MyDao(1/2/3) {public void query(){System.out.println("query MyDao for MyImportSelect");} } @Import({MyDao1.class,MyDao2.class}) @EnableMyImportBeanDefinitionRegistrar public class AppConfig { }@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @Import(MyImportBeanDefinitionRegistrar.class) public @interface EnableMyImportBeanDefinitionRegistrar { }public class MyTest {public static void main(String[] args) {AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);Arrays.stream(ctx.getBeanDefinitionNames()).toList().forEach(System.out::println);} }

    通過EnableMyImportBeanDefinitionRegistrar 注解,我們根據條件判斷,動態引入了MyDao3.class

    三、大部分框架的套路也如此

  • openFeign
  • @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @Import(FeignClientsRegistrar.class) public @interface EnableFeignClients {}FeignClientsRegistrar實現了ImportBeanDefinitionRegistrar接口
  • mybatis
  • @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented @Import({MapperScannerRegistrar.class}) @Repeatable(MapperScans.class) public @interface MapperScan {}MapperScannerRegistrar實現了ImportBeanDefinitionRegistrar接口
  • 也有的是實現importSelector接口,通過返回一個包含類名的數組進行注入的
  • 參考文章

    總結

    以上是生活随笔為你收集整理的ImportBeanDefinitionRegistrar向容器中注册bean的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。