zoukankan      html  css  js  c++  java
  • Spring 源码学习 10:prepareBeanFactory 和 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 则是一个模版方法用来供子类实现。

    相关推荐

  • 相关阅读:
    使用TCP
    socket基本
    windows内核原理及实现-----进程线程管理------3.4节中 windows中进程句柄
    windows内核原理及实现-----进程线程管理------3.3节中 windows中进程线程的数据结构
    winDBG用法
    windows调试异常机制
    MYSQL5上运行多个实例
    Mysql双主实战
    Mysql-Proxy使用
    新的旅程
  • 原文地址:https://www.cnblogs.com/liuzhihang/p/source-spring-10.html
Copyright © 2011-2022 走看看