千家信息网

spring扩展启动流程refresh详解

发表于:2025-12-04 作者:千家信息网编辑
千家信息网最后更新 2025年12月04日,本篇内容介绍了"spring扩展启动流程refresh详解"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所
千家信息网最后更新 2025年12月04日spring扩展启动流程refresh详解

本篇内容介绍了"spring扩展启动流程refresh详解"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

spring扩展启动流程-refresh

XmlWebApplicationContext

在spring-webmvc启动流程中,我们在对wac的刷新过程并没有详细的解释,只是一笔带过。

不管是从ContextLoaderListener进入的,还是Servlet的init方法进入的,都离不开spring整体的初始化。仅仅有bean的读取,加载的spring是不完整的,spring还需要这些扩展的部分,让spring更完善,先来看看入口吧。

// ContextLoader.javaprotected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {        //...        wac.refresh();}
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {                //...                wac.refresh();}

refresh

refresh函数中几乎包含了ApplicationContext提供的所有功能,而且此函数中的逻辑很清楚,瞅一下吧。

调试可以直接从ClassPathXmlApplicationContext这个类驶入,构造方法直接就能驶入这个方法,并初始化完成整个环境。

// AbstractApplicationContext.javapublic void refresh() throws BeansException, IllegalStateException {   synchronized (this.startupShutdownMonitor) {      // Prepare this context for refreshing.      // 准备刷新的上下文环境      prepareRefresh();             // Tell the subclass to refresh the internal bean factory.      // 初始化BeanFactory,并进行xml文件读取      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();             // Prepare the bean factory for use in this context.      // 对BeanFactory进行各种功能填充      prepareBeanFactory(beanFactory);      try {         // Allows post-processing of the bean factory in context subclasses.         // 子类覆盖做额外的处理         postProcessBeanFactory(beanFactory);         // Invoke factory processors registered as beans in the context.         // 激活各种BeanFactory处理器         invokeBeanFactoryPostProcessors(beanFactory);         // Register bean processors that intercept bean creation.         // 注册拦截Bean创建的Bean处理器,这里只是注册,调用是在getBean的时候         registerBeanPostProcessors(beanFactory);         // Initialize message source for this context.         // 为上下文初始化Message源,即不同语言的消息体,国际化处理         initMessageSource();         // Initialize event multicaster for this context.         // 初始化应用消息广播器,并放入"ApplicationEventMulticaster" Bean中          initApplicationEventMulticaster();         // Initialize other special beans in specific context subclasses.         // 留给子类来初始化其他的Bean         onRefresh();         // Check for listener beans and register them.         // 在所有注册的Bean中查找Listenter bean,注册到消息广播器中         registerListeners();         // Instantiate all remaining (non-lazy-init) singletons.         //初始化剩下的单例(非惰性)         finishBeanFactoryInitialization(beanFactory);         // Last step: publish corresponding event.         // 完成刷新过程,通知生命周期处理器lifecycleProcessor完成刷新过程,同时发出ContextRefreshEvent通知别人         finishRefresh();      }      catch (BeansException ex) {         // Destroy already created singletons to avoid dangling resources.         destroyBeans();         // Reset 'active' flag.         cancelRefresh(ex);         // Propagate exception to caller.         throw ex;      }   }}

prepareRefresh

//AbstractApplicationContext.javaprotected void prepareRefresh() {    //...    //留给子类覆盖    initPropertySources();    //属性文件验证,确保需要的文件都已经放入环境中    getEnvironment().validateRequiredProperties();    //...}

obtainFreshBeanFactory

初始化BeanFactory,对xml文件的读取,就是从这个地方开始的,使用的是默认的DefaultListableBeanFactory。

//AbstractApplicationContext.javaprotected ConfigurableListableBeanFactory obtainFreshBeanFactory() {    //初始化BeanFactory        refreshBeanFactory();    //返回初始化之后的BeanFactory        return getBeanFactory();}
//AbstractRefreshableApplicationContext.javaprotected final void refreshBeanFactory() throws BeansException {    //检查是否已经有了初始化的BeanFactory    if (hasBeanFactory()) {        //销毁所有的bean        destroyBeans();        //关闭并销毁BeanFactory        closeBeanFactory();    }    try {        //创建默认的DefaultListableBeanFactory,子类可以覆盖该方法        DefaultListableBeanFactory beanFactory = createBeanFactory();        beanFactory.setSerializationId(getId());        //定制BeanFactory,包括是否允许覆盖同名称的不同定义的对象以及循环依赖        customizeBeanFactory(beanFactory);        //初始化XmlBeanDefinitionReader,并进行xml文件的解析。        loadBeanDefinitions(beanFactory);        synchronized (this.beanFactoryMonitor) {            this.beanFactory = beanFactory;        }    }    catch (IOException ex) {...}}protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {    //设置是否允许同名不同定义的bean覆盖    if (this.allowBeanDefinitionOverriding != null) {        beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);    }    //设置是否允许循环依赖    if (this.allowCircularReferences != null) {        beanFactory.setAllowCircularReferences(this.allowCircularReferences);    }}

prepareBeanFactory

至此,spring已经完成了对配置的解析,ApplicationContext在功能上的扩展也由此开始。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {    beanFactory.setBeanClassLoader(getClassLoader());    //设置表达式语言处理器    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));    //设置一个默认的属性解析器PropertyEditor    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));    //添加BeanPostProcessor    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));    //设置几个忽略自动装配的接口    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);    //注册依赖解析,也是spring的bean,但是会特殊一些,下边会有解释    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);    beanFactory.registerResolvableDependency(ResourceLoader.class, this);    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);    beanFactory.registerResolvableDependency(ApplicationContext.class, this);    //添加BeanPostProcessor    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));    //增加对AspectJ的支持    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));    }    //添加默认的系统环境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());    }}
主要扩展:1. 增加对SPEL语言的支持;2. 增加对属性编辑器的支持,这些PropertyEditors在这里只是注册,使用的时候是将bean包装成BeanWrapper,包装后的BeanWrapper的就包含了所有的这些PropertyEditors,以便后期给bean设置属性的时候使用;3. 增加对一些内置类(实际上就是前置处理器),比如Aware接口的信息注入;4. 设置依赖功能可忽略的接口;5. 注册一些固定的bean,这些都是特殊的依赖解析,比如当注册了BeanFactory.class的依赖解析之后,当bean的属性注入的时候,一旦检测到属性为BeanFactory类型便会将beanFactory的实例注入进去;6. 增加对AspectJ的支持;7. 将相关环境变量及属性以单例模式注册。

invokeBeanFactoryPostProcessors

激活注册的BeanFactoryPostProcessor。这个接口跟BeanPostProcessor类似,可以对bean的定义(配置元数据)进行处理,作用范围是容器级的,只对自己的容器的bean进行处理。典型应用PropertyPlaceholderConfigurer。

这部分代码有点长,不贴了,自己去看吧。

registerBeanPostProcessors

注册所有的bean前后置处理器BeanPostProcessor,这里只是注册,调用是在bean创建的时候。

代码也有点长,不贴了,自己去看吧~~

initMessageSource

国际化处理,如果想使用自定义的,bean name是指定了的MESSAGE_SOURCE_BEAN_NAME = "messageSource"。

protected void initMessageSource() {    ConfigurableListableBeanFactory beanFactory = getBeanFactory();    //根据指定的名称查找messageSource,如果容器中注册了指定名称的messageSource,就使用注册的    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {        this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);        if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {            HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;            if (hms.getParentMessageSource() == null) {                hms.setParentMessageSource(getInternalParentMessageSource());            }        }        //...日志    }    else {        //容器中没有注册指定名称的messageSource,使用默认的DelegatingMessageSource        DelegatingMessageSource dms = new DelegatingMessageSource();        dms.setParentMessageSource(getInternalParentMessageSource());        this.messageSource = dms;        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);        //...日志    }}

initApplicationEventMulticaster

初始化应用的事件广播器,用于事件监听,逻辑跟初始化国际化MessageSource是一样的,也是有一个特定的名称。如果beanFactory有就是用注册的,如果没有就是用默认的SimpleApplicationEventMulticaster。

应用中的listener都是注册到这个广播器,由广播器统一广播的。

registerListeners

在所有注册的Bean中查找Listenter bean,注册到消息广播器中。

protected void registerListeners() {    // 首先注册静态注册的监听器(代码注册的)    for (ApplicationListener listener : getApplicationListeners()) {        getApplicationEventMulticaster().addApplicationListener(listener);    }    // 获取容器中所有配置的listener并注册    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);    for (String listenerBeanName : listenerBeanNames) {        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);    }    // 对earlyApplicationEvents这些事件进行广播,实际上就是遍历所有的listener,找到可以处理event的listener处理    Set earlyEventsToProcess = this.earlyApplicationEvents;    this.earlyApplicationEvents = null;    if (earlyEventsToProcess != null) {        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {            getApplicationEventMulticaster().multicastEvent(earlyEvent);        }    }}

finishBeanFactoryInitialization

初始化剩下的非惰性单例,如果某个单例依赖了惰性的单例,那么这个惰性的单例也会被初始化,这个很好理解吧。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {    // 初始化ConversionService,跟PropertyEditor类似    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&            beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {        beanFactory.setConversionService(                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));    }    //则注册默认的嵌入值解析器    //例如PropertyPlaceholderConfigurer bean)之前注册过:    //主要用于注解属性值的解析。    if (!beanFactory.hasEmbeddedValueResolver()) {        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));    }    //单例bean初始化之前首先初始化LoadTimeWeaverAware,以支持aop,AspectJ    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);    for (String weaverAwareName : weaverAwareNames) {        getBean(weaverAwareName);    }    beanFactory.setTempClassLoader(null);    //冻结bean定义(BeanDefinition),表示所有的bean定义进不被修改或进行进一步处理    beanFactory.freezeConfiguration();    //初始化非惰性单例,实际上就是遍历所有的beanName,然后一一调用getBean()    beanFactory.preInstantiateSingletons();}

finishRefresh

protected void finishRefresh() {    //清除上下文级别(context-level)的资源缓存,比如由scanning产生的ASM元数据    clearResourceCaches();    //初始化LifecycleProcessor    initLifecycleProcessor();    //使用LifecycleProcessor来启动Lifecycle子类    getLifecycleProcessor().onRefresh();    //上下文刷新完成,发布事件    publishEvent(new ContextRefreshedEvent(this));    // Participate in LiveBeansView MBean, if active.    LiveBeansView.registerApplicationContext(this);}

初始化LifecycleProcessor的时候,跟初始化MessageResource一样,没有自定义的就是用默认的DefaultLifecycleProcessor。

getLifecycleProcessor().onRefresh()会使用我们注册的LyfecycleProcessor来启动我们注册的SmartLifeCycle的子类。看一下代码吧。

//默认的DefaultLifecycleProcessor.javapublic void onRefresh() {    startBeans(true);    this.running = true;}private void startBeans(boolean autoStartupOnly) {    //获取所有的LifeCycle类型的bean    Map lifecycleBeans = getLifecycleBeans();    Map phases = new HashMap<>();    lifecycleBeans.forEach((beanName, bean) -> {        //默认的DefaultLifecycleProcessor只会启动SmartLifecycle的,或者非自动启动的类型        //SmartLifecycle继承了Phases接口        if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {            int phase = getPhase(bean);            LifecycleGroup group = phases.get(phase);            if (group == null) {                group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);                //添加到需要启动的集合中                phases.put(phase, group);            }            group.add(beanName, bean);        }    });    //启动需要启动的这些LifeCycle    if (!phases.isEmpty()) {        List keys = new ArrayList<>(phases.keySet());        Collections.sort(keys);        for (Integer key : keys) {            phases.get(key).start();        }    }}

"spring扩展启动流程refresh详解"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

处理 属性 广播 处理器 子类 就是 时候 名称 容器 惰性 接口 文件 环境 支持 流程 上下 上下文 事件 代码 功能 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 帝国神话服务器管理器下载 软件开发项目绩效考核标准 亚马逊怎么查行业数据库 网络技术与传统节日文化案例 深圳python软件开发有用吗 内部员工导致网络安全事故 鹰潭租房软件开发 保密局开展网络安全检查 win10的服务器管理角色 红讯软件开发 有关计算机网络安全的应用 阿里云云数据库polardb 保定翰阁领行软件开发 富文本编辑器数据库字段 青浦区推广网络技术要多少钱 数据库口令安全保存 软件开发项目管理包括哪些内容 云计算需要软件开发吗 网络安全环境2021严峻 共同维护网络安全和秩序 dsp 网络安全 福建企业软件开发咨询热线 服务器上传失败请稍后重试 软件开发自我介绍英文带翻译 网上注册服务器多少钱 vs窗口中如何刷新数据库 edr网络安全是什么的缩写 思源计算机网络技术 空间数据库与传统数据库的优点 王牌战士怎么改服务器名字
0