查看接口注释:根据给定的注释元数据,根据需要注册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定义
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 { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { // 创建beanDefinitionBuilder BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(StudentBean.class); beanDefinitionBuilder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE); // 获取beanDefinition AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition(); BeanDefinitionHolder beanDefinitionHolder = new BeanDefinitionHolder(beanDefinition, StudentBean.class.getSimpleName()); // 注册beanDefinition BeanDefinitionReaderUtils.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); }}
在使用mybatis时,我们需要指定mapper的扫描路径:
@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 { @Override public 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时,我们需要指定feign接口扫描路径:
@EnableFeignClients(basePackages = ""com.test.demo")
查看@EnableFeignClients源码,发现导入了FeignClientsRegistrar类,该类实现了ImportBeanDefinitionRegistrar接口。
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)@Documented@Import(FeignClientsRegistrar.class)public @interface EnableFeignClients
FeignClientsRegistrar类(截取部分代码):
class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata metadata,BeanDefinitionRegistry registry) { registerDefaultConfiguration(metadata, registry); registerFeignClients(metadata, registry); }}
扫描所有加了@FeignClient注解的接口,接着注册FeignClientFactoryBean类型的BeanDefinition到容器中,需要使用时生成具体的接口代理实现服务调用。
本文链接://www.dmpip.com//www.dmpip.com/showinfo-26-11740-0.htmlSpring扩展点之ImportBeanDefinitionRegistrar
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com