refresh() -> registerBeanPostProcessors()

文章详细介绍了Spring框架中BeanPostProcessor接口的作用,包括Bean的初始化前后处理、销毁处理、类型合并、实例化处理以及循环依赖解决。还提到了registerBeanPostProcessors方法的实现,它如何注册和排序各种类型的BeanPostProcessor。

refresh() -> registerBeanPostProcessors()

注册Bean处理器(BeanPostProcessor),这里只是注册功能,真正调用的是getBean()方法

BeanPostProcessor

public interface BeanPostProcessor {
	/**
	 * 初始化方法调用前要进行的处理逻辑
	 */
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
	/**
	 * 在初始化方法指定后要进行的处理逻辑
	 */
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
}

常用的4个BeanPostProcessor接口

在这里插入图片描述

1.DestructionAwareBeanPostProcessor

Bean被销毁前都会调用到postProcessBeforeDestruction()

public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
	/**
	 * 在bean被销毁前调用
	 */
	void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;

	/**
	 * 判断是否要进行销毁,一般情况下都需要
	 */
	default boolean requiresDestruction(Object bean) {
		return true;
	}
}

2.MergedBeanDefinitionPostProcessor

合并父类和子类信息

public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
   /**
    *spring通过此方法找出所有需要注入的字段,同时做缓存
    */
   void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
   /**
    * 用于在BeanDefinition被修改后,清除容器的缓存
    */
   default void resetBeanDefinition(String beanName) {
   }
}

3.InstantiationAwareBeanPostProcessor

实例化前后的处理工作

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
	/**
	 * 在bean实例化之前调用
	 */
	@Nullable
	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}
	/**
	 * 在bean实例化之后调用
	 */
	default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		return true;
	}
	/**
	 * 当使用注解的时候,通过这个方法来完成属性的注入
	 */
	@Nullable
	default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
			throws BeansException {
		return null;
	}
	/**
	 * 属性注入后执行的方法,在5.1版本被废弃
	 */
	@Deprecated
	@Nullable
	default PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
		return pvs;
	}

}

4.SmartInstantiationAwareBeanPostProcessor

解决循环依赖

public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
	/**
	 * 预测bean的类型,主要是在bean还没有创建前我们需要获取bean的类型
	 */
	@Nullable
	default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}
	/**
	 * 完成对构造函数的解析和推断
	 */
	@Nullable
	default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
			throws BeansException {

		return null;
	}
	/**
	 * 解决循环依赖问题,通过此方法提前暴露一个合格的对象
	 */
	default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

registerBeanPostProcessors()

实例化并且注册所有的beanPostProcessor

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

PostProcessorRegistrationDelegate.registerBeanPostProcessors()

此方法的实现方式与PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()方法处理逻辑相似

public static void registerBeanPostProcessors(
  ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

  // 找到所有实现了BeanPostProcessor接口的类
  String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

  // Register BeanPostProcessorChecker that logs an info message when
  // a bean is created during BeanPostProcessor instantiation, i.e. when
  // a bean is not eligible for getting processed by all BeanPostProcessors.
  // 记录下BeanPostProcessor的目标计数
  // 此处为什么要+1呢,原因非常简单,在此方法的最后会添加一个BeanPostProcessorChecker的类
  int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
  // 添加BeanPostProcessorChecker(主要用于记录信息)到beanFactory中
  beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

  // Separate between BeanPostProcessors that implement PriorityOrdered,
  // Ordered, and the rest.
  // 定义存放实现了PriorityOrdered接口的BeanPostProcessor集合
  List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
  // 定义存放spring内部的BeanPostProcessor
  List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
  // 定义存放实现了Ordered接口的BeanPostProcessor的name集合
  List<String> orderedPostProcessorNames = new ArrayList<>();
  // 定义存放普通的BeanPostProcessor的name集合
  List<String> nonOrderedPostProcessorNames = new ArrayList<>();
  // 遍历beanFactory中存在的BeanPostProcessor的集合postProcessorNames,
  for (String ppName : postProcessorNames) {
    // 如果ppName对应的BeanPostProcessor实例实现了PriorityOrdered接口,则获取到ppName对应的BeanPostProcessor的实例添加到priorityOrderedPostProcessors中
    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      priorityOrderedPostProcessors.add(pp);
      // 如果ppName对应的BeanPostProcessor实例也实现了MergedBeanDefinitionPostProcessor接口,那么则将ppName对应的bean实例添加到internalPostProcessors中
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
        internalPostProcessors.add(pp);
      }
    }
    // 如果ppName对应的BeanPostProcessor实例没有实现PriorityOrdered接口,但是实现了Ordered接口,那么将ppName对应的bean实例添加到orderedPostProcessorNames中
    else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
      orderedPostProcessorNames.add(ppName);
    } else {
      // 否则将ppName添加到nonOrderedPostProcessorNames中
      nonOrderedPostProcessorNames.add(ppName);
    }
  }

  // First, register the BeanPostProcessors that implement PriorityOrdered.
  // 首先,对实现了PriorityOrdered接口的BeanPostProcessor实例进行排序操作
  sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
  // 注册实现了PriorityOrdered接口的BeanPostProcessor实例添加到beanFactory中
  registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

  // Next, register the BeanPostProcessors that implement Ordered.
  // 注册所有实现Ordered的beanPostProcessor
  List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
  for (String ppName : orderedPostProcessorNames) {
    // 根据ppName找到对应的BeanPostProcessor实例对象
    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    // 将实现了Ordered接口的BeanPostProcessor添加到orderedPostProcessors集合中
    orderedPostProcessors.add(pp);
    // 如果ppName对应的BeanPostProcessor实例也实现了MergedBeanDefinitionPostProcessor接口,那么则将ppName对应的bean实例添加到internalPostProcessors中
    if (pp instanceof MergedBeanDefinitionPostProcessor) {
      internalPostProcessors.add(pp);
    }
  }
  // 对实现了Ordered接口的BeanPostProcessor进行排序操作
  sortPostProcessors(orderedPostProcessors, beanFactory);
  //  注册实现了Ordered接口的BeanPostProcessor实例添加到beanFactory中
  registerBeanPostProcessors(beanFactory, orderedPostProcessors);

  // Now, register all regular BeanPostProcessors.
  // 创建存放没有实现PriorityOrdered和Ordered接口的BeanPostProcessor的集合
  List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
  // 遍历集合
  for (String ppName : nonOrderedPostProcessorNames) {
    // 根据ppName找到对应的BeanPostProcessor实例对象
    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    // 将没有实现PriorityOrdered和Ordered接口的BeanPostProcessor添加到nonOrderedPostProcessors集合中
    nonOrderedPostProcessors.add(pp);
    // 如果ppName对应的BeanPostProcessor实例也实现了MergedBeanDefinitionPostProcessor接口,那么则将ppName对应的bean实例添加到internalPostProcessors中
    if (pp instanceof MergedBeanDefinitionPostProcessor) {
      internalPostProcessors.add(pp);
    }
  }
  //  注册没有实现PriorityOrdered和Ordered的BeanPostProcessor实例添加到beanFactory中
  registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

  // Finally, re-register all internal BeanPostProcessors.
  // 将所有实现了MergedBeanDefinitionPostProcessor类型的BeanPostProcessor进行排序操作
  sortPostProcessors(internalPostProcessors, beanFactory);
  // 注册所有实现了MergedBeanDefinitionPostProcessor类型的BeanPostProcessor到beanFactory中
  registerBeanPostProcessors(beanFactory, internalPostProcessors);

  // Re-register post-processor for detecting inner beans as ApplicationListeners,
  // moving it to the end of the processor chain (for picking up proxies etc).
  // 注册ApplicationListenerDetector到beanFactory中
  beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

ApplicationListenerDetector监听器为什么会重新添加一次prepareBeanFactory()方法中已经注册过一次

为了能重新使其存在于集合的最后,方便在进行处理的时候来进行相关的一些检测工作

springbooy使用shardingsphere_driud报错日子如下 Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2025-08-11 10:31:45 - Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.apache.shardingsphere.spring.boot.ShardingSphereAutoConfiguration': Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/apache/tomcat/dbcp/dbcp2/BasicDataSource at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:602) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:409) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1341) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1181) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:556) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207) at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:229) at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:723) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:536) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:755) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:402) at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1247) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1236) at com.ahcoder.taskone.TaskOneApplication.main(TaskOneApplication.java:29) Caused by: java.lang.NoClassDefFoundError: org/apache/tomcat/dbcp/dbcp2/BasicDataSource at org.apache.shardingsphere.infra.datasource.pool.metadata.type.dbcp.TomcatDBCPDataSourcePoolMetaData.getType(TomcatDBCPDataSourcePoolMetaData.java:67) at org.apache.shardingsphere.spi.typed.TypedSPIRegistry.lambda$findRegisteredService$0(TypedSPIRegistry.java:44) at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174) at java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1359) at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126) at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464) at org.apache.shardingsphere.spi.typed.TypedSPIRegistry.findRegisteredService(TypedSPIRegistry.java:44) at org.apache.shardingsphere.infra.datasource.pool.metadata.DataSourcePoolMetaDataFactory.newInstance(DataSourcePoolMetaDataFactory.java:46) at org.apache.shardingsphere.infra.datasource.props.DataSourceProperties.<init>(DataSourceProperties.java:53) at org.apache.shardingsphere.spring.boot.datasource.DataSourceMapSetter.getDataSource(DataSourceMapSetter.java:92) at org.apache.shardingsphere.spring.boot.datasource.DataSourceMapSetter.getDataSourceMap(DataSourceMapSetter.java:65) at org.apache.shardingsphere.spring.boot.ShardingSphereAutoConfiguration.setEnvironment(ShardingSphereAutoConfiguration.java:122) at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:108) at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:100) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:415) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1791) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594) ... 25 common frames omitted Caused by: java.lang.ClassNotFoundException: org.apache.tomcat.dbcp.dbcp2.BasicDataSource at java.net.URLClassLoader.findClass(URLClassLoader.java:382) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 47 common frames omitted yml配置文件如下 spring: application: name: task-one # ShardingSphere配置 shardingsphere: mode: type: Standalone # 单机模式 datasource: names: ds-base,ds-2023,ds-2024 default-data-source-name: ds-base # 默认数据源 ds-base: data-source-class-name: com.alibaba.druid.pool.DruidDataSource type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/practice?useSSL=false&serverTimezone=UTC username: root password: 123456 ds-2023: data-source-class-name: com.alibaba.druid.pool.DruidDataSource type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/crm_2023?useSSL=false&serverTimezone=UTC username: root password: 123456 ds-2024: data-source-class-name: com.alibaba.druid.pool.DruidDataSource type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/crm_2024?useSSL=false&serverTimezone=UTC username: root password: 123456 # 分片规则配置 rules: sharding: # 配置分表 tables: # 表名(逻辑表) product_history: # 实际数据节点,格式:数据源名.表名(多个用逗号分隔,这里使用表达式表示多个) actual-data-nodes: ds-$->{2023..2024}.product_history_$->{1..12} # 分库策略 database-strategy: standard: sharding-column: id sharding-algorithm-name: database-inline # 分表策略 table-strategy: standard: sharding-column: id sharding-algorithm-name: table-inline # 分布式主键生成策略 key-generate-strategy: column: id key-generator-name: snowflake # 分片算法配置 sharding-algorithms: database-inline: type: INLINE props: algorithm-expression: ds-$->{id % 3} # 分库规则:按user_id取模,分到3个库 table-inline: type: INLINE props: algorithm-expression: product_history_$->{id % 2} # 分表规则:按user_id取模,分到2个表 # 分布式序列算法配置(雪花算法) key-generators: snowflake: type: SNOWFLAKE props: worker-id: 123 # 其他属性 props: sql-show: true # 打印SQL pom文件如下 <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.8</version> </dependency> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId> <version>5.1.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
08-12
<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`中,是上下文初始化的核心入口。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值