写点什么

spring 系列之 IOC 容器实例化过程二

作者:王威07325
  • 2023-05-29
    上海
  • 本文字数:2492 字

    阅读完需:约 8 分钟

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 表示的启动时间, closedactive 两个都是原子操作类 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 对象。

发布于: 刚刚阅读数: 3
用户头像

王威07325

关注

还未添加个人签名 2021-12-29 加入

还未添加个人简介

评论

发布
暂无评论
spring系列之IOC容器实例化过程二_spring ioc_王威07325_InfoQ写作社区