前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring源码(三)-Context的创建核心逻辑(下)

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

作者头像
码农小胖哥
修改2019-12-05 17:35:01
5620
修改2019-12-05 17:35:01
举报

以下文章来源于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的赋值操作。至此,完成了对上下文的创建

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-14 20:52:30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农小胖哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、BEANDEFINITION
  • 2、BEAN注册
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档