refresh() 方法简析

本文详细解读Spring框架中IoC控制反转的实现过程,涉及beanFactory构建、BeanPostProcessor、ApplicationContext初始化关键步骤,以及finishBeanFactoryInitialization的核心作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IOC 控制反转_牦牛先生的博客-CSDN博客_ioc控制反转和依赖注入Spring Framework 概述https://blog.csdn.net/centrl/article/details/115519480通过前面的学习,我们至少已经知道 IOC,下面我们就来说说 IOC 是个什么东西。1.写在前面首先来想一件事,作为程序员,怎么开发程序才最巴适?我觉得最起码有两点:开发简单、升级简单。开发简单,就是我们只管写业务逻辑(培养只会写 if-else 的程序员)。升级简单,这里也包含两点:我们使用的技术(可理解为框架)出了什么问...https://blog.csdn.net/centrl/article/details/115523139通过前面的学习,我们只需要进行简单的pojo编写就能实现一个应用程序,剩下的工作都交由 Spring Framework 框架。

框架核心IOC 容器构建的方法是refresh(),我们看看具体都做了什么。

1.refresh() 概览

该方法是 Spring Bean 加载的核心,它是 ClassPathXmlApplicationContext 的父类 AbstractApplicationContext 的一个方法 , 用于刷新整个Spring 上下文信息,定义了整个 Spring 上下文加载的流程。

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
    // 1.准备预处理:记录容器的启动时间startupDate, 标记容器为激活,初始化上下文环境如文件路径信息,验证必填属性是否填写 
    this.prepareRefresh();
    // **2.告诉子类去刷新bean工厂,此方法解析配置文件并将bean信息存储到beanDefinition中,注册到BeanFactory(但是未被初始化,仅将信息写到了beanDefination的map中)**重点方法,下面的操作都基于这个beanFactory进行的
    ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
    // 3.设置beanFactory的基本属性:类加载器,添加多个beanPostProcesser
    this.prepareBeanFactory(beanFactory);
    try {
        // 4.空实现:允许子类上下文中对beanFactory做后期处理
        this.postProcessBeanFactory(beanFactory);
         /**************************以上是BeanFactory的创建及预准备工作  ****************/
        // 5.调用BeanFactoryPostProcessor各个实现类的方法
        this.invokeBeanFactoryPostProcessors(beanFactory);
        //6. 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
         // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
         // 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
        this.registerBeanPostProcessors(beanFactory);
        //7.初始化ApplicationContext的MessageSource组件(资源文件),如国际化文件,消息解析,绑定等
        this.initMessageSource();
        //8.初始化ApplicationContext事件广播器
        this.initApplicationEventMulticaster();
        // 9.初始化子类特殊bean(钩子方法)
        this.onRefresh();
        // 10.获取所有的事件监听器,并将监听器注册到事件广播器
        this.registerListeners();
        //** 11.初始化所有singleton bean;**重点方法
        this.finishBeanFactoryInitialization(beanFactory);
        // 12.广播事件:ApplicationContext初始化完成
        this.finishRefresh();
} catch (BeansException ex) {
	if (logger.isWarnEnabled()) {
	logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex);
	}
		// 销毁bean
		this.destroyBeans();
		// 重置 'active' 标志.
		this.cancelRefresh(ex);
		throw ex;
			}
		}

一共12个方法,按作用简单划分一下:

  • 1 为准备环境
  • 2 3 4 5 6 为准备 BeanFactory
  • 7 8 9 10 12 为准备 ApplicationContext
  • 11 为初始化 BeanFactory 中非延迟单例 bean

2.步骤明细

2.1.prepareRefresh

准备预处理:

  • 记录spring容器的启动时间startupDate,
  • 标记容器为激活,
  • 初始化上下文环境如文件路径信息,
  • 验证必填属性是否填写,
  • 初始化保存事件的集合。
//刷新前的预处理;
protected void prepareRefresh() {
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);
​
    if (logger.isInfoEnabled()) {
        logger.info("Refreshing " + this);
    }
    // 初始化一些属性设置;子类自定义个性化的属性设置方法;
    initPropertySources();   
    // 校验配置文件的属性,合法性
    getEnvironment().validateRequiredProperties();
    // 初始化保存事件的集合
    this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}

2.2.obtainFreshBeanFactory

获取BeanFactory,解析配置文件,生成beanDefinition;

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    // 创建了一个this.beanFactory = new DefaultListableBeanFactory();
    // 设置了序列化的ID
    // 自定义此上下文使用的内部beanFactory
    // 加载beanDefinitions
    refreshBeanFactory();
    // 返回刚才创建的DefaultListableBeanFactory
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (logger.isDebugEnabled()) {
        logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
    }
    return beanFactory;
}

2.3.prepareBeanFactory

该方法主要负责对BeanFactory的预准备工作,配置beanFactory的基础属性,比如ClassLoader和一些PostProcessor等。

  • 设置BeanFactory的类加载器、支持表达式解析器…
  • 添加部分BeanPostProcessor【ApplicationContextAwareProcessor】
  • 设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware、xxx;
  • 注册可以解析的自动装配;我们能直接在任何组件中自动注入:BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
  • 添加BeanPostProcessor【ApplicationListenerDetector】
  • 添加编译时的AspectJ;
  • 给BeanFactory中注册一些能用的组件;
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   	// Tell the internal bean factory to use the context's class loader etc.
     //设置类加载器
   	beanFactory.setBeanClassLoader(getClassLoader());
      //设置bean表达式解析器,详解见下文
   	beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
   	//资源编辑注册器
   	beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

   	//添加一个BeanPostProcessor:ApplicationContextAwareProcessor,用于向实现类ApplitionContextAware中,调用setApplicationContext方法,并将ApplicationContext作为参数。
   	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);
   

   	// 注册几个解析依赖项,意思是,当一个Bean需要注入对应的类时,使用下面注册的这些类
   //比如,如果@Autowire 一个BeanFactory,那么这个BeanFactory实际就是在此处注册的一个对象
   //这几项分别是:BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
   	beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
   	beanFactory.registerResolvableDependency(ResourceLoader.class, this);
   	beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
   	beanFactory.registerResolvableDependency(ApplicationContext.class, this);

   	// Detect a LoadTimeWeaver and prepare for weaving, if found.
   	//检查是否由LoadTimeWeaver,如果有loadTimeWeaver的bean,就放入一个BeanPostProcessor:LoadTimeWeaverAwareProcessor
   	if (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()));
   	}
   	
   	// 注册environment,注册成单例
   	if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
   		beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
   	}
   	 //注册systemProperties 成单例
   	if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
   		beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
   	}
      //注册 systemEnvironment 成单例
   	if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
   		beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
   	}
   }

这里涉及到几个点,BeanPostProcessor、XxxAware、XxxRegistrar,我们在另作讲解。

2.4.postProcessBeanFactory

主要负责在BeanFactory准备工作完成之后,beanFactory的后置处理工作;

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    }

这里使用了设计模式中的模板模式

2.5.invokeBeanFactoryPostProcessors

这一步会调用 beanFactory 后处理器。beanFactory 后处理器,充当 beanFactory 的扩展点,可以用来补充或修改 BeanDefinition。

常见的 beanFactory 后处理器有:

  • ConfigurationClassPostProcessor – 解析 @Configuration、@Bean、@Import、@PropertySource 等
  • PropertySourcesPlaceHolderConfigurer – 替换 BeanDefinition 中的 ${ }
  • MapperScannerConfigurer – 补充 Mapper 接口对应的 BeanDefinition
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    
    //用于存放已处理过的Bean
    Set<String> processedBeans = new HashSet<String>();
    
    //如果IOC容器是一个BeanDefinitionRegistry,有了注册BeanDefinition的能力,就可以执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
    if (beanFactory instanceof BeanDefinitionRegistry) {
        
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        
        //regularPostProcessors用于存放普通的BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> 
            regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
        
        //registryPostProcessors用于存放 BeanDefinitionRegistryPostProcessor
        List<BeanDefinitionRegistryPostProcessor> 
            registryPostProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();
        
        //查询通过addBeanFactoryPostProcessor等方法设置进来的的BeanFactoryPostProcessor(不是注册到IOC容器的中)
        for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {
            
            //如果是 BeanDefinitionRegistryPostProcessor  ,
            //就先执行它的postProcessBeanDefinitionRegistry,用于向IOC中注册一些BeanDefinition,
            //然后添加到registryPostProcessors队列中
          if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryPostProcessor =
                    (BeanDefinitionRegistryPostProcessor) postProcessor;
				  
            	registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
                registryPostProcessors.add(registryPostProcessor);
            }
            else {
                //如果是普通的BeanFactoryPostProcessor,就添加到regularPostProcessors队列中
                regularPostProcessors.add(postProcessor);
            }
        }
        
        //获取IOC容器中注册的BeanDefinitionRegistryPostProcessor,
        //放入到registryPostProcessorBeans中,
        //并按照Order排序
        Map<String, BeanDefinitionRegistryPostProcessor> beanMap =
            beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false);
        
        List<BeanDefinitionRegistryPostProcessor> registryPostProcessorBeans =
            new ArrayList<BeanDefinitionRegistryPostProcessor>(beanMap.values());
       
        OrderComparator.sort(registryPostProcessorBeans);
        
        //先调用registryPostProcessorBeans中的所有postProcessBeanDefinitionRegistry方法
        for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessorBeans) {
            postProcessor.postProcessBeanDefinitionRegistry(registry);
        }
        //先调用 registryPostProcessors中的postProcessBeanFactory方法
        //再调用 registryPostProcessorBeans中的postProcessBeanFactory方法
        //最后调用 regularPostProcessors中的postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(registryPostProcessorBeans, beanFactory);
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        
        //对于IOC容器中注册的BeanDefinitionRegistryPostProcessor来说,还要放置到processedBeans中,放置重复调用
        processedBeans.addAll(beanMap.keySet());
    }
    else {
        //如果IOC就是一个普通的BeanFacotry,就直接从context中取出所有的BeanFactoryPostProcessor,并调用他们的postProcessBeanFactory方法
        // Invoke factory processors registered with the context instance.
        invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory);
    }
	
    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // 查询IOC容器中所有的BeanFactoryPostProcessor,有可能上面的BeanDefinitionRegistryPostProcessor刚刚向IOC容器中注册了一些BeanFactoryPostProcessor,所以要在此处全部查出来。
    String[] postProcessorNames =
        beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

    // 按照 这些BeanFactoryPostProcessor实现的排序接口( PriorityOrdered 和 Ordered)分成3组
    //第一组 实现了PriorityOrdered  --- priorityOrderedPostProcessors
    //第二组 实现了Ordered          --- orderedPostProcessorNames
    //第三组 没有实现排序接口         --- nonOrderedPostProcessorNames
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    List<String> orderedPostProcessorNames = new ArrayList<String>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    
    for (String ppName : postProcessorNames) {
        //如果已经处理了,就跳过
        if (processedBeans.contains(ppName)) {
            // skip - already processed in first phase above
        }
         //实现PriorityOrdered 接口的
        else if (isTypeMatch(ppName, PriorityOrdered.class)) {
           
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }
        // 实现Ordered 接口的
        else if (isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        //普通的
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }
      //然后先执行priorityOrderedPostProcessors中的,再执行orderedPostProcessorNames的,最后执行nonOrderedPostProcessorNames
	
    //排序并执行priorityOrderedPostProcessors的
    OrderComparator.sort(priorityOrderedPostProcessors);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // 排序并执行orderedPostProcessors的
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    OrderComparator.sort(orderedPostProcessors);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

    // 最后执行普通的BeanFactoryPostProcessor的
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
}

2.6.registerBeanPost Processors

这一步是继续从 beanFactory 中找出 bean 后处理器,添加至 beanPostProcessors 集合

bean 后处理器,充当 bean 的扩展点,可以工作在 bean 的实例化、依赖注入、初始化阶段,常见的有:

  • AutowiredAnnotationBeanPostProcessor 功能有:解析 @Autowired,@Value 注解
  • CommonAnnotationBeanPostProcessor 功能有:解析 @Resource,@PostConstruct,@PreDestroy
  • AnnotationAwareAspectJAutoProxyCreator 功能有:为符合切点的目标 bean 自动创建代理
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // 获取IOC中注册的 BeanPostProcessor
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    // BeanPostProcessorChecker 也是一个 BeanPostProcessor,用于检查一个Bean应该经过的BeanPostProcessor和
    
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    //按照排序接口分类。
    //这里需要注意的是,priorityOrderedPostProcessors里面装的是BeanPostProcessor
    //而orderedPostProcessorNames和nonOrderedPostProcessorNames里面装的是BeanPostProcessor的name
    //原因是:实例化BeanPostProcessor实现类的时候,也需要调用IOC中已有的BeanPostProcessor,所以Spring这里没有提前实例化Orderd接口和普通的BeanPostProcessor。
    //因此,这里有一个有趣的现象,示例化Orderd接口的BeanProcessor的时候,会使用PriorityOrdered的BeanPostProcessor进行处理
    //实例化普通的BeanProcessor时,会先后经过PriorityOrdered和Orderd接口的BeanPostProcessor的处理
    
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
    
    List<String> orderedPostProcessorNames = new ArrayList<String>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    
    //分类
    for (String ppName : postProcessorNames) {
        //PriorityOrdered接口的,先行实例化,并把MergedBeanDefinitionPostProcessor放入到internalPostProcessors中
        if (isTypeMatch(ppName, PriorityOrdered.class)) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            //
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        //Ordered接口的,这里只是把name记录下来。
        else if (isTypeMatch(ppName, Ordered.class)) {
            //
            orderedPostProcessorNames.add(ppName);
        }
        //普通的,这里只是把name记录下来。
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    //排序并注册PriorityOrdered接口的BeanPostProcessor
    OrderComparator.sort(priorityOrderedPostProcessors);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    //排序并注册Ordered接口的BeanPostProcessor
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
    for (String ppName : orderedPostProcessorNames) {
        //这里才进行实例化,所以会使用实现了PriorityOrdered接口的BeanPostProcessor进行处理
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        //把MergedBeanDefinitionPostProcessor放入到internalPostProcessors中
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    OrderComparator.sort(orderedPostProcessors);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // 注册普通的BeanPostProcessor
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
    for (String ppName : nonOrderedPostProcessorNames) {
       //这里才进行实例化,所以会使用实现了PriorityOrdered接口或Orderd的BeanPostProcessor进行处理
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
         //把 MergedBeanDefinitionPostProcessor 放入到internalPostProcessors中
        //同时注意到,即使在internalPostProcessors中
        //BeanPostProcessor的顺序也是按照 PriorityOrderd > Orderd > 普通 的顺序进入的。
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    //注册所有的MergedBeanDefinitionPostProcessor
    OrderComparator.sort(internalPostProcessors);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);
	
    //最后,在末尾添加一个ApplicationListenerDetector
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector());
}

2.7.initMessageSource

初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
MessageSource:取出国际化配置文件中的某个key的值;能按照区域信息获取。

protected void initMessageSource() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
        this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
        // Make MessageSource aware of parent MessageSource.
        //如果已经注册了 messageSource && messageSource是HierarchicalMessageSource && messageSource没有parent && 此IOC有parent 
        if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
            HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
            if (hms.getParentMessageSource() == null) {
                // Only set parent context as parent MessageSource if no parent MessageSource
                // registered already.
                hms.setParentMessageSource(getInternalParentMessageSource());
            }
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Using MessageSource [" + this.messageSource + "]");
        }
    }
    //如果没有注册messageSource,就创建一个DelegatingMessageSource,并注册到IOC中
    else {
        // Use empty MessageSource to be able to accept getMessage calls.
        DelegatingMessageSource dms = new DelegatingMessageSource();
        dms.setParentMessageSource(getInternalParentMessageSource());
        this.messageSource = dms;
        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
                         "': using default [" + this.messageSource + "]");
        }
    }
}

2.8.initApplicationEventMulticaster

 这一步为 ApplicationContext 添加事件广播器成员,即 applicationContextEventMulticaster

它的作用是发布事件给监听器。

protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    //如果有开发自定的applicationEventMulticaster实例bean,则设置IOC的事件广播器为该实例
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        this.applicationEventMulticaster =
            beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
        if (logger.isDebugEnabled()) {
            logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    }
    //如果没有applicationEventMulticaster,就设置一个SimpleApplicationEventMulticaster
    else {
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                         APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                         "': using default [" + this.applicationEventMulticaster + "]");
        }
    }
}

2.9.onRefresh

模板设计模式;该方法属于钩子方法;子类重写该方法并在容器刷新的时候自定义逻辑;

protected void onRefresh() throws BeansException {
		// For subclasses: do nothing by default.
}

2.10.registerListeners

注册监听器分为两部分:

  1. 向事件分发器注册硬编码设置的applicationListener
  2. 向事件分发器注册一个IOC中的事件监听器(并不实例化)
protected void registerListeners() {
    // 查出所有通过addApplicationListener方法添加的ApplicationListener,然后注册到事件广播器上
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // 查出ioc容器中的所有ApplicationListener,只把他们注册到事件分发器的ApplicationListenerBean上,
    // 待使用时再进行实例化
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }
}

2.11.finishBeanFactoryInitialization

finishBeanFactoryInitialization主要是负责初始化单实例的bean;该方法是重点方法,bean的生命周期基本调用getBean()方法完成。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    //如果IOC中有conversionService的话,就实例化并设置到IOC中
    //conversionService用于类型转换
    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));
    }
    // 如果有LoadTimeWeaverAware,就实例化
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }
    // 清理临时的classLoader
    beanFactory.setTempClassLoader(null);
    // 缓存所有beanDefinition的name,以备不时之需
    beanFactory.freezeConfiguration();
    // 实例化所有非non-lazy-init的单例
    beanFactory.preInstantiateSingletons();
}

2.12.finishRefresh

完成bean创建和初始化过程,通知生命周期处理器 lifecycleProcessor 刷新过程,同时发出 ContextRefreshEvent 通知。

protected void finishRefresh() {
    // 实例化或初始化lifecycleProcessor
    initLifecycleProcessor();
    // 调用lifecycleProcessor的刷新方法
    getLifecycleProcessor().onRefresh();
    //发布一个ContextRefreshedEvent事件
    publishEvent(new ContextRefreshedEvent(this));
    // 注册MBean,用于JMX管理
    LiveBeansView.registerApplicationContext(this);
}

<think>我们正在讨论Spring框架中的`refresh()`方法。根据用户的问题,我们需要解释`refresh()`方法的用途和使用方式。首先,我们需要明确`refresh()`方法Spring框架中的位置和作用。 在Spring框架中,`refresh()`方法是`AbstractApplicationContext`类中的一个核心方法。该方法负责初始化或刷新Spring应用上下文,加载或重新加载配置信息,并创建和管理Bean的生命周期。 ### 用途 1. **初始化应用上下文**:当应用上下文创建后,调用`refresh()`方法会初始化所有的单例Bean,并完成依赖注入。 2. **重新加载配置**:在已经存在的应用上下文中,调用`refresh()`方法可以重新加载配置(例如,修改了配置文件后),并重新初始化Bean。 3. **启动和停止**:该方法还会触发生命周期处理器(Lifecycle Processor)的启动,以及注册的Shutdown Hook。 ### 使用方式 通常,我们不会直接调用`refresh()`方法,因为在使用应用上下文(如`ClassPathXmlApplicationContext`或`AnnotationConfigApplicationContext`)时,构造方法内部已经调用了`refresh()`方法。但是,在某些情况下,比如需要重新加载配置时,我们可以显式调用。 #### 示例代码 ```java // 创建应用上下文 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(AppConfig.class); // 调用refresh方法初始化 context.refresh(); // 使用上下文获取Bean MyService myService = context.getBean(MyService.class); // 如果需要重新加载(例如,在外部配置变更后) context.refresh(); // 注意:再次调用refresh()会销毁所有已创建的Bean并重新初始化 // 关闭上下文 context.close(); ``` ### 注意事项 - 多次调用`refresh()`方法会导致之前创建的Bean被销毁,然后重新创建。因此,需要谨慎使用,以避免资源浪费和状态丢失。 - 在调用`refresh()`之前,必须注册配置类或XML配置位置。 - 调用`refresh()`后,应用上下文处于活动状态,可以获取Bean。使用完毕后,应调用`close()`方法关闭上下文以释放资源。 ### 内部流程 `refresh()`方法内部执行多个步骤,包括: 1. 准备刷新(Prepare refresh):初始化上下文环境,验证必要的属性等。 2. 获取新的BeanFactory(Obtain fresh bean factory):创建或刷新内部的BeanFactory。 3. 准备BeanFactory(Prepare the bean factory):配置BeanFactory的标准上下文特性(如类加载器、后置处理器等)。 4. 后置处理BeanFactory(Post-process the bean factory):允许在Bean加载前对BeanFactory进行修改(通过子类实现)。 5. 调用BeanFactory的后置处理器(Invoke bean factory post processors):处理BeanFactoryPostProcessor,用于修改Bean定义。 6. 注册Bean的后置处理器(Register bean post processors):注册BeanPostProcessor,用于在Bean创建过程中进行拦截处理。 7. 初始化消息源(Initialize message source):用于国际化。 8. 初始化事件广播器(Initialize event multicaster):用于事件发布。 9. 初始化其他特殊的Bean(On refresh):由子类实现,用于初始化特定的Bean。 10. 注册监听器(Register listeners):注册事件监听器。 11. 完成BeanFactory的初始化(Finish bean factory initialization):初始化所有剩余的单例Bean(非延迟初始化)。 12. 完成刷新(Finish refresh):发布ContextRefreshedEvent事件,完成刷新过程。 ### 引用说明 在Spring框架中,`refresh()`方法是应用上下文初始化的核心方法,它定义在`AbstractApplicationContext`类中[^2]。另外,在初始化消息源时,我们可以配置`ResourceBundleMessageSource`来支持国际化[^1]。 §§相关问题§§ 1. `refresh()`方法Spring框架中定义在哪个类中? 2. 调用`refresh()`方法多次会有什么后果? 3. 在`refresh()`方法执行过程中,哪些步骤允许开发者进行扩展? 4. 如何监听Spring上下文刷新完成的事件?</think>### Spring框架中`refresh()`方法的用途及使用方式 `refresh()`方法Spring框架中**应用上下文(ApplicationContext)初始化的核心方法**,定义在`AbstractApplicationContext`类中[^2]。其主要用途和执行流程如下: #### 一、核心用途 1. **初始化应用上下文** 加载配置元数据(XML/注解/Java Config),创建并管理Bean实例,完成依赖注入(DI)和生命周期管理。 2. **刷新内部状态** 重新加载配置(如热部署场景),销毁旧Bean并创建新实例,更新应用状态。 3. **启动扩展点** 触发`BeanFactoryPostProcessor`(修改Bean定义)、`BeanPostProcessor`(拦截Bean初始化)等扩展机制。 4. **发布事件** 完成刷新后发布`ContextRefreshedEvent`事件,通知监听器(如启动定时任务)。 #### 二、使用方式 ##### 1. 显式调用场景 ```java // 创建应用上下文(默认未刷新) AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class); // 注册配置类 ctx.refresh(); // 关键:触发初始化流程 // 重新加载配置(如配置文件更新后) ctx.refresh(); // 销毁旧Bean,重建新实例 ``` ##### 2. 隐式调用场景 ```java // 常用上下文实现类会在构造函数中自动调用refresh() ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); // 内部已调用refresh ``` #### 三、执行流程(关键步骤) ```mermaid graph TD A[开始refresh] --> B[准备刷新<br>Prepare Refresh] B --> C[初始化BeanFactory<br>Obtain Fresh BeanFactory] C --> D[配置BeanFactory<br>Prepare BeanFactory] D --> E[执行BeanFactory后处理器<br>PostProcessBeanFactory] E --> F[注册Bean后处理器<br>RegisterBeanPostProcessors] F --> G[初始化消息源<br>InitMessageSource] G --> H[初始化事件广播器<br>InitApplicationEventMulticaster] H --> I[子类扩展点<br>onRefresh] I --> J[注册监听器<br>RegisterListeners] J --> K[实例化单例Bean<br>FinishBeanFactoryInitialization] K --> L[完成刷新<br>FinishRefresh] L --> M[发布ContextRefreshedEvent] ``` #### 四、注意事项 1. **单次上下文生命周期** 通常只调用一次`refresh()`,多次调用需配合`close()`释放资源。 2. **资源管理** 调用`refresh()`后必须显式调用`close()`(或在try-with-resources中)避免内存泄漏。 3. **线程安全** 非线程安全方法,需在完全初始化的上下文中调用。 #### 五、典型应用场景 - **热部署**:动态重载配置时调用`refresh()` - **测试环境**:在单元测试中手动控制上下文生命周期 - **自定义扩展**:通过覆盖`onRefresh()`实现容器扩展[^2] > 引用说明: > [^1] 消息源初始化在`refresh()`流程中通过`ResourceBundleMessageSource`实现国际化支持。 > [^2] `refresh()`方法定义在`AbstractApplicationContext`中,是上下文初始化的核心入口。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值