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

货架网站开发wordpress 汽车租赁

货架网站开发,wordpress 汽车租赁,服装鞋帽 网站建设,Wordpress会员插件出错点击上方“匠心零度”#xff0c;选择“设为星标”做积极的人#xff0c;而不是积极废人来源#xff1a;my.oschina.net/floor/blog/4325651前言1.Component解析流程找入口找核心方法概要分析2.查文档找思路3. 探寻Component派生性流程1. 确定metadataReader2.查看match方法… 点击上方“匠心零度”选择“设为星标”做积极的人而不是积极废人来源my.oschina.net/floor/blog/4325651前言1.Component解析流程找入口找核心方法概要分析2.查文档找思路3. 探寻Component派生性流程1. 确定metadataReader2.查看match方法找重点方法逐步分析总结前言Component和Service都是工作中常用的注解Spring如何解析1.Component解析流程找入口Spring Framework2.0开始引入可扩展的XML编程机制该机制要求XML Schema命名空间需要与Handler建立映射关系。该关系配置在相对于classpath下的/META-INF/spring.handlers中。如上图所示 ContextNamespaceHandler对应context:... 分析的入口。找核心方法浏览ContextNamespaceHandler在parse中有一个很重要的注释// Actually scan for bean definitions and register them.ClassPathBeanDefinitionScanner scanner configureScanner(parserContext, element);大意是ClassPathBeanDefinitionScanner#doScan是扫描BeanDefinition并注册的实现 。ClassPathBeanDefinitionScanner 的源码如下protected Set doScan(String... basePackages) {   Assert.notEmpty(basePackages, At least one base package must be specified);   Set beanDefinitions  new LinkedHashSet();for (String basePackage : basePackages) {//findCandidateComponents 读资源装换为BeanDefinition      Set candidates  findCandidateComponents(basePackage);for (BeanDefinition candidate : candidates) {         ScopeMetadata scopeMetadata  this.scopeMetadataResolver.resolveScopeMetadata(candidate);         candidate.setScope(scopeMetadata.getScopeName());         String beanName  this.beanNameGenerator.generateBeanName(candidate, this.registry);if (candidate instanceof AbstractBeanDefinition) {            postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);         }if (candidate instanceof AnnotatedBeanDefinition) {            AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);         }if (checkCandidate(beanName, candidate)) {            BeanDefinitionHolder definitionHolder  new BeanDefinitionHolder(candidate, beanName);            definitionHolder                   AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);            beanDefinitions.add(definitionHolder);            registerBeanDefinition(definitionHolder, this.registry);         }      }   }return beanDefinitions;}上边的代码从方法名猜测findCandidateComponents从classPath扫描组件并转换为备选BeanDefinition也就是要做的解析Component的核心方法。概要分析findCandidateComponents在其父类ClassPathScanningCandidateComponentProvider 中。public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware {//省略其他代码public Set findCandidateComponents(String basePackage) {   if (this.componentsIndex ! null  indexSupportsIncludeFilters()) {      return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);   }   else {      return scanCandidateComponents(basePackage);   }}private Set scanCandidateComponents(String basePackage) {   Set candidates  new LinkedHashSet();try {      String packageSearchPath  ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX             resolveBasePackage(basePackage)  /  this.resourcePattern;      Resource[] resources  getResourcePatternResolver().getResources(packageSearchPath);//省略部分代码for (Resource resource : resources) {//省略部分代码if (resource.isReadable()) {try {               MetadataReader metadataReader  getMetadataReaderFactory().getMetadataReader(resource);if (isCandidateComponent(metadataReader)) {                  ScannedGenericBeanDefinition sbd  new ScannedGenericBeanDefinition(metadataReader);                  sbd.setSource(resource);if (isCandidateComponent(sbd)) {                     candidates.add(sbd);//省略部分代码      }   }catch (IOException ex) {//省略部分代码 }return candidates;}}findCandidateComponents大体思路如下String packageSearchPath ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX resolveBasePackage(basePackage) / this.resourcePattern;                            将package转化为ClassLoader类资源搜索路径packageSearchPath例如com.wl.spring.boot转化为classpath*:com/wl/spring/boot/**/*.classResource[] resources getResourcePatternResolver().getResources(packageSearchPath); 加载搜素路径下的资源。isCandidateComponent 判断是否是备选组件candidates.add(sbd); 添加到返回结果的listClassPathScanningCandidateComponentProvider#isCandidateComponent其源码如下protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {    //省略部分代码   for (TypeFilter tf : this.includeFilters) {      if (tf.match(metadataReader, getMetadataReaderFactory())) {         return isConditionMatch(metadataReader);      }   }   return false;}includeFilters由registerDefaultFilters()设置初始值有Component没有Service啊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.   }}Spring如何处理Service的注解的呢2.查文档找思路查阅官方文档下面这话https://docs.spring.io/spring/docs/5.0.17.RELEASE/spring-framework-reference/core.html#beans-meta-annotationsComponent is a generic stereotype for any Spring-managed component. Repository, Service, and Controller are specializations of Component大意如下Component是任何Spring管理的组件的通用原型。Repository、Service和Controller是派生自Component。Target({ElementType.TYPE})Retention(RetentionPolicy.RUNTIME)Documented// Service 派生自ComponentComponentpublic interface Service {   /**    * The value may indicate a suggestion for a logical component name,    * to be turned into a Spring bean in case of an autodetected component.    * return the suggested component name, if any (or empty String otherwise)    */   AliasFor(annotation  Component.class)   String value() default ;}Component是Service的元注解Spring 大概率在读取Service也读取了它的元注解并将Service作为Component处理。3. 探寻Component派生性流程回顾ClassPathScanningCandidateComponentProvider 中的关键的代码片段如下private Set scanCandidateComponents(String basePackage) { //省略其他代码 MetadataReader metadataReader             getMetadataReaderFactory().getMetadataReader(resource);   if(isCandidateComponent(metadataReader)){       //....   }}public final MetadataReaderFactory getMetadataReaderFactory() {   if (this.metadataReaderFactory  null) {      this.metadataReaderFactory  new CachingMetadataReaderFactory();   }   return this.metadataReaderFactory;}1. 确定metadataReaderCachingMetadataReaderFactory继承自 SimpleMetadataReaderFactory就是对SimpleMetadataReaderFactory加了一层缓存。其内部的SimpleMetadataReaderFactory#getMetadataReader 为public class SimpleMetadataReaderFactory implements MetadataReaderFactory {    Overridepublic MetadataReader getMetadataReader(Resource resource) throws IOException {   return new SimpleMetadataReader(resource, this.resourceLoader.getClassLoader());}    }这里可以看出MetadataReader metadataReader new SimpleMetadataReader(...);2.查看match方法找重点方法AnnotationTypeFilter#matchself方法如下Overrideprotected boolean matchSelf(MetadataReader metadataReader) {   AnnotationMetadata metadata  metadataReader.getAnnotationMetadata();   return metadata.hasAnnotation(this.annotationType.getName()) ||         (this.considerMetaAnnotations  metadata.hasMetaAnnotation(this.annotationType.getName()));}是metadata.hasMetaAnnotation法从名称看是处理元注解我们重点关注逐步分析找metadata.hasMetaAnnotationmetadatametadataReader.getAnnotationMetadata();metadataReader new SimpleMetadataReader(...)metadata new SimpleMetadataReader#getAnnotationMetadata()//SimpleMetadataReader 的构造方法SimpleMetadataReader(Resource resource, Nullable ClassLoader classLoader) throws IOException {   InputStream is  new BufferedInputStream(resource.getInputStream());   ClassReader classReader;   try {      classReader  new ClassReader(is);   }   catch (IllegalArgumentException ex) {      throw new NestedIOException(ASM ClassReader failed to parse class file -              probably due to a new Java class file version that isnt supported yet:   resource, ex);   }   finally {      is.close();   }   AnnotationMetadataReadingVisitor visitor             new AnnotationMetadataReadingVisitor(classLoader);   classReader.accept(visitor, ClassReader.SKIP_DEBUG);   this.annotationMetadata  visitor;   // (since AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor)   this.classMetadata  visitor;   this.resource  resource;}metadatanew SimpleMetadataReader(...)**.**getAnnotationMetadata() new AnnotationMetadataReadingVisitor(。。)也就是说metadata.hasMetaAnnotationAnnotationMetadataReadingVisitor#hasMetaAnnotation其方法如下public class AnnotationMetadataReadingVisitor{    // 省略部分代码Overridepublic boolean hasMetaAnnotation(String metaAnnotationType) {   Collection allMetaTypes  this.metaAnnotationMap.values();for (Set metaTypes : allMetaTypes) {if (metaTypes.contains(metaAnnotationType)) {return true;      }   }return false;}}逻辑很简单就是判断该注解的元注解在在不在metaAnnotationMap中如果在就返回true。这里面核心就是metaAnnotationMap搜索AnnotationMetadataReadingVisitor类没有发现赋值的地方。查找metaAnnotationMap赋值回到SimpleMetadataReader 的方法//这个accept方法很可疑在赋值之前执行SimpleMetadataReader(Resource resource, Nullable ClassLoader classLoader) throws IOException {//省略其他代码AnnotationMetadataReadingVisitor visitor  new AnnotationMetadataReadingVisitor(classLoader);classReader.accept(visitor, ClassReader.SKIP_DEBUG); this.annotationMetadata  visitor; }发现一个可疑的语句classReader.accept。查看accept方法public class ClassReader {        //省略其他代码public void accept(..省略代码){    //省略其他代码    readElementValues(    classVisitor.visitAnnotation(annotationDescriptor, /* visible  */ true),    currentAnnotationOffset,     true,    charBuffer);}}查看readElementValues方法public class ClassReader{    //省略其他代码private int readElementValues(final AnnotationVisitor annotationVisitor,final int annotationOffset,final boolean named,final char[] charBuffer) {  int currentOffset  annotationOffset;  // Read the num_element_value_pairs field (or num_values field for an array_value).  int numElementValuePairs  readUnsignedShort(currentOffset);  currentOffset  2;  if (named) {    // Parse the element_value_pairs array.    while (numElementValuePairs--  0) {      String elementName  readUTF8(currentOffset, charBuffer);      currentOffset           readElementValue(annotationVisitor, currentOffset  2, elementName, charBuffer);    }  } else {    // Parse the array_value array.    while (numElementValuePairs--  0) {      currentOffset           readElementValue(annotationVisitor, currentOffset, /* named  */ null, charBuffer);    }  }  if (annotationVisitor ! null) {    annotationVisitor.visitEnd();  }  return currentOffset;}}这里面的核心就是 annotationVisitor.visitEnd();确定annotationVisitor这里的annotationVisitorAnnotationMetadataReadingVisitor#visitAnnotation源码如下注意这里传递了metaAnnotationMappublic class AnnotationMetadataReadingVisitor{Overridepublic AnnotationVisitor visitAnnotation(String desc, boolean visible) {   String className  Type.getType(desc).getClassName();   this.annotationSet.add(className);   return new AnnotationAttributesReadingVisitor(         className, this.attributesMap,              this.metaAnnotationMap, this.classLoader);}}annotationVisitorAnnotationAttributesReadingVisitor查阅annotationVisitor.visitEnd()annotationVisitorAnnotationAttributesReadingVisitor#visitEnd()public class AnnotationAttributesReadingVisitor{Overridepublic void visitEnd() {   super.visitEnd();   Class extends Annotation annotationClass  this.attributes.annotationType();   if (annotationClass ! null) {      List attributeList  this.attributesMap.get(this.annotationType);if (attributeList  null) {this.attributesMap.add(this.annotationType, this.attributes);      }else {         attributeList.add(0, this.attributes);      }if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotationClass.getName())) {try {            Annotation[] metaAnnotations  annotationClass.getAnnotations();if (!ObjectUtils.isEmpty(metaAnnotations)) {               Set visited  new LinkedHashSet();for (Annotation metaAnnotation : metaAnnotations) {                  recursivelyCollectMetaAnnotations(visited, metaAnnotation);               }if (!visited.isEmpty()) {                  Set metaAnnotationTypeNames  new LinkedHashSet(visited.size());for (Annotation ann : visited) {                     metaAnnotationTypeNames.add(ann.annotationType().getName());                  }this.metaAnnotationMap.put(annotationClass.getName(), metaAnnotationTypeNames);               }            }         }catch (Throwable ex) {if (logger.isDebugEnabled()) {               logger.debug(Failed to introspect meta-annotations on   annotationClass  :   ex);            }         }      }   }}}内部方法recursivelyCollectMetaAnnotations 递归的读取注解与注解的元注解(读Service再读元注解Component)并设置到metaAnnotationMap也就是AnnotationMetadataReadingVisitor 中的metaAnnotationMap中。总结大致如下ClassPathScanningCandidateComponentProvider#findCandidateComponents1、将package转化为ClassLoader类资源搜索路径packageSearchPath2、加载搜素路径下的资源。3、isCandidateComponent 判断是否是备选组件。内部调用的TypeFilter的match方法AnnotationTypeFilter#matchself中metadata.hasMetaAnnotation处理元注解metadata.hasMetaAnnotationAnnotationMetadataReadingVisitor#hasMetaAnnotation就是判断当前注解的元注解在不在metaAnnotationMap中。AnnotationAttributesReadingVisitor#visitEnd()内部方法recursivelyCollectMetaAnnotations 递归的读取注解与注解的元注解(读Service再读元注解Component)并设置到metaAnnotationMap4、添加到返回结果的listEND如果读完觉得有收获的话欢迎点【好看】关注【匠心零度】查阅更多精彩历史让我“好看”
http://www.zqtcl.cn/news/498586/

相关文章:

  • 网站后台文章添加成功 不显示公司设计网站建设合同
  • 后端开发需要掌握哪些知识潍坊优化公司
  • 专业手机网站制作哪家好wordpress wp-polls
  • 网站建设前分析网页制作素材按钮
  • 做视频网站怎么对接云盘松江新城网站建设
  • 温州阿里巴巴网站建设企业宣传片怎么拍
  • 淮阳住房城乡建设局网站阿里巴巴做国际网站要多少钱
  • 电子商务个人网站可以备案吗短网址还原
  • 网站内容由什么组成部分组成部分电子商务网站建设主管的策划书
  • 云服务器安装win系统做网站seo三人行论坛
  • 电气网站设计机械设计软件solidworks
  • 内网网站建设所需硬件设备厦门关键词排名提升
  • 网站动态海报效果怎么做的最专业网站建
  • 学校如何建设网站北京市住房及城乡建设部网站
  • 响应式网站制作流程全国城建培训中心官网查询证书
  • 北京工程建设信息网站中国市场网
  • xml做网站源码免费网站是
  • 中国工商建设标准化协会网站织梦app网站模板
  • 怎么做好网络销售文大侠seo博客
  • wish网站应该怎么做网站建设前规划
  • 网站建设目的是什么建筑机械人才培训网官网
  • 建筑建设行业网站大型购物网站开发
  • 手机网站开发用什么设计之家网
  • 网站开发平台有哪些什么是网络开发
  • 学校网站前置审批网站做哪些比较有意思
  • 怎么给企业做网站学计算机网站建设
  • 网站关键词优化排名技巧aiyuan wordpress
  • 建设工程资质证书二维码扫描网站自己做的网站如何让qq登录
  • 网站域名有效期wordpress 特别慢
  • 建立个人网站服务器如何用dedecms做网站