ImportBeanDefinitionRegistrar介绍
在上一篇博文http://elim.iteye.com/blog/2428994中介绍了ImportSelector的作用及其用法。本文需要介绍的ImportBeanDefinitionRegistrar的用法和作用跟ImportSelector类似。唯一的不同点是ImportBeanDefinitionRegistrar的接口方法void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)
的返回类型是void
,且多了一个BeanDefinitionRegistry类型的参数,它允许我们直接通过BeanDefinitionRegistry对象注册bean。承接上文内容,为了扫描并注册HelloService类型的bean,我们可以自定义如下ImportBeanDefinitionRegistrar实现类。在实现类中可以使用ClassPathBeanDefinitionScanner进行扫描并自动注册,它是ClassPathScanningCandidateComponentProvider的子类,所以还是可以添加相同的TypeFilter,然后通过scanner.scan(basePackages)
扫描指定的basePackage下满足条件的Class并注册它们为bean。
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);
}
}
此时我们的@Configuration
配置类可以进行如下定义。
@Configuration
@ComponentScan("com.elim.spring.core.importselector")
@Import(HelloImportBeanDefinitionRegistrar.class)
public class HelloConfiguration {
}
为它定义一个特定的注解也是可以的,比如下面代码为HelloImportBeanDefinitionRegistrar定义了@HelloScan
,其value属性和basePackages属性互为别名,用于指定需要扫描的basePackage。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(HelloImportBeanDefinitionRegistrar.class)
public @interface HelloScan {
@AliasFor("value")
String[] basePackages() default {};
@AliasFor("basePackages")
String[] value() default {};
}
为了满足@HelloScan
指定扫描的basePackage的需求,我们的HelloImportBeanDefinitionRegistrar需要改造为如下这样。
public class HelloImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(HelloScan.class.getName());
String[] basePackages = (String[]) annotationAttributes.get("basePackages");
if (basePackages == null || basePackages.length == 0) {//HelloScan的basePackages默认为空数组
String basePackage = null;
try {
basePackage = Class.forName(importingClassMetadata.getClassName()).getPackage().getName();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
basePackages = new String[] {basePackage};
}
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry, false);
TypeFilter helloServiceFilter = new AssignableTypeFilter(HelloService.class);
scanner.addIncludeFilter(helloServiceFilter);
scanner.scan(basePackages);
}
}
此时我们的HelloConfiguration可以定义为如下这样,它的效果和之前是一模一样的。
@Configuration
@HelloScan("com.elim.spring.core.importselector")
public class HelloConfiguration {
}
(注:本文是基于Spring 5.0.7所写)
相关推荐
SpringCloud——分布式配置中心(Spring Cloud Config)之高可用的分布式配置中心
SpringCloud——消息总线(Bus)之Spring Cloud Bus将分布式系统的节点与轻量级消息代理链接。
SpringCloud——断路器(Hystrix)之Ribbon使用断路器和Feign使用断路器
SpringCloud——分布式跟踪(Sleuth)之Spring Cloud Sleuth 主要功能就是在分布式系统中提供追踪解决方案。
Spring boot——@DeclareParents例子...
SpringCloud——服务注册(consul)之Consul通过HTTP API和DNS提供服务发现服务。
关于Spring方面的常见面试题
SpringCloud——路由器和过滤器(Zuul)之微服务网关的实现
Spring系列——MVC框架整合.md
MyBatis与Spring整合——通过官方文档进行最简单的整合
所有Spring——jar详细介绍 所有Spring——jar详细介绍 所有Spring——jar详细介绍
Spring总结——田超凡【原创田超凡,已申请版权,禁止随意转发,侵权仿冒必究】
Zookeeper作为注册中心搭建SpringCloud实现服务注册及发现
NULL 博文链接:https://ylxy3058.iteye.com/blog/2225314
我们从一个简单的容器开始,一步步的重构,最后实现一个基本的Spring框架的雏形,为了帮助我们更加深入的理解Spring的IoC...【SSH进阶之路】一步步重构容器实现Spring框架——彻底封装,实现简单灵活的Spring框架(十一)
SpringCloud-Eureka实现服务的注册与发现,创建服务注册中心(eureka-server)和服务提供者 (eureka-client)
SpringCloud —— Eureka 集群 SpringCloud —— 服务注册进 Eureka 集群 SpringCloud —— Eureka 自我保护 SpringCloud —— SpringCloud Consul 实现服务注册中心 SpringCloud —— 三个注册中心的异同点 ...
NULL 博文链接:https://snowolf.iteye.com/blog/236264
NULL 博文链接:https://ylxy3058.iteye.com/blog/2230763