有时候想要扫描某一个包下的类,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())); } }