@@ -0,0 +1,3227 @@
+package io.github.simonxianyu.util.spring;%0A%0Aimport org.springframework.core.io.Resource;%0Aimport org.springframework.core.io.support.PathMatchingResourcePatternResolver;%0Aimport org.springframework.core.io.support.ResourcePatternResolver;%0Aimport org.springframework.core.type.AnnotationMetadata;%0Aimport org.springframework.core.type.ClassMetadata;%0Aimport org.springframework.core.type.MethodMetadata;%0Aimport org.springframework.core.type.classreading.CachingMetadataReaderFactory;%0Aimport org.springframework.core.type.classreading.MetadataReader;%0Aimport org.springframework.core.type.classreading.MetadataReaderFactory;%0Aimport org.springframework.util.ClassUtils;%0A%0Aimport java.io.IOException;%0Aimport java.util.HashSet;%0Aimport java.util.Set;%0A%0A/**%0A * Use spring package search related class to collect Class annotation information.%0A * Because spring using ASM class reader, so detail class information is not loaded.%0A * Created by simon on 16/5/11.%0A */%0Apublic class PackageScanner %7B%0A  protected PathMatchingResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();%0A  private MetadataReaderFactory metadataReaderFactory =%0A      new CachingMetadataReaderFactory(this.resourcePatternResolver);%0A%0A  public Set%3CMethodMetadata%3E search(Class%3C?%3E annotationClass,MethodCallback callback, String... packages) throws IOException %7B%0A    Set%3CMethodMetadata%3E methodSet = new HashSet%3C%3E();%0A    if (null == packages %7C%7C packages.length%3C1) %7B%0A      throw new IllegalArgumentException(%22no package specified%22);%0A    %7D%0A    for(String p : packages) %7B%0A      String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +%0A          ClassUtils.convertClassNameToResourcePath(p)%0A          + %22/%22 + %22**/*.class%22;%0A      Resource%5B%5D resources = resourcePatternResolver.getResources(packageSearchPath);%0A      if (null != resources) %7B%0A        for(Resource resource : resources) %7B%0A          MetadataReader reader = metadataReaderFactory.getMetadataReader(resource);%0A          ClassMetadata classMetadata = reader.getClassMetadata();%0A          AnnotationMetadata annotationMetadata = reader.getAnnotationMetadata();%0A          if (!isCandidateComponent(annotationMetadata)) %7B%0A            continue;%0A          %7D%0A%0A          if (annotationMetadata.hasAnnotatedMethods(annotationClass.getCanonicalName())) %7B%0A//            System.out.println(classMetadata.getClassName());%0A            Set%3CMethodMetadata%3E methods = annotationMetadata.getAnnotatedMethods(annotationClass.getCanonicalName());%0A            methodSet.addAll(methods);%0A            if (null != callback && methods.size()%3E0  ) %7B%0A              for(MethodMetadata m : methods) %7B%0A                //              System.out.println(%22  %22+m.getMethodName());%0A                callback.process(classMetadata, annotationMetadata, m);%0A              %7D%0A            %7D%0A          %7D%0A        %7D%0A      %7D%0A    %7D%0A    return methodSet;%0A  %7D%0A%0A  /**%0A   * Use this callback to handle found method.%0A   */%0A  interface MethodCallback %7B%0A    void process(ClassMetadata classMetadata, AnnotationMetadata annotationMetadata, MethodMetadata methodMetadata);%0A  %7D%0A%0A  protected boolean isCandidateComponent(AnnotationMetadata metadata) %7B%0A    return metadata.isConcrete() && metadata.isIndependent();%0A  %7D%0A%0A%7D%0A

add package scanner of collecting annotation information.