spring IOC源碼學習(一)

咱們搭建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;
    }
相關文章
相關標籤/搜索