Spring源码分析spring源码JavaWeb 知识点

Spring源码(三)-Context的创建(下)

2017-08-15  本文已影响176人  阿亮私语

由于该篇文章较多,所以就拆分为了上下两篇,接上面完成了beanFactory的信息处理,接下来是bean的相关定义的处理。

1、BeanDefinition

获取完beanFactory的之后,代码涉及到了一些bean的定义,接下来看beanDefination的定义。

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));  
        }  

这段代码以及其紧跟的代码为创建若干bean,其中

registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)

表示注册名称为org.springframework.context.annotation.internalConfigurationAnnotationProcessor,beanClass 对应为ConfigurationClassPostProcessor的bean

2、Bean注册

private static BeanDefinitionHolder registerPostProcessor(
        BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

    definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    registry.registerBeanDefinition(beanName, definition);
    return new BeanDefinitionHolder(definition, beanName);
}

其中registry.registerBeanDefinition(beanName,definition)调用GenericApplicationContext中的方法

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
        throws BeanDefinitionStoreException {

    this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}

其中this.beanFactory为DefaultListableBeanFactory实例

    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException {

        Assert.hasText(beanName, "Bean name must not be empty");
        Assert.notNull(beanDefinition, "BeanDefinition must not be null");

        if (beanDefinition instanceof AbstractBeanDefinition) {
            try {
                ((AbstractBeanDefinition) beanDefinition).validate();
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                        "Validation of bean definition failed", ex);
            }
        }

        BeanDefinition oldBeanDefinition;

        oldBeanDefinition = this.beanDefinitionMap.get(beanName);
        if (oldBeanDefinition != null) {
            if (!isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                        "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
                        "': There is already [" + oldBeanDefinition + "] bound.");
            }
            else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
                // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
                            "' with a framework-generated bean definition: replacing [" +
                            oldBeanDefinition + "] with [" + beanDefinition + "]");
                }
            }
            else if (!beanDefinition.equals(oldBeanDefinition)) {
                if (this.logger.isInfoEnabled()) {
                    this.logger.info("Overriding bean definition for bean '" + beanName +
                            "' with a different definition: replacing [" + oldBeanDefinition +
                            "] with [" + beanDefinition + "]");
                }
            }
            else {
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Overriding bean definition for bean '" + beanName +
                            "' with an equivalent definition: replacing [" + oldBeanDefinition +
                            "] with [" + beanDefinition + "]");
                }
            }
            this.beanDefinitionMap.put(beanName, beanDefinition);
        }
        else {
            if (hasBeanCreationStarted()) {
                // Cannot modify startup-time collection elements anymore (for stable iteration)
                synchronized (this.beanDefinitionMap) {
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
                    updatedDefinitions.addAll(this.beanDefinitionNames);
                    updatedDefinitions.add(beanName);
                    this.beanDefinitionNames = updatedDefinitions;
                    if (this.manualSingletonNames.contains(beanName)) {
                        Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
                        updatedSingletons.remove(beanName);
                        this.manualSingletonNames = updatedSingletons;
                    }
                }
            }
            else {
                // Still in startup registration phase
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                this.manualSingletonNames.remove(beanName);
            }
            this.frozenBeanDefinitionNames = null;
        }

        if (oldBeanDefinition != null || containsSingleton(beanName)) {
            resetBeanDefinition(beanName);
        }
    }

以上方法完成了bean的注册;
1、首先完成校验

((AbstractBeanDefinition) beanDefinition).validate()

2、接下来从map中获取bean,首次获取肯定是空

oldBeanDefinition = this.beanDefinitionMap.get(beanName);

3、为空进入以下代码

if (hasBeanCreationStarted()) {
    // Cannot modify startup-time collection elements anymore (for stable iteration)
    synchronized (this.beanDefinitionMap) {
        this.beanDefinitionMap.put(beanName, beanDefinition);
        List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
        updatedDefinitions.addAll(this.beanDefinitionNames);
        updatedDefinitions.add(beanName);
        this.beanDefinitionNames = updatedDefinitions;
        if (this.manualSingletonNames.contains(beanName)) {
            Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
            updatedSingletons.remove(beanName);
            this.manualSingletonNames = updatedSingletons;
        }
    }
}
else {
    // Still in startup registration phase
    this.beanDefinitionMap.put(beanName, beanDefinition);
    this.beanDefinitionNames.add(beanName);
    this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;

这里顺便解释下,在从map中获取到bean时表示bean已经注册,则会判断是否可以覆盖oldBean,也需要判断bean对应的Role级别

以上完成了AnnotationConfigEmbeddedWebApplicationContext中 AnnotatedBeanDefinitionReader实例的构造

接下来为ClassPathBeanDefinitionScanner实例的创建

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {  
        this(registry, useDefaultFilters, getOrCreateEnvironment(registry));  
    }  

调用内部方法

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
        Environment environment, @Nullable ResourceLoader resourceLoader) {

    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    this.registry = registry;

    if (useDefaultFilters) {
        //注册默认拦截器,将Component、ManagedBean、Named注解增加到包含过滤规则中。
        registerDefaultFilters();
    }
    setEnvironment(environment);
    //完成对resourcePatternResolver以及metadataReaderFactory的赋值操作。
    setResourceLoader(resourceLoader);
}

调用super构造

public ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters, Environment environment) {  
        if (useDefaultFilters) {  
            registerDefaultFilters();  
        }  
        Assert.notNull(environment, "Environment must not be null");  
        this.environment = environment;  
}  

在该方法中完成了environment的赋值以及为ClassPathScanningCandidateComponentProvider完成了默认过滤器的注册

protected void registerDefaultFilters() {  
        this.includeFilters.add(new AnnotationTypeFilter(Component.class));  
        ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();  
        try {  
            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 {  
            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注解增加到包含过滤规则中。

setResourceLoader((ResourceLoader) this.registry)  
    public void setResourceLoader(@Nullable ResourceLoader resourceLoader) {
        this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
        this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
        this.componentsIndex = CandidateComponentsIndexLoader.loadIndex(this.resourcePatternResolver.getClassLoader());
    }

完成对resourcePatternResolver以及metadataReaderFactory的赋值操作。
至此,完成了对上下文的创建

代码的构建请参考 github
该地址有相应代码的注释

Spring源码分析

上一篇下一篇

猜你喜欢

热点阅读