SpringIOC 容器 Bean 的实例化过程
书接上回,在 SpringIOC 容器的实例化过程中,AbstractApplicationContext 中有一个非常重要的方法 refresh(),spring 创造者采用了模板方法设计模式去设计这个方法,IOC 主要功能逻辑都在这个方法中实现,如果不知道模板方法模式的可以去看看博主的23种设计模式详解 ,也就是因为这种设计模式的关系,这个方法中相关的逻辑实现会比较复杂,为了更加细致的讲解 Spring 因此我会每篇文章讲解一部分。
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
复制代码
上面是 Refresh 方法的实现,我们这篇文章主要讲解 this.prepareRefresh();
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
// Initialize any placeholder property sources in the context environment
//空实现
initPropertySources();
// Validate that all properties marked as required are resolvable
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}
复制代码
前三行代码就是对 IOC 容器对象中的属性进行一个赋值,startupDate 表示的启动时间, closed,active 两个都是原子操作类 AtomicBoolean(保证了多线程下的读写原子性)。
protected void initPropertySources() {
// For subclasses: do nothing by default.
}
复制代码
initPropertySources(); 在上下文环境中初始化任何占位符属性源,是一个空实现,目的是为了让子类去实现,也算是很经典的设计理念了,代码的扩展性、灵活性得到了提高。
// Validate that all properties marked as required are resolvable
// see ConfigurablePropertyResolver#setRequiredProperties
//进行属性校验
getEnvironment().validateRequiredProperties();
public ConfigurableEnvironment getEnvironment() {
if (this.environment == null) {
//获取StandardEnvironment对象
this.environment = createEnvironment();
}
return this.environment;
}
protected ConfigurableEnvironment createEnvironment() {
return new StandardEnvironment();
}
复制代码
getEnvironment().validateRequiredProperties(); 首先通过 getEnvironment() 去获取一个 StandardEnvironment 对象。
public void validateRequiredProperties() throws MissingRequiredPropertiesException {
this.propertyResolver.validateRequiredProperties();
}
//AbstractEnvironment的构造器方法
public AbstractEnvironment() {
this.propertySources = new MutablePropertySources(this.logger);
this.propertyResolver = new PropertySourcesPropertyResolver(this.propertySources);
this.customizePropertySources(this.propertySources);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Initialized " + this.getClass().getSimpleName() + " with PropertySources " + this.propertySources);
}
}
//属性校验
public void validateRequiredProperties() throws MissingRequiredPropertiesException {
//这里validateRequiredProperties方法的实现是在PropertySourcesPropertyResolver的父类AbstractPropertyResolver中。
this.propertyResolver.validateRequiredProperties();
}
复制代码
调用 validateRequiredProperties() 方法进行一个属性的校验工作,就是说如果环境变量和系统变量不符合要求(其实在 spring 源码中并没有需要校验的属性,也就是存储校验的属性为 null。至于为什么要写这个方法,博主也不得而知),就会抛出 MissingRequiredPropertiesException 异常,而这个工作实际完成的通过 PropertySourcesPropertyResolver 类完成的,这个类是在 AbstractEnvironment 构造器调用过程完成实例化的,而 AbstractEnvironment 实例化过程在 getEnvironment() 调用过程中完成。
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
复制代码
在方法的最后给 earlyApplicationEvents 赋值为一个 LinkedHashSet 用于存储 applicationevent 对象。
评论