Spring源码(三)-Context的创建核心逻辑(下)

2019-12-05 17:35:01 浏览数 (2)

以下文章来源于SpringForAll社区,作者Darren Luo

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

1、BEANDEFINITION

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

1、BeanDefinition 设计bean相关信息

2、BeanDefinitionHolder 封装bean定义相关信息,以及bean名称、别名等

3、BeanDefinitionRegistry 持有所有注册的bean相关信息

下面我们接着上面一篇 registerAnnotationConfigProcessors()方法的分析。

代码语言:javascript复制
      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,其中

代码语言:javascript复制
registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)

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

2、BEAN注册
代码语言:javascript复制
    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中的方法

代码语言:javascript复制
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)

            throws BeanDefinitionStoreException {


        this.beanFactory.registerBeanDefinition(beanName, beanDefinition);

    }

其中this.beanFactory为DefaultListableBeanFactory实例

代码语言:javascript复制
    @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、首先完成校验

代码语言:javascript复制
((AbstractBeanDefinition) beanDefinition).validate()

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

代码语言:javascript复制
oldBeanDefinition = this.beanDefinitionMap.get(beanName);

3、为空进入以下代码

代码语言:javascript复制
    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实例的创建

代码语言:javascript复制
    public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {  

            this(registry, useDefaultFilters, getOrCreateEnvironment(registry));  

        }

调用内部方法

代码语言:javascript复制
    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构造

代码语言:javascript复制
    public ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters, Environment environment) {  

            if (useDefaultFilters) {  

                registerDefaultFilters();  

            }  

            Assert.notNull(environment, "Environment must not be null");  

            this.environment = environment;  

    }

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

代码语言:javascript复制
    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注解增加到包含过滤规则中。

代码语言:javascript复制
    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的赋值操作。至此,完成了对上下文的创建

0 人点赞