当前位置: 首页 > 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.pierceye.com/news/498586/

相关文章:

  • 固始县网站建设培训怎么制作网站首页
  • 产品经理做网站三河市最新消息
  • 做新闻类网站需要什么资质如何外贸seo网站建设
  • 注册网站流程和费用百度seo关键词排名s
  • 做推广网站的去哪能买到有效资料苏州建设网站找网络公司
  • vs做网站如何输出怎么做flash网站
  • 网站做政务广告传媒公司简介ppt
  • 番茄网络营销策划方案seo网站培训
  • 自己做一网站高唐网页定制
  • 快速网站seo效果什么是网络营销与概念
  • 个体网站建设企业网站做的好的有什么公司
  • 建设银行网站短信错误6次wordpress个人淘客
  • 让网站快速收录最新集团公司网站案例
  • 网站开发公司长春高校 网站建设实施方案
  • 我做的网站打开慢怎么处理防控措施有这些优化
  • 网站的登录界面是怎么做的网站开发 职位
  • 西安英文网站制作企业年报申报入口官网
  • 做一网站多少钱企业官方网站建设教程
  • 自己建的网站能用吗海南网站建设哪家好
  • 网络公司网站模板html网站制作 数据库
  • 温州哪里有网站优化南通营销网站建设
  • 怎么在网站标头做图标wordpress 远程数据库
  • 厦门做手机网站公司最新常州网页制作招聘
  • 施工企业农民工工资专项检查报告百度seo怎么把关键词优化上去
  • 圆通速递我做网站sydney wordpress
  • 做外汇有哪些正规的网站做网站只用前端知识可以吗
  • 奢侈品购物网站排名微分销手机网站制作
  • 东莞市永铭装饰有限公司优质的seo快速排名优化
  • 大型网站服务器配置西宁网站设计建设
  • 网站怎么加ico网站模板上传到那个目录