有时候想要扫描某一个包下的类,spring提供一个一扫描的类,org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider
这个类的findCandidateComponents就是扫描的方法。通过自己继承这个类,再提供类的过滤条件。就可以了
还可以继承它的子类org.springframework.context.annotation.ClassPathBeanDefinitionScanner
需要两个过滤设置。因为扫描的时候会过滤两次addIncludeFilter 添加的条件isCandidateComponent(AnnotatedBeanDefinition)方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public  class  ClassPathCacheEntityScanner  extends  ClassPathScanningCandidateComponentProvider  {    private  Logger  logger  =  LoggerFactory.getLogger(getClass());     ClassPathCacheEntityScanner(BeanDefinitionRegistry registry) {         super (false );                   addIncludeFilter(new  AnnotationTypeFilter (Entity.class));          addIncludeFilter(new  AnnotationTypeFilter (Table.class));     }     public  Set<Class> doScan (String... basePackages)  throws  ClassNotFoundException {         Assert.notEmpty(basePackages, "At least one base package must be specified" );         Set<Class> entitySet = new  HashSet <>();         for  (String basePackage : basePackages) {             Set<BeanDefinition> candidates = findCandidateComponents(basePackage);             for  (BeanDefinition candidate : candidates) {                 Class  entityClass  =  ClassUtils.forName(candidate.getBeanClassName(), null );                 entitySet.add(entityClass);             }         }         return  entitySet;     }          @Override      protected  boolean  isCandidateComponent (AnnotatedBeanDefinition beanDefinition)  {         return  beanDefinition.getMetadata().isConcrete()              && (beanDefinition.getMetadata().hasAnnotation(Entity.class.getName())              || beanDefinition.getMetadata().hasAnnotation(Table.class.getName()));      } }