You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RefreshScope中ContextRefreshedEvent处理逻辑的两个技术疑问

RefreshScope中ContextRefreshedEvent处理逻辑的两个问题解答

在Spring Cloud的org.springframework.cloud.context.scope.refresh.RefreshScope中,处理ContextRefreshedEvent的逻辑如下:

@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
    start(event);
}

public void start(ContextRefreshedEvent event) {
    if (event.getApplicationContext() == this.context && this.eager
            && this.registry != null) {
        eagerlyInitialize();
    }
}

private void eagerlyInitialize() {
    for (String name : this.context.getBeanDefinitionNames()) {
        BeanDefinition definition = this.registry.getBeanDefinition(name);
        if (this.getName().equals(definition.getScope())
                && !definition.isLazyInit()) {
            Object bean = this.context.getBean(name);
            // question 1
            if (bean != null) {
                 // question 2
                 bean.getClass();
            }
        }
    }
}

问题1:调用getBean方法时,若Bean不存在会抛出异常,为何还要判断Bean是否为null?

Spring的getBean()方法多数场景下会在Bean不存在或初始化失败时抛出异常,但存在特殊场景会返回null:

  • 当Bean是FactoryBean类型时,如果其getObject()方法返回null,调用getBean(name)会直接返回null,而非抛出异常;
  • 极少数自定义BeanFactory或BeanPostProcessor的实现中,可能存在返回null的情况。

这里的null判断就是为了兼容这些边缘场景,避免后续调用bean.getClass()时出现NullPointerException。

问题2:执行bean.getClass()看似无实际意义,为何要添加该处理逻辑?

因为RefreshScope的Bean默认通过动态代理实现(CGLIB或JDK代理),调用getBean()返回的只是代理对象,真实的目标Bean此时可能还未完成初始化。

调用bean.getClass()会触发代理对象的方法调用逻辑:代理类会在第一次接收到方法调用(包括getClass())时,创建并初始化真实的目标Bean。这样就能实现eagerlyInitialize()方法的目的——提前初始化所有非懒加载的RefreshScope Bean,而非等到第一次业务调用时才触发初始化。

内容的提问来源于stack exchange,提问作者duanduan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 20:25:20