Spring 通过@Import实现Bean的注册
今天看到一个神奇的用法, Spring可以通过@Import导入实现了ImportBeanDefinitionRegistrar接口的类来注册那个类.
ImportBeanDefinitionRegistrar接口是用来被实现以使Spring在处理Configuration的时候注册额外的bean. @Import注解可以引入一个Configuration类, 或ImportSelector实现类以根据特定条件导入合适的类. 其次就是可以引入实现了ImportBeanDefinitionRegistrar接口的类来直接注册类.
当然, 除了ImportBeanDefinitionRegistrar实现类, 还可以使用ClassPathBeanDefinitionScanner这个扫描器, 获取需要注册的bean. ClassPathBeanDefinitionScanner继承了ClassPathScanningCandidateComponentProvider, 其中有两个TypeFilter, includeFilters和excludeFilters, 可以用来过滤类.
比如以下即实现了ImportBeanDefinitionRegistrar接口:
class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware {
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
this.registerDefaultConfiguration(metadata, registry);
this.registerFeignClients(metadata, registry);
}
}
在registerFeignClients使用ClassPathScanningCandidateComponentProvider来过滤类, 注入包含了@FeignClient注解的类.
public void registerFeignClients(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
ClassPathScanningCandidateComponentProvider scanner = this.getScanner();
scanner.setResourceLoader(this.resourceLoader);
Map<String, Object> attrs = metadata.getAnnotationAttributes(EnableFeignClients.class.getName());
AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(FeignClient.class);
Class<?>[] clients = attrs == null ? null : (Class[])((Class[])attrs.get("clients"));
Object basePackages;
if (clients != null && clients.length != 0) {
final Set<String> clientClasses = new HashSet();
basePackages = new HashSet();
Class[] var9 = clients;
int var10 = clients.length;
for(int var11 = 0; var11 < var10; ++var11) {
Class<?> clazz = var9[var11];
((Set)basePackages).add(ClassUtils.getPackageName(clazz));
clientClasses.add(clazz.getCanonicalName());
}
AbstractClassTestingTypeFilter filter = new AbstractClassTestingTypeFilter() {
protected boolean match(ClassMetadata metadata) {
String cleaned = metadata.getClassName().replaceAll("\\$", ".");
return clientClasses.contains(cleaned);
}
};
scanner.addIncludeFilter(new FeignClientsRegistrar.AllTypeFilter(Arrays.asList(filter, annotationTypeFilter)));
} else {
scanner.addIncludeFilter(annotationTypeFilter);
basePackages = this.getBasePackages(metadata);
}
Iterator var17 = ((Set)basePackages).iterator();
while(var17.hasNext()) {
String basePackage = (String)var17.next();
Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents(basePackage);
Iterator var21 = candidateComponents.iterator();
while(var21.hasNext()) {
BeanDefinition candidateComponent = (BeanDefinition)var21.next();
if (candidateComponent instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition)candidateComponent;
AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
Assert.isTrue(annotationMetadata.isInterface(), "@FeignClient can only be specified on an interface");
Map<String, Object> attributes = annotationMetadata.getAnnotationAttributes(FeignClient.class.getCanonicalName());
String name = this.getClientName(attributes);
this.registerClientConfiguration(registry, name, attributes.get("configuration"));
this.registerFeignClient(registry, annotationMetadata, attributes);
}
}
}
}
Spring 通过@Import实现Bean的注册的更多相关文章
- 品Spring:SpringBoot发起bean定义注册的“二次攻坚战”
上一篇文章整体非常轻松,因为在容器启动前,只注册了一个bean定义,就是SpringBoot的主类. OK,今天接着从容器的启动入手,找出剩余所有的bean定义的注册过程. 具体细节肯定会颇为复杂,同 ...
- Spring Boot 使用Java代码创建Bean并注册到Spring中
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/catoop/article/details/50558333 声明同一个类下的多个实例: packa ...
- (41)Spring Boot 使用Java代码创建Bean并注册到Spring中【从零开始学Spring Boot】
已经好久没有讲一些基础的知识了,这一小节来点简单的,这也是为下节的在Spring Boot中使用多数据源做准备. 从Spring 3.0开始,增加了一种新的途径来配置Bean Definition,这 ...
- 品Spring:负责bean定义注册的两个“排头兵”
别看Spring现在玩的这么花,其实它的“筹码”就两个,“容器”和“bean定义”. 只有先把bean定义注册到容器里,后续的一切可能才有可能成为可能. 所以在进阶的路上如果要想走的顺畅些,彻底搞清楚 ...
- Spring源码-IOC部分-自定义IOC容器及Bean解析注册【4】
实验环境:spring-framework-5.0.2.jdk8.gradle4.3.1 Spring源码-IOC部分-容器简介[1] Spring源码-IOC部分-容器初始化过程[2] Spring ...
- Spring IOC(三)单例 bean 的注册管理
Spring IOC(三)单例 bean 的注册管理 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) 在 Spring 中 ...
- spring概念简介、bean扫描与注册实现方式
写在前面:本文作为整理,包含很多个人理解,有跳跃成份,初学者如果看晕了,可以先看其它同类文章,或者……多看几遍. 一.概念部分: 1.spring概念:网上有很多 2.spring核心:IOC(DI) ...
- 品Spring:SpringBoot轻松取胜bean定义注册的“第一阶段”
上一篇文章强调了bean定义注册占Spring应用的半壁江山.而且详细介绍了两个重量级的注册bean定义的类. 今天就以SpringBoot为例,来看看整个SpringBoot应用的bean定义是如何 ...
- Spring(五)核心容器 - 注册 Bean、BeanDefinitionRegistry 简介
目录 前言 正文 1.BeanDefinitionRegistry 简介 2.registerBeanDefinition 方法注册 Bean 最后 前言 上篇文章我们对 BeanDefinition ...
随机推荐
- LeetCode 953. Verifying an Alien Dictionary
原题链接在这里:https://leetcode.com/problems/verifying-an-alien-dictionary/ 题目: In an alien language, surpr ...
- [RN] React Native 使用开源库 react-native-image-crop-picker 实现图片选择、图片剪裁
React Native 使用开源库 react-native-image-crop-picker 实现图片选择.图片剪裁 该库可以实现启动本地相册和照相机来采集图片,并且提供多选.图片裁剪等功能,支 ...
- 假设检验总结以及如何用python进行假设检验(scipy)
几种常见的假设检验总结如下: 假设检验名称 Z检验 t检验 χ2检验 F检验 原假设 H0: μ≥μ0 H0: μ≤μ0 H0: μ=μ0 (比较样本和总体均值) ...
- 【Wannafly挑战赛24E】旅行
[Wannafly挑战赛24E]旅行 题面 牛客 题解 首先有一个非常显然的\(dp\):我们直接把\(s\rightarrow t\)的路径抠出来然后设\(f_{i,j}\)表示到第\(i\)个点, ...
- mysql(四)缓存
参考文档: http://www.cnblogs.com/zemliu/archive/2013/08/03/3234372.html
- Spring中@Bean与@Configuration
一.Spring中Bean及@Bean的理解[1] Bean在Spring和SpringMVC中无所不在,将这个概念内化很重要,下面分享一下我的想法: 一.Bean是啥 1.Java面向对象,对象有方 ...
- Spark2.x(六十二):(Spark2.4)共享变量 - Broadcast原理分析
之前对Broadcast有分析,但是不够深入<Spark2.3(四十三):Spark Broadcast总结>,本章对其实现过程以及原理进行分析. 带着以下几个问题去写本篇文章: 1)dr ...
- Java NIO 文件通道使用
读取一个文件的内容,然后写入另外一个文件 public class NioTest4 { public static void main(String[] args) throws Exception ...
- APISIX系列 | 使用 docker-apisix 安装APISIX服务
官方仓库:https://github.com/iresty/docker-apisix 官方仓库 拉取 git clone git@github.com:iresty/docker-apisix.g ...
- Vscode 修改主题颜色
首先向大家演示如何使用VSCode自带的颜色主题:依次点击左上角的文件-首选项-颜色主题,出现如下的主题选取界面.