一, ImportBeanDefinitionRegistrar 类介绍
ImportBeanDefinitionRegistrar 类通过其他 @Configuration 类通过 @Import 的方式来加载, 通常是启动类或配置类.
然后会调用该接口方法, 将其中要注册的类注册成 bean.
通过实现该接口的类拥有注册 bean 的能力.
可以实现遗下 Aware 接口
- EnvironmentAware
- BeanFactoryAware
- BeanClassLoaderAware
- ResourceLoaderAware
二, 实现注册指定类型的 Bean
1) 定义一个需要用来注册的 service 类
- /**
- * @author zhangboqing
- * @date 2019/12/13
- */
- @Slf4j
- public class HelloService {
- public void sayHello() {
- log.info("Hello!!!");
- }
- }
2) 定义 HelloImportBeanDefinitionRegistrar 类实现 ImportBeanDefinitionRegistrar 接口
- /**
- * @author zhangboqing
- * @date 2019/12/13
- */
- public class HelloImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
- @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);
- }
- }
3) 定义 HelloConfiguration 配置类, 引入 ImportBeanDefinitionRegistrar
- /**
- * @author zhangboqing
- * @date 2019/12/13
- */
- @Configuration
- @ComponentScan("com.zbq.springbootdemo.speciality.dynamicRegisterBean.ImportBeanDefinitionRegistrar")
- @Import(HelloImportBeanDefinitionRegistrar.class)
- public class HelloConfiguration {
- }
4) 定义测试类可验证 HelloService 类是否注册成功
- /**
- * @author zhangboqing
- * @date 2019/12/13
- */
- @SpringBootTest(classes = {HelloConfiguration.class})
- // 指定配置类
- //@ContextConfiguration(classes = {HelloConfiguration.class})
- public class HelloImportBeanDefinitionRegistrarTest {
- @Autowired
- private HelloService helloService;
- @Test
- public void testHelloService() {
- helloService.sayHello();
- }
- }
三, 实现注册指定注解的 Bean
1) 自定义注解 HelloAnnotation
- /**
- * @author zhangboqing
- * @date 2019/12/13
- */
- @Documented
- @Inherited
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ElementType.TYPE})
- public @interface HelloAnnotation {
- }
2) 将注解加入到 HelloService 类上
- /**
- * @author zhangboqing
- * @date 2019/12/13
- */
- @Slf4j
- @HelloAnnotation
- public class HelloService {
- public void sayHello() {
- log.info("Hello!!!");
- }
- }
3) 修改 HelloImportBeanDefinitionRegistrar 类, 将类型过滤器从指定类型变为指定注解
- /**
- * @author zhangboqing
- * @date 2019/12/13
- */
- public class HelloImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
- @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);
- // 指定注解
- TypeFilter helloServiceFilter = new AnnotationTypeFilter(HelloAnnotation.class);
- scanner.addIncludeFilter(helloServiceFilter);
- scanner.scan(basePackages);
- }
- }
4) 用上面的测试类再次验证, 同样可以
来源: http://www.bubuko.com/infodetail-3330151.html