Spring IoC源码学习:总览

IoC 构建过程:
Spring 初始化的入口在 ContextLoaderListener,如果你的项目用了 Spring,通常可以在 web.xml 中找到下面这行代码。

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

ContextLoaderListener 是实现了 javax.servlet.ServletContextListener 接口的服务器端程序,随 web 应用的启动而启动,只初始化一次,随 web 应用的停止而销毁。在web应用启动的时候会调用 contextInitialized 方法,停止的时候会调用 contextDestroyed 方法

从 ContextLoaderListener 类为出发点,跟着下面的调用过程:

ContextLoaderListener.contextInitialized(ServletContextEvent event) -> 
    initWebApplicationContext(event.getServletContext());
ContextLoader.initWebApplicationContext(ServletContext servletContext) -> 		
    configureAndRefreshWebApplicationContext(cwac, servletContext);
ContextLoader.configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) ->
    wac.refresh(); 
AbstractApplicationContext.refresh()

我们最终来到了 AbstractApplicationContext.java 里的 refresh() 方法,这个方法就是构建整个 IoC 容器过程的完整代码,只要把这个方法里的每一行代码都了解了,基本上了解了大部分 Spring 的原理和功能。

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        prepareRefresh();
 
        // Tell the subclass to refresh the internal bean factory.
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 
        // Prepare the bean factory for use in this context.
        prepareBeanFactory(beanFactory);
 
        try {
            // Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);
 
            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);
 
            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);
 
            // Initialize message source for this context.
            initMessageSource();
 
            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();
 
            // Initialize other special beans in specific context subclasses.
            onRefresh();
 
            // Check for listener beans and register them.
            registerListeners();
 
            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);
 
            // Last step: publish corresponding event.
            finishRefresh();
        } catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "cancelling refresh attempt: " + ex);
            }
 
            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();
 
            // Reset 'active' flag.
            cancelRefresh(ex);
 
            // Propagate exception to caller.
            throw ex;
        } finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}

startupShutdownMonitor 属性

用于“刷新”和“销毁”的同步监视器,说白了就是一个锁。

prepareRefresh() 方法

为刷新准备新的上下文环境,设置其启动日期和活动标志以及执行一些属性的初始化。主要是一些准备工作,不是很重要的方法,可以先不关注。

obtainFreshBeanFactory() 方法

用于获得一个新的 BeanFactory。

该方法会解析所有 Spring 配置文件(通常我们会放在 resources 目录下),将所有 Spring 配置文件中的 bean
定义封装成 BeanDefinition,加载到 BeanFactory
中。常见的,如果解析到<context:component-scan base-package=“com.joonwhee.open” />
注解时,会扫描 base-package
指定的目录,将该目录下使用指定注解(@Controller、@Service、@Component、@Repository)的 bean
定义也同样封装成 BeanDefinition,加载到 BeanFactory 中。 上面提到的“加载到 BeanFactory
中”的内容主要指的是以下3个缓存:

beanDefinitionNames缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 集合。
beanDefinitionMap缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 和BeanDefinition 映射。
aliasMap缓存:所有被加载到 BeanFactory 中的 bean 的 beanName
和别名映射。

prepareBeanFactory(beanFactory) 方法
配置 beanFactory 的标准上下文特征,例如上下文的 ClassLoader、后置处理器等。这个方法会注册3个默认环境 bean:environment、systemProperties 和 systemEnvironment,注册 2 个 bean 后置处理器:ApplicationContextAwareProcessor 和 ApplicationListenerDetector。

postProcessBeanFactory(beanFactory) 方法

允许子类对 BeanFactory 进行后续处理,默认实现为空,留给子类实现。

invokeBeanFactoryPostProcessors(beanFactory) 方法

实例化和调用所有 BeanFactoryPostProcessor,包括其子类 BeanDefinitionRegistryPostProcessor。

BeanFactoryPostProcessor 接口是 Spring 初始化 BeanFactory 时对外暴露的扩展点,Spring IoC 容器允许 BeanFactoryPostProcessor 在容器实例化任何 bean 之前读取 bean 的定义,并可以修改它。

BeanDefinitionRegistryPostProcessor 继承自 BeanFactoryPostProcessor,比 BeanFactoryPostProcessor 具有更高的优先级,主要用来在常规的 BeanFactoryPostProcessor 激活之前注册一些 bean 定义。特别是,你可以通过 BeanDefinitionRegistryPostProcessor 来注册一些常规的 BeanFactoryPostProcessor,因为此时所有常规的 BeanFactoryPostProcessor 都还没开始被处理。

注:这边的 “常规 BeanFactoryPostProcessor” 主要用来跟 BeanDefinitionRegistryPostProcessor 区分。

registerBeanPostProcessors(beanFactory) 方法
注册所有的 BeanPostProcessor,将所有实现了 BeanPostProcessor 接口的类加载到 BeanFactory 中。

BeanPostProcessor 接口是 Spring 初始化 bean 时对外暴露的扩展点,Spring IoC 容器允许 BeanPostProcessor 在容器初始化 bean 的前后,添加自己的逻辑处理。在这边只是注册到 BeanFactory 中,具体调用是在 bean 初始化的时候。

具体的:在所有 bean 实例化时,执行初始化方法前会调用所有 BeanPostProcessor 的 postProcessBeforeInitialization 方法,执行初始化方法后会调用所有 BeanPostProcessor 的 postProcessAfterInitialization 方法。

initMessageSource() 方法
初始化消息资源 MessageSource。

initApplicationEventMulticaster() 方法
初始化应用的事件广播器 ApplicationEventMulticaster。

onRefresh() 方法
该方法为模板方法,提供给子类扩展实现,可以重写以添加特定于上下文的刷新工作,默认实现为空。

finishBeanFactoryInitialization(beanFactory) 方法
该方法会实例化所有剩余的非懒加载单例 bean。除了一些内部的 bean、实现了 BeanFactoryPostProcessor 接口的 bean、实现了 BeanPostProcessor 接口的 bean,其他的非懒加载单例 bean 都会在这个方法中被实例化,并且 BeanPostProcessor 的触发也是在这个方法中。

finishRefresh() 方法
完成此上下文的刷新,主要是推送上下文刷新完毕事件(ContextRefreshedEvent )到监听器。

总结
上文标红的方法为构建 IoC 构成中最重要的4个方法,简单的描述就是:
obtainFreshBeanFactory 创建一个新的 BeanFactory、读取和解析 bean 定义。
invokeBeanFactoryPostProcessors 提供给开发者对 BeanFactory 进行扩展。
registerBeanPostProcessors 提供给开发者对 bean 进行扩展。
finishBeanFactoryInitialization 实例化剩余的所有非懒加载单例 bean。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值