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

织梦php网站wordpress手机版app导航

织梦php网站,wordpress手机版app导航,网站icp备案时间,怎么利用网站开发app文章目录 目标重要的组件加载配置类启动解析组件定位配置类解析配置类 扫描过程总结 目标 这是我们使用注解方式启动spring容器的核心代码 AnnotationConfigApplicationContext applicationContext new AnnotationConfigApplicationContext(MyConfig.class); User user (Us… 文章目录 目标重要的组件加载配置类启动解析组件定位配置类解析配置类 扫描过程总结 目标 这是我们使用注解方式启动spring容器的核心代码 AnnotationConfigApplicationContext applicationContext new AnnotationConfigApplicationContext(MyConfig.class); User user (User) applicationContext.getBean(user); user.printName();其中配置类MyConfig的代码是 ComponentScan(value com.mydemo) public class MyConfig { }现在我们的目标是搞清楚spring是怎么解析这个配置类并且扫描该配置类包路径下的bean 重要的组件 AnnotatedBeanDefinitionReader spring容器启动的时候就会创建这个读取器主要是将类以BeanDefinition的方式保存到bean工厂DefaultListableBeanFactory 在创建这个读取器的时候spring会默认添加一个ConfigurationClassPostProcessor的BeanDefinition这个就是在解析配置类时的主要对象,在AnnotationConfigUtils类的registerAnnotationConfigProcessors中实现 if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); }ClassPathBeanDefinitionScanner 路径扫描器在spring启动的时候就会创建主要功能就是对类路径进行扫描内含一些扫描规则例如在创建时候就会内置一个Component注解的过滤器 protected void registerDefaultFilters() {this.includeFilters.add(new AnnotationTypeFilter(Component.class));... }加载配置类 我们的配置类是由AnnotatedBeanDefinitionReader类的doRegisterBean方法转成BeanDefinition存到bean工厂的beanDefinitionMap中基于ASM获取一个类信息转成BeanDefinition。 转成的核心代码 AnnotatedGenericBeanDefinition abd new AnnotatedGenericBeanDefinition(beanClass);得到配置类对象的AnnotatedGenericBeanDefinition后虽然还没有加载类但是已经获取到了类的注解信息。 虽然都是带有BeanDefinition但是保存到bean工厂的BeanDefinition和这个是不一样的这个AnnotatedGenericBeanDefinition主要是一些注解信息并没有类似于BeanDefinition的属性如是否懒加载作用域是否依赖等。 解析AnnotatedGenericBeanDefinition注解信息的主要代码主要就是读取Lazy、Primary 、DependsOn、Description设置成属性值 AnnotationAttributes lazy attributesFor(metadata, Lazy.class); if (lazy ! null) {abd.setLazyInit(lazy.getBoolean(value)); } else if (abd.getMetadata() ! metadata) {lazy attributesFor(abd.getMetadata(), Lazy.class);if (lazy ! null) {abd.setLazyInit(lazy.getBoolean(value));} }if (metadata.isAnnotated(Primary.class.getName())) {abd.setPrimary(true); } AnnotationAttributes dependsOn attributesFor(metadata, DependsOn.class); if (dependsOn ! null) {abd.setDependsOn(dependsOn.getStringArray(value)); }AnnotationAttributes role attributesFor(metadata, Role.class); if (role ! null) {abd.setRole(role.getNumber(value).intValue()); } AnnotationAttributes description attributesFor(metadata, Description.class); if (description ! null) {abd.setDescription(description.getString(value)); }解析AnnotatedGenericBeanDefinition后转成BeanDefinitionHolder才是我们要保存到bean工厂的BeanDefinition BeanDefinitionHolder definitionHolder new BeanDefinitionHolder(abd, beanName);如果配置类不是代理模式就直接保存BeanDefinition到bean工厂中了 如果是代理模式就创建一个新的RootBeanDefinition保存到bean工厂中主要实现的代码在ScopedProxyUtils类createScopedProxy方法中 启动解析组件 spring在启动配置类扫描的任务时是以启动一个BeanDefinitionRegistryPostProcessor的方式调用扫描类执行的属于一种组件化启动任务类的方式 for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {...postProcessor.postProcessBeanDefinitionRegistry(registry);... }这个组件的实现类是ConfigurationClassPostProcessor所以所有的扫描代码都在该类的postProcessBeanDefinitionRegistry方法下 定位配置类 在bean工厂的beanDefinitionMap中遍历每个元素来定位符合配置类的bd,规则校验在ConfigurationClassUtils类checkConfigurationClassCandidate方法中 主要是确定该bd是AnnotatedBeanDefinition类型如果beanDef不是AnnotatedBeanDefinition的实例则进一步检查它是否是AbstractBeanDefinition的实例并且已经有了对应的Class对象。如果是的话接着会检查这个Class是否实现了某些特定接口如BeanFactoryPostProcessor, BeanPostProcessor, AopInfrastructureBean, 或者EventListenerFactory。如果确实实现了这些接口中的一个或多个函数将返回false表示不需要继续解析。否则它将通过AnnotationMetadata.introspect(beanClass)方法来获取该类的注解元数据。如果以上两种情况都不满足代码将尝试通过MetadataReader从类路径中读取指定类名(className)的元数据。这通常涉及到加载类文件并从中提取信息。如果在这个过程中发生IO异常例如找不到类文件则记录错误信息并返回false。 解析配置类 解析的操作是ConfigurationClassParser来完成的所有解析的相关逻辑都在该类的processConfigurationClass方法中主要负责解析和注册配置类中的各种注解 处理PropertySource ComponentScan Import ImportResour Bean注解这里值分析 ComponentScan注解因为已经获取到了类的元信息所以就可以获取ComponentScan配置的路径进而进行路径扫描扫描是交由ComponentScanAnnotationParser组件执行的由ComponentScanAnnotationParser组件发起最终在ClassPathBeanDefinitionScanner类型的doScan来实现 扫描过程 SetBeanDefinition candidates findCandidateComponents(basePackage);通过调用findCandidateComponents方法根据提供的基础包名(basePackage)来查找该包及其子包下的所有符合组件扫描条件的类并将它们作为候选组件返回。每个候选组件都是一个BeanDefinition对象表示潜在的Spring bean 构建搜索路径: 构建一个资源模式路径用于指示ResourcePatternResolver在哪里查找资源。这个路径包括了类路径前缀、基础包名以及资源模式例如/**/*.class以便于匹配所有的类文件。 String packageSearchPath ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX resolveBasePackage(basePackage) / this.resourcePattern;获取资源 Resource[] resources getResourcePatternResolver().getResources(packageSearchPath);通过getResourcePatternResolver()获取资源解析器实例并调用其getResources方法来获取与给定模式匹配的所有资源。这里的资源是指符合路径模式的类文件。 初步筛选 遍历每个资源,使用MetadataReaderFactory为每个资源创建一个MetadataReader实例它能够读取类的元数据而无需加载该类到JVM中。 ScannedGenericBeanDefinition sbd new ScannedGenericBeanDefinition(metadataReader); sbd.setSource(resource);首先使用isCandidateComponent(metadataReader)方法初步判断资源是否可能是一个候选组件 AnnotationMetadata metadata beanDefinition.getMetadata(); return (metadata.isIndependent() (metadata.isConcrete() ||(metadata.isAbstract() metadata.hasAnnotatedMethods(Lookup.class.getName()))));类必须是独立的非内部类。同时类必须是具体的非接口或非抽象类或者如果是抽象类的话它必须包含至少一个用 Lookup 注解标记的方法。 确定是否创建为BeanDefinition ScopeMetadata scopeMetadata this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); String beanName this.beanNameGenerator.generateBeanName(candidate, this.registry);对于每个候选的BeanDefinition使用scopeMetadataResolver解析其作用域scope信息,同时为Bean生成或获取一个唯一的beanName if (candidate instanceof AbstractBeanDefinition) {postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); }如果候选Bean是一个AbstractBeanDefinition类型的实例则调用postProcessBeanDefinition方法进行额外的后处理比如应用默认值和自动装配规则 if (candidate instanceof AnnotatedBeanDefinition) {AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); }如果候选Bean是AnnotatedBeanDefinition类型那么将处理常见的注解如Lazy, Primary, DependsOn, Role, 和 Description等 if (checkCandidate(beanName, candidate)) {BeanDefinitionHolder definitionHolder new BeanDefinitionHolder(candidate, beanName);definitionHolder AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);beanDefinitions.add(definitionHolder);registerBeanDefinition(definitionHolder, this.registry); }检查当前候选Bean是否可以被注册到容器中如果可以继续执行以下操作: 创建一个BeanDefinitionHolder对象该对象持有Bean定义、Bean名称以及其他元数据, 如果需要使用applyScopedProxyMode根据作用域代理模式来创建作用域代理 将处理后的BeanDefinitionHolder添加到beanDefinitions列表并注册到registry中。 在checkCandidate中还有一个方法 protected boolean isCompatible(BeanDefinition newDef, BeanDefinition existingDef) {return (!(existingDef instanceof ScannedGenericBeanDefinition) || // explicitly registered overriding bean(newDef.getSource() ! null newDef.getSource().equals(existingDef.getSource())) || // scanned same file twicenewDef.equals(existingDef)); // scanned equivalent class twice } 检查新的Bean定义是否与已存在的Bean定义兼容避免重复扫描同一个文件或者类而引起的冲突。 总结 配置类加载使用AnnotatedBeanDefinitionReader将配置类转换为BeanDefinition并通过ASM库获取类信息。启动解析组件通过实现BeanDefinitionRegistryPostProcessor接口的ConfigurationClassPostProcessor组件来启动配置类的解析任务。定位与解析配置类遍历bean工厂中的所有BeanDefinition以定位配置类并使用ConfigurationClassParser处理配置类上的各种注解如ComponentScan。组件扫描ClassPathBeanDefinitionScanner根据指定的基础包名查找符合组件扫描条件的类进行初步筛选后创建BeanDefinition对象最终注册到Spring容器中。
http://www.hkea.cn/news/14464240/

相关文章:

  • 用kid做教育网站域名百度账号注册
  • 广州商城建站苏州大学网站建设
  • 网站仿做利用云服务器做网站
  • 简述网站的建设流程图做电商网站就业岗位晋升
  • 沧州市网站建设公司亚马逊海外购
  • 如何建立网站做微商低价网站建设多少钱
  • 自己怎么来建设网站seo推广小分享
  • 哈德网站建设建筑工程网格化管理考核管理办法
  • 西昌新站seo写作网站可以签约未成年吗
  • 做影视网站赚钱wordpress页面不能访问
  • 阜阳讯拓网站建设开发一个软件能赚多少钱
  • 目前流行的网站开发设计大型网站建设企业名录模板
  • 简洁大气蓝色文章资讯网站网站建设外包公司怎么样
  • 哈尔滨门户网站制作哪家好网站的标题可以改吗
  • 网站建设高端网页设计曹县商城网站建设
  • 百度地图手机网站代码wordpress支付插件安全
  • 绿植网站怎么做做网站需要多少
  • 海口网站建设策划方案什么是网站建设需求
  • 企业网站托管关于百度网站的优缺点
  • 家居网站建设平台莲花网站
  • 网站前台后台模板营销策划公司加盟
  • 深圳专业网站开发公司缔烨建设公司网站
  • 电子商务网站建设期末试题答案05wordpress 登陆 443
  • 做外贸需要什么样的网站海南建设网网站
  • 电子商务网站开发实务石道元百度推广计划
  • 美工素材网站口碑营销
  • 杭州有做网站好的app开发公司
  • 快速建站官网自己怎么建立自己的国际网站
  • 网站设计的总结wordpress foot增加js
  • 漫画网站建设威海外贸网站建设联系方式