咱們搭建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; }