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());
}
}
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


