咱们搭建SSM框架的时候,将service等等会注册到IOC当中,这里咱们先看一下配置文件node
<!-- 自动扫描 --> <context:component-scan base-package="com.ssm" />
这里咱们看到,spring进行初始化的时候,只有这一句配置,那它是什么时候进行扫描的呢spring
咱们先来看一下Spring Bean的体系结构数组
其中BeanFactory做为最顶层的一个接口类,它定义了IOC容器的基本功能规范,BeanFactory 有三个子类:ListableBeanFactory、HierarchicalBeanFactory 和AutowireCapableBeanFactory。可是从上图中咱们能够发现最终的默认实现类是 DefaultListableBeanFactory,他实现了全部的接口,咱们就进入DefaultListableBeanFactory中app
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
能够看到定义了一个map,能够猜想,map是经过前面的stringkey获取到bean对象框架
咱们还能够在这个类中找到一个parseBeanDefinitions这个函数函数
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { if (delegate.isDefaultNamespace(root)) { NodeList nl = root.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (node instanceof Element) { Element ele = (Element) node; if (delegate.isDefaultNamespace(ele)) { parseDefaultElement(ele, delegate); } else { delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } }
这个函数是分析配置文件,咱们能够看到post
最后咱们能够看到是要去解析咱们的扫描文件this
进入ComponentScanBeanDefinitionParser这个类 spa
public BeanDefinition parse(Element element, ParserContext parserContext) { String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE); basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage); String[] basePackages = StringUtils.tokenizeToStringArray(basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); // Actually scan for bean definitions and register them. ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element); Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
//在这里注册咱们 的每一个bean registerComponents(parserContext.getReaderContext(), beanDefinitions, element); return null; }
这里在获取要扫描哪些包,最后加载到一个数组中,下图是个人截图code
而后经过scanner.doScan(basePackages);进行扫描,将每一个注解类找出后返回注册
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) { ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); if (candidate instanceof AbstractBeanDefinition) { postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) { AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } if (checkCandidate(beanName, candidate)) { BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); beanDefinitions.add(definitionHolder); registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions; }