spring扩展点之ImportBeanDefinitionRegistrar
一、是什么?查看接口注释:根据给定的注释元数据,根据需要注册bean定义......spring会遍历所有的beanDefinition,逐个创建对应的bean 。
public interface ImportBeanDefinitionRegistrar { /*** Register bean definitions as necessary based on the given annotation metadata of* the importing {@code @Configuration} class.......(截取部分注释)*/ default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,BeanNameGenerator importBeanNameGenerator) {registerBeanDefinitions(importingClassMetadata, registry); } default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { }}
PS:创建bean还有哪些方式?
1、@Component、@Bean等等2、@Import(导入类)3、实现ImportSelector接口,重写selectImports方法,返回需要导入的全类名4、实现ImportBeanDefinitionRegistrar接口,注册bean定义
二、demo案例StudentBean:学生类
public class StudentBean {private String stuName;public String getStuName() {return stuName;}public void setStuName(String stuName) {this.stuName = stuName;}}
StudentImportBeanDefinitionRegistrar:实现ImportBeanDefinitionRegistrar接口
@Componentpublic class StudentImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {// 创建beanDefinitionBuilderBeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(StudentBean.class);beanDefinitionBuilder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);// 获取beanDefinitionAbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();BeanDefinitionHolder beanDefinitionHolder = new BeanDefinitionHolder(beanDefinition, StudentBean.class.getSimpleName());// 注册beanDefinitionBeanDefinitionReaderUtils.registerBeanDefinition(beanDefinitionHolder, registry);}}
启动类:使用@Import导入
StudentImportBeanDefinitionRegistrar类
@Import(StudentImportBeanDefinitionRegistrar.class)@SpringBootApplicationpublic class DemoApplication {public static void mAIn(String[] args) {ConfigurableApplicationContext applicationContext = SpringApplication.run(DemoApplication.class, args);StudentBean studentBean = applicationContext.getBean(StudentBean.class);System.out.println("studentBean: " + studentBean);}}
文章插图
我们大都习惯使用@Enable***方式引入某个组件,此处可稍作改造 。
新增注解:EnableStudentBean
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)@Documented@Import(StudentImportBeanDefinitionRegistrar.class)public @interface EnableStudentBean {}
启动类修改:@EnableStudentBean@SpringBootApplicationpublic class DemoApplication {public static void main(String[] args) {ConfigurableApplicationContext applicationContext = SpringApplication.run(DemoApplication.class, args);StudentBean studentBean = applicationContext.getBean(StudentBean.class);System.out.println("studentBean: " + studentBean);}}
三、ImportBeanDefinitionRegistrar在其他开源项目中的使用- MyBatis
@MapperScan(basePackages = "com.test.demo.dao.mapper")
查看@MapperScan源码,发现导入了MapperScannerRegistrar类,该类实现了ImportBeanDefinitionRegistrar接口
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)@Documented@Import(MapperScannerRegistrar.class)@Repeatable(MapperScans.class)public @interface MapperScan
MapperScannerRegistrar类(截取部分代码):public class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {// 获取MapperScan注解AnnotationAttributes mapperScanAttrs = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));if (mapperScanAttrs != null) {// 扫描对应的mapper接口,并注册BeanDefinition(bean定义)registerBeanDefinitions(importingClassMetadata, mapperScanAttrs, registry,generateBaseBeanName(importingClassMetadata, 0));}}}
- Openfeign
@EnableFeignClients(basePackages = ""com.test.demo")
查看@EnableFeignClients源码,发现导入了FeignClientsRegistrar类,该类实现了
推荐阅读
- AI 作画工具 Midjourney 推出“pan”功能,可平移扩展图片外场景
- ubuntu虚拟机扩展硬盘
- 聊聊 Springboot 启动原理
- win10如何扩展虚拟的内存条
- word文档扩展名怎么改
- 电脑文件扩展名怎么改
- win7更改文件的扩展名
- 如果改变文件扩展名可能导致文件不可用 如果改变文件扩展名
- SpringBoot整合Mybatis-Plus多数据源
- VS Code 的 六个优秀 ChatGPT 扩展插件