SpringBoot源码之ConfigurableApplicationContext及refresh方法

SpringBoot中使用的ApplicationContext主要是ConfigurableApplicationContext这个接口。

1、接口继承了ApplicationContext->ListableBeanFactory->BeanFactory。所以ConfigurableApplicationContext也是一个BeanFactory类,拥有getBean()方法用来获取Spring管理的Bean对象。

2、接口定义了一个很重要的方法refresh()

/**
 * Load or refresh the persistent representation of the configuration,
 * which might an XML file, properties file, or relational database schema.
 * <p>As this is a startup method, it should destroy already created singletons
 * if it fails, to avoid dangling resources. In other words, after invocation
 * of that method, either all or no singletons at all should be instantiated.
 * @throws BeansException if the bean factory could not be initialized
 * @throws IllegalStateException if already initialized and multiple refresh
 * attempts are not supported
 */
void refresh() throws BeansException, IllegalStateException;

通过注释可以得知:这个方法用于加载或者刷新配置,配置可以是一个xml文件,配置文件等各种形式。我们也知道,Spring管理的各种Bean我们可以通过注解或者xml的形式进行配置,即我们可以认为这个方法主要是用于加载我们委托Spring进行管理的各种Bean。


接口有了,我们来看看实现,ConfigurableApplicationContext的主要实现位于实现了它的抽象类AbstractApplicationContext

1、对于getBean()方法的实现,其实应该说对于整个BeanFactory接口的实现,AbstractApplicationContext都是直接通过获取一个BeanFactory,之后代理这个BeanFactory来实现的。获取BeanFactory使用的是getBeanFactory()这个方法,这个方法是一个抽象方法,留给子类实现,见GenericApplicationContext

@Override
public Object getBean(String name) throws BeansException {
    assertBeanFactoryActive();
    return getBeanFactory().getBean(name);
}

@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
    assertBeanFactoryActive();
    return getBeanFactory().getBean(name, requiredType);
}

@Override
public Object getBean(String name, Object... args) throws BeansException {
    assertBeanFactoryActive();
    return getBeanFactory().getBean(name, args);
}

@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
    assertBeanFactoryActive();
    return getBeanFactory().getBean(requiredType);
}

@Override
public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
    assertBeanFactoryActive();
    return getBeanFactory().getBean(requiredType, args);
}

2、refresh()方法的实现

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        prepareBeanFactory(beanFactory);

        try {
            // Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            initMessageSource();

            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            onRefresh();

            // Check for listener beans and register them.
            registerListeners();

            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            finishRefresh();
        }

        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "cancelling refresh attempt: " + ex);
            }

            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();

            // Reset 'active' flag.
            cancelRefresh(ex);

            // Propagate exception to caller.
            throw ex;
        }

        finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}

可以看到方法做了很多很多的操作,具体操作及解析参考注释及对应连接(未完成,留坑待填)

支付宝搜索:344355 领取随机红包

如果文章对您有帮助的话,欢迎老板打赏↑↑↑(请我吃饭😋