乐趣区

关于spring:Spring-源码学习-10prepareBeanFactory-和-postProcessBeanFactory

前言

依据 refresh 流程,当 obtainFreshBeanFactory 执行完结后,下一步会执行 prepareBeanFactory,顾名思义,这个办法次要是 筹备 BeanFactory,上面一起看一看这部分逻辑。

prepareBeanFactory

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // Tell the internal bean factory to use the context's class loader etc.
    // 设置 beanFactory 的类加载器
    beanFactory.setBeanClassLoader(getClassLoader());
    // spring.spel.ignore 属性管制是否解析 SpEL 表达式
    if (!shouldIgnoreSpel) {beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    }
    // 设置属性解析器
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // Configure the bean factory with context callbacks.
    // 增加到后置处理器列表, 新创建的 ApplicationContextAwareProcessor 入参为以后 ApplicationContext
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

    // 疏忽主动拆卸
    // 默认状况下 只有 BeanFactoryAware 被疏忽 要疏忽其余类型,须要独自设置
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationStartup.class);

    // BeanFactory interface not registered as resolvable type in a plain factory.
    // MessageSource registered (and found for autowiring) as a bean.
    // 注册主动拆卸的类
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    // Register early post-processor for detecting inner beans as ApplicationListeners.
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    // Detect a LoadTimeWeaver and prepare for weaving, if found.
    // 是否须要类加载期间织入  减少 Aspectj 的反对
    if (!IN_NATIVE_IMAGE && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        // Set a temporary ClassLoader for type matching.
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }

    // Register default environment beans.
    // 注册其余的 bean
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
    if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
    }
}

这块代码比拟长,然而逻辑比较简单,就间接贴代码了。

再对代码进行剖析,次要经验以下几个阶段:

  1. addBeanPostProcessor 增加 BeanPostProcessor
  2. registerResolvableDependency 注册依赖关系
  3. registerSingleton 注册其余的单例 Bean

上面能够 Debug 看一下。

Debug

办法调用前:

registerResolvableDependency 执行之后

这里发现调用 registerResolvableDependency 执行完结之后,beanDefinitionNames 中并没有多增加相干对象。

查看源码发现其实是增加到了 resolvableDependencies 这个 Map 中了。

回顾

在介绍 DefaultListableBeanFactory 时,说 BeanDefinition 是存储在 beanDefinitionMap 中的。
而这里的依赖关系是则是存储在 resolvableDependencies 中的。

postProcessBeanFactory

在执行 prepareBeanFactory 之后,当看到 postProcessBeanFactory(beanFactory); 办法的时候就很纳闷,因为这个是须要子类实现的,只是作为一个模板办法,子类实现之后,能够在外面增加本人的逻辑。

总结

这篇文章绝对比较简单,就是筹备 BeanFactory 向其中增加零碎的依赖以及 bean, 而 postProcessBeanFactory 则是一个模版办法用来供子类实现。

相干举荐

  • Spring 源码学习 09:refresh 大略流程
  • Spring 源码学习 08:register 注册配置类
  • Spring 源码学习 07:ClassPathBeanDefinitionScanner
退出移动版