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();
        }
    }
}

可以看到方法做了很多很多的操作,具体操作及解析参考注释及对应连接(todo)


觉得内容还不错?打赏个钢镚鼓励鼓励!!👍

晨光(M&G)文具12色圆形粗杆水彩笔 幼儿园可水洗水彩笔 儿童绘画涂鸦 美术课必备ACP901M4考试用品
¥25.90
马培德Maped 3D带护套儿童剪刀13cm/粉色 学生儿童剪刀安全手工舒适软柄带刻度圆角小剪子女孩 474094CH
¥5.40
毕亚兹【贴坏包赔】任天堂switch钢化膜 Nintendo保护贴膜 全屏覆盖抗蓝光游戏机玻璃前膜NS配件
¥19.90
得力(deli) 手握式订书机 大 外卖打包专用订单商用订书器省力钉书机装订机订书钉办公用品 省力手握款-黑色 0358
¥24.80
曼秀雷敦 蜂蜜植萃精华油润唇膏4g小蜜油-无香料(唇膏男女 保湿补水 )
¥30.90
飞雕开关插座面板10a五孔墙壁插座86型单开暗装电源5孔网线网络16A空调带开关面板雕琢白 四开单控
¥36.46
迪士尼【官方正版】手机挂绳 Disney宽带创意卡通网红证件挂饰钥匙防丢编织挂脖长款男女款 92*2cm 黛丝
¥18.00
简爱 酸奶水果裸酸奶原味百香果果泥便携早餐 低温酸牛奶生鲜 原味230g*6瓶
¥50.00