ImportBeanDefinitionRegistrar接口的作用是什么呢?

书欣 Spring 发布时间:2023-03-22 22:40:17 阅读数:17217 1
下文笔者讲述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());
  }
}
 
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaFramework/Spring/202303/6136.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者