当前位置: 首页 > news >正文

科技信息网站系统建设方案陕西seo公司

科技信息网站系统建设方案,陕西seo公司,服务器做的网站 怎么使用,怎样进入公众号平台登录本文主要讲述Spring是如何解析“context:component-scan”元素&#xff0c;扫描加载目录下的BeanDefinition。 解析内容 1、解析的元素如下&#xff1a; <!-- 注解模式&#xff1a;配置bean扫描路径&#xff08;注&#xff1a;自动包含子路径&#xff09; --><conte…

本文主要讲述Spring是如何解析“context:component-scan”元素,扫描加载目录下的BeanDefinition。

解析内容

1、解析的元素如下:

	<!-- 注解模式:配置bean扫描路径(注:自动包含子路径) --><context:component-scan base-package="com.learnsf.main,com.learnsf.service"/>

注:该元素解析过程中,会自动处理“context:annotation-config/”元素要解析的内容。
2、只扫描加载目录下的BeanDefinition,不对注解进行解析。在AbstractApplicationContext.invokeBeanFactoryPostProcessors统一解析。

解析

ComponentScanBeanDefinitionParser.parse(Element element, ParserContext parserContext)

解析元素“context:component-scan”。

	@Override@Nullablepublic BeanDefinition parse(Element element, ParserContext parserContext) {// 获取属性“base-package”(多个包路径)String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);// 对包路径中占位符进行替换处理basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);// 分解成包数组String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);// 生成BeanDefinition扫描器ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);// 扫描生成beanDefinitionSet<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);// 注册BeanDefinitionregisterComponents(parserContext.getReaderContext(), beanDefinitions, element);return null;}

ClassPathBeanDefinitionScanner.doScan(String… basePackages)

在包里扫描BeanDefinition。

	protected Set<BeanDefinitionHolder> doScan(String... basePackages) {Assert.notEmpty(basePackages, "At least one base package must be specified");Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();// 每个包进行扫描for (String basePackage : basePackages) {// 获取候选BeanDefinitionSet<BeanDefinition> candidates = findCandidateComponents(basePackage);// 每个侯选者处理for (BeanDefinition candidate : candidates) {// 解析Bean作用域ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);candidate.setScope(scopeMetadata.getScopeName());// 生成beanName String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);if (candidate instanceof AbstractBeanDefinition abstractBeanDefinition) {// 对 AbstractBeanDefinition类型的BeanDefinition 进一步处理:赋值BeanDefinition属性默认值,并设置 autowireCandidate 属性postProcessBeanDefinition(abstractBeanDefinition, beanName);}if (candidate instanceof AnnotatedBeanDefinition annotatedBeanDefinition) {// 对 AnnotatedBeanDefinition 类型的 BeanDefinition 进一步处理:对通用注解的解析处理,通用注解包括 @Lazy、@Primary、@DependsOn、@Role、@Description。例如:如果当前类被@Lazy修饰,则会获取@Lazy 的value 值并保存到 BeanDefinition#lazyInit 属性中。AnnotationConfigUtils.processCommonDefinitionAnnotations(annotatedBeanDefinition);}// 检查给定候选bean的beanName,确定相应的bean定义是否需要注册或与现有定义冲突if (checkCandidate(beanName, candidate)) {// 封装候选BeanDefinition为BeanDefinitionHolder BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);// 对 BeanDefinitionHolder 填充代理信息definitionHolder =AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);// 加入到返回集合beanDefinitions.add(definitionHolder);// 注册BeanDefinitionHolder 到bean工厂容器中registerBeanDefinition(definitionHolder, this.registry);}}}return beanDefinitions;}

ClassPathScanningCandidateComponentProvider.findCandidateComponents(String basePackage)

ClassPathScanningCandidateComponentProvider是ClassPathBeanDefinitionScanner父类。
获取注解的Bean的BeanDefinition。

	public Set<BeanDefinition> findCandidateComponents(String basePackage) {if (this.componentsIndex != null && indexSupportsIncludeFilters()) {// @Indexed 注解的处理 注1return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);}else {// 非@Indexed 注解的处理return scanCandidateComponents(basePackage);}}

注1:@Indexed注解Spring在5.0版本引入的,主要解决启动时注解模式解析太长的问题。处理方式是在项目编译打包时,会自动生成META-INF/spring.components文件,文件包含被@Indexed注释的类的模式解析结果。当Spring应用上下文进行组件扫描时,META-INF/spring.components会被org.springframework.context.index.CandidateComponentsIndexLoader读取并加载,转换为CandidateComponentsIndex对象,此时组件扫描会读取CandidateComponentsIndex,而不进行实际扫描,从而提高组件扫描效率,减少应用启动时间。如果使用该功能,需要引入如下依赖:

<dependency><groupId>org.springframework</groupId><artifactId>spring-context-indexer</artifactId><version>${spring.version}</version><optional>true</optional>
</dependency>

ClassPathScanningCandidateComponentProvider.scanCandidateComponents(String basePackage)

该方法是从指定的包路径获取到字节码文件,筛选出可能注入到Spring容器的Bean生成对应的ScannedGenericBeanDefinition

	private Set<BeanDefinition> scanCandidateComponents(String basePackage) {Set<BeanDefinition> candidates = new LinkedHashSet<>();try {// // 形成完整包路径String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +resolveBasePackage(basePackage) + '/' + this.resourcePattern;// 扫描路径下的资源(字节码文件)Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);boolean traceEnabled = logger.isTraceEnabled();boolean debugEnabled = logger.isDebugEnabled();// 遍历所有资源(字节码文件),挑选有注解的字节码文件生成BeanDefinitionfor (Resource resource : resources) {String filename = resource.getFilename();if (filename != null && filename.contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {// Ignore CGLIB-generated classes in the classpathcontinue;}if (traceEnabled) {logger.trace("Scanning " + resource);}try {// 获得资源的MetadataReader(包含文件信息和对应类注解信息)MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);// 校验是否是候选组件,条件是:包含在include-filters(扫描时需要实例化的类,默认都包含)且 @Conditional注解中不跳过的类(默认都不跳过)if (isCandidateComponent(metadataReader)) {ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);sbd.setSource(resource);// 校验是否是候选组件:bean是独立且具体的类 或者 是抽象类但被@Lookup注解修饰if (isCandidateComponent(sbd)) {if (debugEnabled) {logger.debug("Identified candidate component class: " + resource);}// 加入返回的候选组件集candidates.add(sbd);}else {if (debugEnabled) {logger.debug("Ignored because not a concrete top-level class: " + resource);}}}else {if (traceEnabled) {logger.trace("Ignored because not matching any filter: " + resource);}}}catch (FileNotFoundException ex) {if (traceEnabled) {logger.trace("Ignored non-readable " + resource + ": " + ex.getMessage());}}catch (Throwable ex) {throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, ex);}}}catch (IOException ex) {throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);}return candidates;}

ComponentScanBeanDefinitionParser.registerComponents( XmlReaderContext readerContext, Set beanDefinitions, Element element)

	protected void registerComponents(XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) {Object source = readerContext.extractSource(element);// 构建CompositeComponentDefinitionCompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);// 将所有BeanDefinition添加到compositeDef的nestedComponents属性中for (BeanDefinitionHolder beanDefHolder : beanDefinitions) {compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder));}// Register annotation config processors, if necessary.// 处理“annotation-config”:假定annotation-config是存在,这意味着配置了“context:component-scan”,则不需要再配置“context:annotation-config”boolean annotationConfig = true;if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) {// 获取component-scan标签的annotation-config属性值(默认为true)annotationConfig = Boolean.parseBoolean(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE));}if (annotationConfig) {// 获取所有处理注解类的BeanPostProcessors(BeanPostProcessor本身也是bean)Set<BeanDefinitionHolder> processorDefinitions =AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);// 将所有BeanPostProcessors的BeanDefinition添加到compositeDef的nestedComponents属性中for (BeanDefinitionHolder processorDefinition : processorDefinitions) {compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));}}// 触发组件注册事件readerContext.fireComponentRegistered(compositeDef);}
http://www.dinnco.com/news/27570.html

相关文章:

  • 网站建设技术选择百度指数查询官方网
  • 咸鱼网站做链接2022年最新十条新闻
  • 建设网站前准备资料西安关键词排名优化
  • 单页面网站怎么做游戏推广平台有哪些
  • 锦州市城市建设服务中心网站河南网站推广公司
  • 华为网站建站电商怎么做新手入门
  • 具有品牌的网站建设企业推广托管
  • 吴中区建设局网站google搜索引擎入口网址
  • 吉林科技网站建设搜一搜站长工具
  • 房管局 网站做房查网站建设公司业务
  • 做今日头条的网站自己如何建立网站
  • 建商城网站需要什么条件今日新闻大事件
  • 许昌建网站南昌seo报价
  • 不用编程做APP和响应式网站游戏推广合作平台
  • 用wordpress制作网站模板下载百度在线客服人工服务
  • 自营店网站建设站长工具关键词查询
  • 做网站用c 还是php网络推广工作好吗
  • 天津建设工程造价信息网郑州网站优化哪家好
  • 专业英文网站建设营销型网站建设公司价格
  • 做网站有什么必要免费注册
  • 网站设计的优点2021最新免费的推广引流软件
  • 网站怎么做英文版的模板之家官网
  • 开发一款视频app多少钱关键词优化是什么工作
  • 洛阳市住房和城乡建设网站网络销售平台排名前十
  • 东莞的网站建设公司百度关键词热度排名
  • 深圳最好的网站建设上海抖音推广
  • 滁州网站开发公司黄页推广引流
  • 家用100mb光纤做网站网站推广计划方法
  • 17网站一起做网店图片工具推广获客
  • 提供哈尔滨网站建设服务百度网站首页入口