Component-Scan源码解析
入口解析
IOC过程中,自定义标签解析,就是Component-Scan入口,详情查看IOC自定义标签相关文档。
// ContextNamespaceHandler
@Override
public void init() {
registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
}
可以看到component-scan, 对应加载的就是ComponentScanBeanDefinitionParser。Spring是使用ComponentScanBeanDefinitionParser来进行扫描的。
ComponentScanBeanDefinitionParser.parse()方法
// ComponentScanBeanDefinitionParser.java
public BeanDefinition parse(Element element, ParserContext parserContext) {
// 获取base-packgage属性
String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
// 对base-package的值中的${}进行解析并替换
basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
// 解析分隔符
String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
// 创建classpath扫描器
ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
// 执行扫描操作,返回组装好的BeanDefinition集合
Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
// 根据配置注册相关组件
registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
return null;
}
- 获取base-packgage属性
- 对base-package的值中的${}进行解析并替换
- 解析分隔符
- 创建Classpath扫描器
- 执行扫描scanner.doScan操作,返回组装好的BeanDefinition集合
- 根据配置注册相关组件
创建Classpath扫描器
ComponentScanBeanDefinitionParser.java
protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
// 是否使用默认过滤器(@Component注解)
boolean useDefaultFilters = true;
if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) {
useDefaultFilters = Boolean.valueOf(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE));
}
// Delegate bean definition registration to scanner class.
// 创建scan实例,设置默认过滤器
ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters);
scanner.setResourceLoader(parserContext.getReaderContext().getResourceLoader());
scanner.setEnvironment(parserContext.getReaderContext().getEnvironment());
scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());
// 解析资源正则表达式,匹配类名称
if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) {
scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE));
}
try {
// 解析bean名称生成器
parseBeanNameGenerator(element, scanner);
}
catch (Exception ex) {
parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
}
try {
// scope-resolver(scope解析器)以及scope-proxy(代理方式,默认为no)
parseScope(element, scanner);
}
catch (Exception ex) {
parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
}
// include-filters和exclude-filters解析
parseTypeFilters(element, scanner, parserContext);
return scanner;
}
- 判断是否使用默认过滤器(@Component注解),并且设置boolean变量
- 创建scan实例,设置默认过滤器
- 设置解析资源正则表达式,匹配类名称
- 解析bean名称生成器
- scope-resolver(scope解析器)以及scope-proxy(代理方式,默认为no)
- include-filters和exclude-filters解析
创建scan实例,设置默认过滤器
protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) {
return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters,
readerContext.getEnvironment(), readerContext.getResourceLoader());
}
// 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
protected void registerDefaultFilters() {
// @Component注册过滤器
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
// @ManagedBean过滤器
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
logger.debug("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 {
// @Named过滤器
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
- 父类实现,设置默认过滤器
- 添加@Component注册过滤器
- 添加@ManagedBean过滤器
- 添加@Named过滤器
- 设置其他参数
一般情况下都是通过**@Component**来过滤,而@Repository,@Service,@Controller都是@Component的子类
include-filters和exclude-filters解析
<context:component-scan base-package="com.lcifn.spring">
<context:include-filter type="annotation" expression="com.lcifn.SelfDefined"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
需要解析上述自定义标签,对于不同的type生成不同的TypeFilter
// ComponentScanBeanDefinitionParser.java
protected void parseTypeFilters(Element element, ClassPathBeanDefinitionScanner scanner, ParserContext parserContext) {
// Parse exclude and include filter elements.
ClassLoader classLoader = scanner.getResourceLoader().getClassLoader();
NodeList nodeList = element.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
String localName = parserContext.getDelegate().getLocalName(node);
try {
// include-filter
if (INCLUDE_FILTER_ELEMENT.equals(localName)) {
TypeFilter typeFilter = createTypeFilter((Element) node, classLoader, parserContext);
scanner.addIncludeFilter(typeFilter);
}
// exclude-filter
else if (EXCLUDE_FILTER_ELEMENT.equals(localName)) {
TypeFilter typeFilter = createTypeFilter((Element) node, classLoader, parserContext);
scanner.addExcludeFilter(typeFilter);
}
}
catch (Exception ex) {
parserContext.getReaderContext().error(
ex.getMessage(), parserContext.extractSource(element), ex.getCause());
}
}
}
}
- scanner设置include-filter
- scanner设置exclude-filter
扫描scanner.doScan()操作
// ClassPathBeanDefinitionScanner.java
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>();
for (String basePackage : basePackages) {
// 扫描包路径,找到所有候选者
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
// 解析scope属性
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
// 生成bean名称
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
// 组装BeanDefinition默认属性
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
// 解析类中的注解配置
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
// 校验同已注册的BeanDefinition是否有冲突
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
// scope-proxy设置
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
// 注册BeanDefinition到容器中
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
- 扫描包路径,找到所有候选者
- 解析scope属性,设置到BeanDefinition
- 生成bean名称,设置到BeanDefinition
- 组装BeanDefinition默认属性
- 解析类中的注解配置,设置到BeanDefinition
- 如果和已注册的BeanDefinition是否有冲突,设置BeanDefinition的scope-proxy
- 注册BeanDefinition到容器中
找到所有候选者findCandidateComponents(basePackage)
// ClassPathScanningCandidateComponentProvider
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
}
else {
return scanCandidateComponents(basePackage);
}
}
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
// 根据base-package以及resource-pattern组装出资源匹配表达式来匹配并读取所有的class文件
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
for (Resource resource : resources) {
if (traceEnabled) {
logger.trace("Scanning " + resource);
}
if (resource.isReadable()) {
try {
// 获取class文件元信息
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
// 匹配TypeFilter
if (isCandidateComponent(metadataReader)) {
// 把源信息封装成ScannedGenericBeanDefinition
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
// 校验ScannedGenericBeanDefinition是否非接口非抽象
if (isCandidateComponent(sbd)) {
if (debugEnabled) {
logger.debug("Identified candidate component class: " + resource);
}
// 加入候选者集合
candidates.add(sbd);
}
else {
if (debugEnabled) {
logger.debug("Ignored because not a concrete top-level class: " + resource);
}
}
}
else {
if (traceEnabled) {
logger.trace("Ignored because not matching any filter: " + resource);
}
}
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to read candidate component class: " + resource, ex);
}
}
else {
if (traceEnabled) {
logger.trace("Ignored because not readable: " + resource);
}
}
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
}
return candidates;
}
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
for (TypeFilter tf : this.excludeFilters) {
if (tf.match(metadataReader, this.metadataReaderFactory)) {
return false;
}
}
for (TypeFilter tf : this.includeFilters) {
if (tf.match(metadataReader, this.metadataReaderFactory)) {
return isConditionMatch(metadataReader);
}
}
return false;
}
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
AnnotationMetadata metadata = beanDefinition.getMetadata();
return (metadata.isIndependent() && (metadata.isConcrete() ||
(metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()))));
}
- 根据base-package以及resource-pattern组装出资源匹配表达式来匹配并读取所有的class文件
- 获取class文件元信息
- 元信息匹配TypeFilter
- 把源信息封装成ScannedGenericBeanDefinition
- 校验ScannedGenericBeanDefinition是否非接口非抽象
- 加入候选者集合
组装BeanDefinition默认属性
// ClassPathBeanDefinitionScanner.java
protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) {
// 设置默认属性
beanDefinition.applyDefaults(this.beanDefinitionDefaults);
if (this.autowireCandidatePatterns != null) {
beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName));
}
}
public void applyDefaults(BeanDefinitionDefaults defaults) {
setLazyInit(defaults.isLazyInit()); // false
setAutowireMode(defaults.getAutowireMode()); // AUTOWIRE_NO
setDependencyCheck(defaults.getDependencyCheck());// DEPENDENCY_CHECK_NONE
setInitMethodName(defaults.getInitMethodName()); // null
setEnforceInitMethod(false);
setDestroyMethodName(defaults.getDestroyMethodName());// null
setEnforceDestroyMethod(false);
}
解析类中的注解配置,设置到AnnotatedBeanDefinition
// AnnotationConfigUtils.java
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
// 解析@Lazy,设置到AnnotatedBeanDefinition
if (metadata.isAnnotated(Lazy.class.getName())) {
abd.setLazyInit(attributesFor(metadata, Lazy.class).getBoolean("value"));
}
else if (abd.getMetadata() != metadata && abd.getMetadata().isAnnotated(Lazy.class.getName())) {
abd.setLazyInit(attributesFor(abd.getMetadata(), Lazy.class).getBoolean("value"));
}
// 解析@Primary,设置到AnnotatedBeanDefinition
if (metadata.isAnnotated(Primary.class.getName())) {
abd.setPrimary(true);
}
// 解析@DependsOn,设置到AnnotatedBeanDefinition
if (metadata.isAnnotated(DependsOn.class.getName())) {
abd.setDependsOn(attributesFor(metadata, DependsOn.class).getStringArray("value"));
}
if (abd instanceof AbstractBeanDefinition) {
AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd;
// 解析@Role,设置到AnnotatedBeanDefinition
if (metadata.isAnnotated(Role.class.getName())) {
absBd.setRole(attributesFor(metadata, Role.class).getNumber("value").intValue());
}
// 解析@Description,设置到AnnotatedBeanDefinition
if (metadata.isAnnotated(Description.class.getName())) {
absBd.setDescription(attributesFor(metadata, Description.class).getString("value"));
}
}
}
- 解析@Lazy,设置到AnnotatedBeanDefinition
- 解析@Primary,设置到AnnotatedBeanDefinition
- 解析@DependsOn,设置到AnnotatedBeanDefinition
- 解析@Role,设置到AnnotatedBeanDefinition
- 解析@Description,设置到AnnotatedBeanDefinition
根据配置注册相关组件
// ComponentScanBeanDefinitionParser
protected void registerComponents(
XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) {
Object source = readerContext.extractSource(element);
// 创建复合组件定义CompositeComponentDefinition
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);
// 把BeanDefinitionHolder集合加入到CompositeComponentDefinition中
for (BeanDefinitionHolder beanDefHolder : beanDefinitions) {
compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder));
}
// Register annotation config processors, if necessary.
boolean annotationConfig = true;
if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) {
annotationConfig = Boolean.valueOf(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE));
}
if (annotationConfig) {
// 使用AnnotationConfigUtils工具,获取注解解析器集合
Set<BeanDefinitionHolder> processorDefinitions =
AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);
// 把BeanDefinitionHolder集合加入到CompositeComponentDefinition中
for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));
}
}
// 触发事件
readerContext.fireComponentRegistered(compositeDef);
}
- 创建复合组件定义CompositeComponentDefinition
- 把BeanDefinitionHolder集合加入到CompositeComponentDefinition中
- 使用AnnotationConfigUtils工具,获取注解解析器集合
- 把BeanDefinitionHolder集合加入到CompositeComponentDefinition中
- 触发组件注册事件
// AnnotationConfigUtils
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4);
// @Configuration注解解析器
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// @Autowired注解解析器
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// @Required注解解析器
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
return beanDefs;
}
- 添加@Configuration注解解析器
- 添加@Autowired注解解析器
- 添加@Required注解解析器
主要的@Configuration,@Autowired,@Required的解析器,都是BeanFactoryPostProcessor或者BeanPostProcessor的子类,在这里注册到spring容器中。等到bean实例化的过程中,在适当的时候对bean进行配置或调整。
总结
ComponentScanBeanDefinitionParser.parse()总体流程如下
- 获取base-packgage属性
- 对base-package的值中的${}进行解析并替换
- 解析分隔符
- 创建Classpath扫描器
- 判断是否使用默认过滤器(@Component注解),并且设置boolean变量
- 创建scan实例,设置默认过滤器
- 父类实现,设置默认过滤器
- 添加@Component注册过滤器
- 添加@ManagedBean过滤器
- 添加@Named过滤器
- 设置其他参数
- 父类实现,设置默认过滤器
- 设置解析资源正则表达式,匹配类名称
- 解析bean名称生成器
- scope-resolver(scope解析器)以及scope-proxy(代理方式,默认为no)
- include-filters和exclude-filters解析
- scanner设置include-filter
- scanner设置exclude-filter
- 执行扫描scanner.doScan操作,返回组装好的BeanDefinition集合
- 扫描包路径,找到所有候选者
- 根据base-package以及resource-pattern组装出资源匹配表达式来匹配并读取所有的class文件
- 获取class文件元信息
- 元信息匹配TypeFilter
- 把源信息封装成ScannedGenericBeanDefinition
- 校验ScannedGenericBeanDefinition是否非接口非抽象
- 加入候选者集合
- 解析scope属性,设置到BeanDefinition
- 生成bean名称,设置到BeanDefinition
- 组装BeanDefinition默认属性
- 解析类中的注解配置,设置到BeanDefinition
- 解析@Lazy,设置到AnnotatedBeanDefinition
- 解析@Primary,设置到AnnotatedBeanDefinition
- 解析@DependsOn,设置到AnnotatedBeanDefinition
- 解析@Role,设置到AnnotatedBeanDefinition
- 解析@Description,设置到AnnotatedBeanDefinition
- 如果和已注册的BeanDefinition是否有冲突,设置BeanDefinition的scope-proxy
- 注册BeanDefinition到容器中
- 扫描包路径,找到所有候选者
- 根据配置注册相关组件
- 创建复合组件定义CompositeComponentDefinition
- 把BeanDefinitionHolder集合加入到CompositeComponentDefinition中
- 使用AnnotationConfigUtils工具,获取注解解析器集合
- 添加@Configuration注解解析器
- 添加@Autowired注解解析器
- 添加@Required注解解析器
- 把BeanDefinitionHolder集合加入到CompositeComponentDefinition中
- 触发组件注册事件