prepareRefresh()
obtainFreshBeanFactory()
prepareBeanFactory()
postProcessBeanFactory()
首先,从这个AnnotationConfigApplicationContext这个类的构造函数中的refresh()方法会去执行其父类(GenericApplicationContext)的父类(AbstractApplicationContext)中的refresh()方法,因为AnnotationConfigApplicationContext这个类是不存在这个方法,是继承父类的方法。
public AnnotationConfigApplicationContext(Class>... componentClasses) {
this();
register(componentClasses);
// 前面两个方法在上一篇博文已经做好笔记了 这篇博文主要说的是refresh()刷新方法
refresh();
}
从这个刷新方法可以数的出来在try语句块中有12个方法,而catch语句块中有1个方法,finally语句块中有1个方法。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 刷新上下文
prepareRefresh();
// 告诉子类刷新内部 Bean工厂
// 在这个方法中主要是获取 DefaultListableBeanFactory 这个Bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备Bean工厂以便在此上下文中使用
prepareBeanFactory(beanFactory);
try {
// 允许在上下文子类中对bean工厂进行后处理
postProcessBeanFactory(beanFactory);
// 这篇博文主要先记录前四个步骤
// 调用在上下文中注册为bean的工厂处理器(重要)
invokeBeanFactoryPostProcessors(beanFactory);
// 注册拦截bean创建的bean处理器
registerBeanPostProcessors(beanFactory);
// 初始化此上下文的消息源
initMessageSource();
// 初始化此上下文的事件多播
initApplicationEventMulticaster();
// 初始化特定上下文子类中的其他特殊bean
onRefresh();
// 检查侦听器bean并注册它们
registerListeners();
// 实例化所有剩余的(非惰性初始化)单例 重要
finishBeanFactoryInitialization(beanFactory);
// 最后一步:发布相应的事件
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已创建的singleton以避免挂起资源
destroyBeans();
// 重置“活动”标志
cancelRefresh(ex);
// 向调用方传播异常
throw ex;
} finally {
// 重置Spring核心中的常见内省缓存,因为我们可能不再需要单例bean的元数据
resetCommonCaches();
}
}
}
在这个方法中。第一件做的事情是initPropertySources()方法:主要是设置启动时间与初始化上下文环境中任何占位符属性源;第二件事情就是getEnvironment().validateRequiredProperties()方法:获取当前的操作系统环境去验证属性合法性;第三件事情是this.earlyApplicationEvents = new LinkedHashSet<>():创建一个早期应用事件的容器。
protected void prepareRefresh() {
// 设置启动时间
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
} else {
logger.debug("Refreshing " + getDisplayName());
}
}
// 初始化上下文环境中的任何占位符属性源
initPropertySources();
// 验证标记为必需的所有属性是否可解析:
// 请参阅ConfigurationPropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
} else {
// 将本地应用程序侦听器重置为预刷新状态
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// 允许收集早期 ApplicationEvents,以便在多主机可用后发布
this.earlyApplicationEvents = new LinkedHashSet<>();
}
从这个方法的内部可以看到又去执行了refreshBeanFactory()方法,字面意思就是刷新Bean工厂。于是来到了AbstartRefreshableApplicationContext这个子类去对这个方法进行操作。从源码可以看得出来如果有Bean工厂就销毁,最后返回DefaultListableBeanFactory这个Bean工厂。
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
在AbstartRefreshableApplicationContext这个子类继承了这个方法完成了具体实现
protected final void refreshBeanFactory() throws BeansException {
// 判断是否有Bean工厂 如果有则销毁并且关闭
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
// 这里最主要的目的就是返回一个DefaultListableBeanFactory 这个Bean工厂
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
第一件事是设置Bean工厂的上下文类加载器等;第二件事情是为Bean工厂添加Bean的后置处理器(ApplicationContextAwareProcessor)并且忽略一些依赖接口,添加到名为ignoredDependencyInterfaces的HashSet集合中;第三件事情是注册解析依赖项,将它们放入名为resolvableDependencies的ConcurrentHashMap集合中;第四件事情是为这个Bean工厂添加一个Bean后置处理器(ApplicationListenerDetector);第五件事情是判断Bean工厂是否包含一个名为"loadTimeWeaver"的Bean,如果有则添加一个Bean后置处理器(LoadTimeWeaverAwareProcessor);第六件事是注册默认的Bean环境。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 告诉内部 Bean工厂使用上下文的类加载器等。
beanFactory.setBeanClassLoader(getClassLoader());// 设置Bean工厂的类加载器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));// 设置Bean的解析处理器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 使用上下文回调配置 Bean工厂 并且忽略一些依赖接口
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);
// 注册可以解析的自动装配:BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
// 这里的beanFactory就是刷新IoC容器的第二步中获取到的DefaultListableBeanFactory 而this就是表示AbstractApplicationContext这个类
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 为Bean工厂添加Bean的后置处理器(ApplicationListenerDetector)
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 如果Bean工厂有"loadTimeWeaver" 则添加一个Bean的后置处理器 以及临时的类加载器
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());
}
}
// 根据传来的是哪个子类就到其重写方法中创建和准备环境
postProcessBeanFactory(beanFactory);
注意:以上四个步骤可以统称为对Bean工厂的创建以及预准备工作。