SpringIoc源码(十四)- ApplicationContext(十)- refresh(finishRefresh和destroyBeans)

目录

一、finishRefresh

1、clearResourceCaches

2、initLifecycleProcessor

3、LifecycleProcessor的onRefresh

4、ContextRefreshedEvent

5、LiveBeansView.registerApplicationContext

二、Spring Boot类型的finishRefresh


一、finishRefresh

1、clearResourceCaches

    Clear context-level resource caches (such as ASM metadata from scanning).清除Spring ApplicationContext级别的资源加载缓存,比如通过扫描加载注入的时候的ASM。清除的是DefaultResourceLoader

Map<Class<?>, Map<Resource, ?>> resourceCaches

public void clearResourceCaches() {
    this.resourceCaches.clear();
}

 

2、initLifecycleProcessor

    之前在SpringIoc源码(五)- ApplicationContext(一)- 结构梳理的时候分析过,ApplicationContext实现了Lifecycle接口定义了容器的生命周期。那么在这里实现了生命周期的onRefresh方法。一般我们不会进行注册,则会初始化DefaultLifecycleProcessor 类型,并且注册名称为lifecycleProcessor的Bean。

protected void initLifecycleProcessor() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
        this.lifecycleProcessor =
                beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
    }
    else {
        DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
        defaultProcessor.setBeanFactory(beanFactory);
        this.lifecycleProcessor = defaultProcessor;
        beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
    }
}

3、LifecycleProcessor的onRefresh

    上一步初始化完成DefaultLifecycleProcessor类型,这里执行生命周期的onRefresh。

@Override
public void onRefresh() {
    startBeans(true);
    this.running = true;
}
private void startBeans(boolean autoStartupOnly) {
    Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
    Map<Integer, LifecycleGroup> phases = new HashMap<>();
    lifecycleBeans.forEach((beanName, bean) -> {
        if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
            int phase = getPhase(bean);
            LifecycleGroup group = phases.get(phase);
            if (group == null) {
                group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
                phases.put(phase, group);
            }
            group.add(beanName, bean);
        }
    });
    if (!phases.isEmpty()) {
        List<Integer> keys = new ArrayList<>(phases.keySet());
        Collections.sort(keys);
        for (Integer key : keys) {
            phases.get(key).start();
        }
    }
}

    先获取实现了Lifecycle接口的Bean,再根据不同的生命周期阶段分组,最后调用start方法,可能就会调用我们自定义的start方法。stop方法同理。 getLifecycleBeans方法如下:

protected Map<String, Lifecycle> getLifecycleBeans() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    Map<String, Lifecycle> beans = new LinkedHashMap<>();
    String[] beanNames = beanFactory.getBeanNamesForType(Lifecycle.class, false, false);
    for (String beanName : beanNames) {
        String beanNameToRegister = BeanFactoryUtils.transformedBeanName(beanName);
        boolean isFactoryBean = beanFactory.isFactoryBean(beanNameToRegister);
        String beanNameToCheck = (isFactoryBean ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
        if ((beanFactory.containsSingleton(beanNameToRegister) &&
                (!isFactoryBean || matchesBeanType(Lifecycle.class, beanNameToCheck, beanFactory))) ||
                matchesBeanType(SmartLifecycle.class, beanNameToCheck, beanFactory)) {
            Object bean = beanFactory.getBean(beanNameToCheck);
            if (bean != this && bean instanceof Lifecycle) {
                beans.put(beanNameToRegister, (Lifecycle) bean);
            }
        }
    }
    return beans;
}

4、ContextRefreshedEvent

    发送ContextRefreshedEvent类型事件,Spring把事件定义为ApplicationEvent类型和我们自己的的事件(PayloadApplicationEvent)。详细可参考Spring源码-事件监听机制(实现EventListener接口)

5、LiveBeansView.registerApplicationContext

LiveBeansView.registerApplicationContext(this);
static void registerApplicationContext(ConfigurableApplicationContext applicationContext) {
    String mbeanDomain = applicationContext.getEnvironment().getProperty(MBEAN_DOMAIN_PROPERTY_NAME);
    if (mbeanDomain != null) {
        synchronized (applicationContexts) {
            if (applicationContexts.isEmpty()) {
                try {
                    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
                    applicationName = applicationContext.getApplicationName();
                    server.registerMBean(new LiveBeansView(),
                            new ObjectName(mbeanDomain, MBEAN_APPLICATION_KEY, applicationName));
                }
                catch (Throwable ex) {
                    throw new ApplicationContextException("Failed to register LiveBeansView MBean", ex);
                }
            }
            applicationContexts.add(applicationContext);
        }
    }
}

    初始化MBeanServer,完成JVM相关的监控。后续梳理与Spring Boot Actuator的JVM监控的关系。

二、Spring Boot类型的finishRefresh

    SpringBoot类型的finishRefresh,比如ServletWebServerApplicationContext或者ReactiveWebServerApplicationContext类型,则会在处理父类AbstractApplicationContext的finishRefresh后,还会处理WebServer嵌入式容器相关相关的,如TomcatWebServer。下面就只看类型:

@Override
protected void finishRefresh() {
    super.finishRefresh();
    WebServer webServer = startWebServer();
    if (webServer != null) {
        publishEvent(new ServletWebServerInitializedEvent(webServer, this));
    }
}

    1、先回调父类,也就是上面的五步;

    2、初始化WebServer(内嵌容器)

    3、发送服务容器初始化事件,给监听的列表。

private WebServer startWebServer() {
    WebServer webServer = this.webServer;
    if (webServer != null) {
        webServer.start();
    }
    return webServer;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值