参考
https://blog.csdn.net/qq_44836294/article/details/107794445
入口
AbstractApplicationContext:refresh()
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备好刷新上下文
prepareRefresh();
// 告诉子类刷新内部bean工厂 IOC 加载定位注册bean到beanDefinitionMap中
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备bean工厂,以便在此上下文中使用
prepareBeanFactory(beanFactory);
try {
//可算作DI开始
// 允许在上下文子类中对bean工厂进行后处理(例如 继承Aware)
// 1.添加后处理器、忽略依赖接口
// 2.注册web应用的scopes
// 3.注册和环境有关的beans 参考https://www.cnblogs.com/feng-jq/p/10282260.html
postProcessBeanFactory(beanFactory);
// 调用上下文中注册为bean的工厂处理器(实现BeanFactoryPostProcessor接口的postProcessBeanFactory()方法,来对生成好的beanDefinition做处理操作)
invokeBeanFactoryPostProcessors(beanFactory);
// 开始实例化bean
// 注册拦截bean创建的bean处理器(实现BeanPostProcessor接口的before,after方法,对BeanFactory的实例化,注册后置拦截器,当getBean()的时候,触发before,after方法)
registerBeanPostProcessors(beanFactory);
// 初始化此上下文的消息源(国际化)
initMessageSource();
// 初始化此上下文的事件多播器
initApplicationEventMulticaster();
// 在特定上下文子类中初始化其他特殊bean
onRefresh();
// 检查侦听器bean并注册它们
registerListeners();
// 实例化所有剩余的(非惰性初始化)单例,这里完成DI及三级缓存
// 三级缓存 https://blog.csdn.net/qq_43516647/article/details/122682677
finishBeanFactoryInitialization(beanFactory);
// 最后一步:发布相应的事件
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已经创建的单例,以避免挂起资源。
destroyBeans();
// 重置“活跃”的旗帜。
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// 重置Spring核心中的公共内省缓存,因为我们可能再也不需要单例bean的元数据了……
resetCommonCaches();
}
}
}
postProcessBeanFactory方法的使用示例
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("调用MyBeanFactoryPostProcessor的postProcessBeanFactory");
BeanDefinition bd = beanFactory.getBeanDefinition("myJavaBean");
System.out.println("属性值============" + bd.getPropertyValues().toString());
MutablePropertyValues pv = bd.getPropertyValues();
if (pv.contains("remark")) {
pv.addPropertyValue("remark", "把备注信息修改一下");
}
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
}
}