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本質(zhì)上是一個接口。在ImportBeanDefinitionRegistrar接口中,有一個registerBeanDefinitions()方法,通過registerBeanDefinitions()方法,我們可以向Spring容器中注冊bean實例。Spring官方在動態(tài)注冊bean時,大部分套路其實是使用ImportBeanDefinitionRegistrar接口。所有實現(xiàn)了該接口的類都會被ConfigurationClassPostProcessor處理,ConfigurationClassPostProcessor實現(xiàn)了BeanFactoryPostProcessor接口,進一步實現(xiàn)了BeanDefinitionRegistryPostProcessor。該接口主要功能是參與BeanFactory的建造,主要功能如下: 解析加了@Configuration的配置類 解析@ComponentScan掃描的包 解析@ComponentScans掃描的包,解析@Bean,@Import ,@PreopertySource。所以ImportBeanDefinitionRegistrar中動態(tài)注冊的bean是優(yōu)先于依賴其的bean初始化的,也能被aop、validator等機制處理。
- 實現(xiàn)了ImportBeanDefinitionRegistrar的類,在refresh的invokeBeanFactoryPostProcessors階段,調(diào)用到最后,會調(diào)用到registerBeanDefinitios
ImportBeanDefinitionRegistrar調(diào)用鏈
二、使用方法
ImportBeanDefinitionRegistrar需要配合@Import注解,@Import注解導(dǎo)入實現(xiàn)了ImportBeanDefinitionRegistrar接口的類。
既然ImportBeanDefinitionRegistrar是一個接口,那我們就創(chuàng)建一個MyImportBeanDefinitionRegistrar類,實現(xiàn)ImportBeanDefinitionRegistrar接口,如下所示。
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar{/*** AnnotationMetadata: 當(dāng)前類的注解信息* BeanDefinitionRegistry:BeanDefinition注冊類* 通過調(diào)用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 注解,我們根據(jù)條件判斷,動態(tài)引入了MyDao3.class
三、大部分框架的套路也如此
參考文章
總結(jié)
以上是生活随笔為你收集整理的ImportBeanDefinitionRegistrar向容器中注册bean的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 互联网日报 | 小米11取消随机附送充电
- 下一篇: 2020快手母婴行业数据价值报告