@Override protected void doParse( Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { Map<String, ParsingModuleInfo> classes = parseSpecificBeans( element, parserContext, builder.getRawBeanDefinition(), and(beansNs(), name("bean"))); ElementSelector searchPackages = and(sameNs(element), name("search-packages")); ElementSelector searchClasses = and(sameNs(element), name("search-classes")); ModuleDefinitionScanner scanner = getScanner(parserContext); for (Element subElement : subElements(element)) { Pattern classNamePattern = null; String typeName = null; String moduleName = null; String classResourceName = null; if (searchPackages.accept(subElement)) { String packageName = assertNotNull( normalizeClassName(subElement.getAttribute("packages")), "no package name provided for search-packages"); classNamePattern = compileClassName(packageName, MATCH_PREFIX); typeName = assertNotNull(trimToNull(subElement.getAttribute("type")), "no type name provided"); classResourceName = classNameToPathName(packageName) + "/**/*.class"; log.trace("Searching in packages: {}, moduleType={}", packageName, typeName); } else if (searchClasses.accept(subElement)) { String className = assertNotNull( normalizeClassName(subElement.getAttribute("classes")), "no class name provided for search-classes"); classNamePattern = compileClassName(className, MATCH_PREFIX); typeName = assertNotNull(trimToNull(subElement.getAttribute("type")), "no type name provided"); moduleName = assertNotNull(trimToNull(subElement.getAttribute("name")), "no module name provided"); classResourceName = classNameToPathName(className); if (classResourceName.endsWith("**")) { classResourceName += "/*.class"; } else { classResourceName += ".class"; } log.trace( "Searching for classes: {}, moduleType={}, moduleName={}", new Object[] {className, typeName, moduleName}); } boolean includeAbstractClasses = "true".equalsIgnoreCase(trimToNull(subElement.getAttribute("includeAbstractClasses"))); if (classResourceName != null) { // 处理所有的include/exclude filters ClassLoader classLoader = scanner.getResourceLoader().getClassLoader(); List<TypeFilter> includes = createLinkedList(); List<TypeFilter> excludes = createLinkedList(); parseTypeFilters(subElement, classLoader, includes, excludes); ModuleTypeFilter filter = new ModuleTypeFilter(classes, classNamePattern, typeName, moduleName, includes); // 事实上,只有一个顶级的include filter,其它的include filter被这一个moduleTypeFilter所调用。 scanner.addIncludeFilter(filter); // Exclude filter比较简单,直接加到scanner中即可。 for (TypeFilter exclude : excludes) { scanner.addExcludeFilter(exclude); } scanner.setBeanNameGenerator(filter); scanner.setResourcePattern(classResourceName.replace('?', '*')); scanner.setIncludeAbstractClasses(includeAbstractClasses); scanner.setBeanDefinitionDefaults(getBeanDefinitionDefaults(subElement, parserContext)); int found = scanner.scan(""); log.debug("Found {} module classes with pattern: {}", found, classResourceName); } } postProcessItems(element, parserContext, builder, classes, "search-packages or search-classes"); }
private ModuleDefinitionScanner getScanner(ParserContext parserContext) { ModuleDefinitionScanner scanner = new ModuleDefinitionScanner(parserContext.getRegistry()); scanner.setResourceLoader(parserContext.getReaderContext().getResourceLoader()); return scanner; }