本文继续跟着上一篇文章走,开始分析 AbstractApplication
的 refresh
方法。
本文主要围绕以下几个方面进行:
加锁
在 AbstractApplication
中,定义了 Object
类型的 变量 startupShutdownMonitor
作为锁。当执行 refresh 和 destroy 方法则会进行加锁禁止并发操作。
synchronized (this.startupShutdownMonitor) {
...
}
prepareRefresh
该方法,主要是为refresh 方法执行 准备操作。
protected void prepareRefresh() {
// 设置启动日期,closed 和 active 状态
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
// log 打日志
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
// 初始化 一些环境变量信息,由子类实现。
initPropertySources();
// 验证所有变量的合法性
getEnvironment().validateRequiredProperties();
// 存储 pre-refresh 类型的 ApplicationListeners
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// 初始化 early ApplicationEvents 类型的事件,允许 multicaster 可用时立刻触发。
this.earlyApplicationEvents = new LinkedHashSet<>();
}
以上几步主要是初始化 资源,例如 earlyApplicationListeners
、applicationListeners
、earlyApplicationEvents
另一方面,也会使用 initPropertySources
去加载子类所需要的一些 属性。
validateRequiredProperties
则是对属性进行验证。
例如,如果项目项目里面使用了 某一个环境变量,而 对应机器或者 在 initPropertySources
加载资源未加载进去,则可以在 validateRequiredProperties
验证不通过进行告警。
obtainFreshBeanFactory
在这里面主要是让子类去刷新(refresh) beanFactory。
obtainFreshBeanFactory:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
refreshBeanFactory
是 protected 的空方法,主要看子类如何实现。
本文使用 是 AnnotationConfigApplicationContext
在 当前类 AnnotationConfigApplicationContext
中,并没有 实现 refreshBeanFactory
,而在 其父类 GenericApplication
中有实现该方法,并在 在GenericApplication
中会对 final 成员变量 beanFactory
进行初始化。默认构造为 DefaultListableBeanFactory
。
GenericApplicationContext
的 refreshBeanFactory
:
@Override
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
this.beanFactory.setSerializationId(getId());
}
里面判断了 beanFactory 初始化状态,以及设置 了 beanFactory 的序列化id。
prepareBeanFactory
准备完环境,初始化了BeanFactory,那么到这里就开始要为使用BeanFactory做准备了。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
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 interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
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()));
}
// Register default environment beans.
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());
}
}
上文准备过程,包括添加classLoader,忽略了一些DependencyInterface
(这些不需要bean初始化),还添加了两个BeanPostProcessor
:
ApplicationContextAwareProcessor
: 用于在初始化bean时候,自动填入一些属性。ApplicationListenerDetector
: 添加ApplicationListeners 所需要的支持。
后面则根据需要提前注册了一些bean。
觉得博主写的有用,不妨关注博主公众号: 六点A君。
哈哈哈,一起研究Spring: