先看一下ClassPathBeanDefinitionScanner类注释和翻译:
/**
* A bean definition scanner that detects bean candidates on the classpath,
* registering corresponding bean definitions with a given registry ({@code BeanFactory}
* or {@code ApplicationContext}).
*
* <p>Candidate classes are detected through configurable type filters. The
* default filters include classes that are annotated with Spring's
* {@link org.springframework.stereotype.Component @Component},
* {@link org.springframework.stereotype.Repository @Repository},
* {@link org.springframework.stereotype.Service @Service}, or
* {@link org.springframework.stereotype.Controller @Controller} stereotype.
*
* <p>Also supports Java EE 6's {@link javax.annotation.ManagedBean} and
* JSR-330's {@link javax.inject.Named} annotations, if available.
*
*/
一个BeanDefinition扫描程序,检测classpath路径上的bean候选对象,并使用给定的BeanDefinitionRegistry(BeanFactory或ApplicationContext)注册相应的BeanDefinition。
通过可配置的类型过滤器检测候选类。默认的过滤器包括用Spring的@Component,@Repository,@Service或@Controller构造型注释的类。
如果可用,还支持Java EE 6的javax.annotation.ManagedBean和JSR-330的javax.inject.Named注释。
类图:说白了二者是父子关系,ClassPathBeanDefinitionScanner和父类一起,做BeanDefinition的扫描工作,
ClassPathBeanDefinitionScanner的主要构造方法:
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
if (useDefaultFilters) {
registerDefaultFilters();
}
setEnvironment(environment);
setResourceLoader(resourceLoader);
}
ClassPathScanningCandidateComponentProvider的主要构造方法:
public ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters, Environment environment) {
if (useDefaultFilters) {
registerDefaultFilters();
}
setEnvironment(environment);
setResourceLoader(null);
}
ClassPathBeanDefinitionScanner类内public方法:其实说白了,主要就是要用这里的 scan() 方法,扫描出指定包路径下的BeanDefinition
ClassPathScanningCandidateComponentProvider类内public方法:
这里的findCandidateComponents方法,查找出路径下所有候选BeanDefinition,ClassPathBeanDefinitionScanner类的scan方法中调用此方法获取所有候选BeanDefinition,然后做了些后续处理,检查通过后注册到了BeanDefinitionRegistry 。