ImportBeanDefinitionRegistrar接口的作用是什么呢?
下文笔者讲述ImportBeanDefinitionRegistrar接口的功能简介说明,如下所示
ImportBeanDefinitionRegistrar接口功能
当一个类是ImportBeanDefinitionRegistrar接口的实现类 如果我们使用@import注解导入这个类时 会运行ImportBeanDefinitionRegistrar的registerBeanDefinitions方法 然后生成BeanDefinition对象 并最终注册到BeanDefinitionRegistry 实现ImportBeanDefinitionRegistrar接口的类:拥有注册类的能力
例:手动将一个类注册成bean
首先写一个类,最终要把它注册为bean。 public class HelloService { } //自定义ImportBeanDefinitionRegistrar实现类手动注册bean。 public class HelloImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { /** * @Description AnnotationMetadata:当前类的注解信息; * BeanDefinitionRegistry:注册类,其registerBeanDefinition()可以注册bean **/ @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //扫描注解 Map<String, Object> annotationAttributes = importingClassMetadata .getAnnotationAttributes(ComponentScan.class.getName()); String[] basePackages = (String[]) annotationAttributes.get("basePackages"); //扫描类 ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry, false); TypeFilter helloServiceFilter = new AssignableTypeFilter(HelloService.class); scanner.addIncludeFilter(helloServiceFilter); scanner.scan(basePackages); } } //定义一个配置类发现一下上面的ImportBeanDefinitionRegistrar实现类。 @Configuration @ComponentScan("com.java265.import2.domain") @Import(HelloImportBeanDefinitionRegistrar.class) public class HelloConfiguration { } //测试: @RunWith(SpringRunner.class) @SpringBootTest @ContextConfiguration(classes = {HelloConfiguration.class}) //表示只需要这一个文件 public class DemoApplicationTest2 { @Resource HelloService helloService; /** * @Description 扫描到helloService **/ @Test public void contextLoads(){ System.out.println(helloService.getClass()); } } @Mapper: @Documented @Inherited @Retention(RetentionPolicy.Runtime) @Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER}) public @interface Mapper { } @Mapper public class CountryMapper { } //实现ImportBeanDefinitionRegistrar接口 //重写registerBeanDefinitions方法 //手动注册bean:同时实现一些Aware接口,以便获取Spring的一些数据 public class MapperAutoConfiguredMyBatisRegistrar implements ImportBeanDefinitionRegistrar,ResourceLoaderAware,BeanFactoryAware { private ResourceLoader resourceLoader; private BeanFactory beanFactory; /** * @Description 注册bean,但我们并不知道需要注册哪些bean,所以需要借助 * ClassPathBeanDefinitionScanner扫描器,扫描我们需要注册的bean **/ @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) { MyClasssPathBeanDefinitionScanner scanner= new MyClasssPathBeanDefinitionScanner(registry,false); scanner.setResourceLoader(resourceLoader); scanner.registerFilters(); scanner.doScan("com.java265.import1.domain"); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory=beanFactory; } @Override public void setResourceLoader(ResourceLoader resourceLoader) { this.resourceLoader=resourceLoader; } } //还借助扫描器ClassPathBeanDefinitionScanner //通过它来获取我们需要注册的bean public class MyClasssPathBeanDefinitionScanner extends ClassPathBeanDefinitionScanner { public MyClasssPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) { super(registry, useDefaultFilters); } /** * @Description 注册条件过滤器,将@Mapper注解加入允许扫描的过滤器中, * 如果加入排除扫描的过滤器集合excludeFilter中,则不会扫描 **/ protected void registerFilters(){ addIncludeFilter(new AnnotationTypeFilter(Mapper.class)); } @Override protected Set<BeanDefinitionHolder> doScan(String... basePackages) { return super.doScan(basePackages); } } //测试 @RunWith(SpringRunner.class) @SpringBootTest(classes = MapperAutoConfig.class) //只将MapperAutoConfig类纳入测试环境的Spring容器中, //或@ContextConfiguration(classes = {MapperAutoConfig.class}) public class DemoApplicationTest { @Resource CountryMapper countryMapper; @Test public void contextLoads(){ System.out.println(countryMapper.getClass()); } }
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。