Appuim环境搭建 tensorflow 开源商城系统 vue的钩子函数 vue标签 vue安装教程 找公司做网站 前端项目实战 java运行软件 mysql 导入数据 表白网页源码 python功能 python的random函数 python关键字 python自学 python等待10秒 java查找字符串 java学习基础 java中float java对象序列化 java创建目录 java文件读写 java中long java多线程编程 魔兽世界字体包 行业软件下载 按钮制作 万能低格工具 js倒计时代码 图解设计模式 js判断字符串相等 风火云 eml文件阅读器下载 复制到剪贴板 3d软件下载 spss22安装教程 medcalc 视频编辑专家下载 arm体系结构与编程 脚本编程
当前位置: 首页 > 学习教程  > 编程语言

【Spring】Spring是如何完成扫描的

2020/11/24 10:49:27 文章标签: 测试文章如有侵权请发送至邮箱809451989@qq.com投诉后文章立即删除

// 在创建Spring容器的时候,AnnotationConfigApplicationContext的构造方法中 // 分别创建了AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner public AnnotationConfigApplicationContext() {this.reader new AnnotatedBeanDefinitionReader(this)…

// 在创建Spring容器的时候,AnnotationConfigApplicationContext的构造方法中
// 分别创建了AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner
public AnnotationConfigApplicationContext() {
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

在AnnotatedBeanDefinitionReader的构造方法中调用了AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry),该方法的主要目的是为了创建5个Spring内部的BeanDefinition。

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		Assert.notNull(environment, "Environment must not be null");
		this.registry = registry;
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}

创建Spring内部BeanDefinition的过程
其中,目前需要关注的一个BeanDefinition是org.springframework.context.annotation.internalConfigurationAnnotationProcessor,这是一个BeanDefinitionRegistryPostProcessor类型的BeanDefinition。
Spring内部的个BeanDefinition
在ClassPathBeanDefinitionScanner的构造方法中,最主要的代码是registerDefaultFilters(),布尔值useDefaultFilters默认为true,所以默认情况下registerDefaultFilters方法一定执行。

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
			Environment environment, @Nullable ResourceLoader resourceLoader) {

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		this.registry = registry;

		if (useDefaultFilters) {
			registerDefaultFilters();
		}
		setEnvironment(environment);
		setResourceLoader(resourceLoader);
	}

registerDefaultFilters方法中需要我们关注的代码是
this.includeFilters.add(new AnnotationTypeFilter(Component.class)),这里的AnnotationTypeFilter继承自TypeFilter,用来指定扫描哪种类型的类或者过滤哪些类型的类,而这里指定的Component.class代表Spring将会扫描加了@Component或继承自Component的如@Service、@Configuration注解的类。mybatis的@MapperScan就是利用自定义的TypeFilter完成对mapper的扫描。

protected void registerDefaultFilters() {
		this.includeFilters.add(new AnnotationTypeFilter(Component.class));
		ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
		try {
			this.includeFilters.add(new AnnotationTypeFilter(
					((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
			logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
		}
		catch (ClassNotFoundException ex) {
			// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
		}
		try {
			this.includeFilters.add(new AnnotationTypeFilter(
					((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
			logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
		}
		catch (ClassNotFoundException ex) {
			// JSR-330 API not available - simply skip.
		}
	}

接下来遍历所有配置类,创建BeanDefinition并放入beanFactory的beanDefinitionMap中,至此容器中又多了一个BeanDefinition。
增加类一个BeanDefinition
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()方法中,会找BeanDefinitionRegistryPostProcessor类型的BeanDefinition,这里将会找到创建AnnotatedBeanDefinitionReader对象时放到beanDefinitionMap中的org.springframework.context.annotation.internalConfigurationAnnotationProcessor,接下来从beanFactory中找名字叫这个,类型是BeanDefinitionRegistryPostProcessor的Bean,此时是找不到的,而beanFactory的getBean方法在get不到Bean时是会实例化所需的Bean的,而他实例化的是ConfigurationClassPostProcessor。

// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}

在这里插入图片描述


本文链接: http://www.dtmao.cc/news_show_400359.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?