Spring refresh()方法

刷新容器前的预处理

prepareRefresh();

  1. initPropertySources();
    初始化一些属性设置

  2. getEnvironment().validateRequiredProperties();
    校验属性的合法性

  3. this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
    保存容器中的早期事件的容器 Set 集合

获取 beanFactory

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

  1. this.beanFactory = new DefaultListableBeanFactory();
    构造一个 beanFactory

  2. ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    获取 BeanFactory 返回的上一步构 GenericApplicationContext 类构造器创建的 beanFactory

  3. return beanFactory;
    返回 beanFactory 【ConfigurableListableBeanFactory 的实例实例对象】

beanFactory 的预准备工作

prepareBeanFactory(beanFactory);

  1. 设置 beanFactory 的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
  1. 添加 BeanPostProcessor 后置处理器
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
  1. 设置忽略的自动装配的接口
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAwarelass);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAre.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.cls);
  1. 注解可以自动装配的 Bean, 我们可以直接进行注入
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
  1. 添加 BeanPostProcessor ApplicationListenerDetector
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
  1. 给 beanFactory 注册一些包含的组件
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
  beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
  beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
  beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}

beanFactory 准备完成的后置处理工作

postProcessBeanFactory(beanFactory);

  1. 空方法,子类通过重写这个方法来在 BeanFactory 创建并预准备完成以后做进一步的设置
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}

执行 beanFactoryPostProcessors 方法

invokeBeanFactoryPostProcessors(beanFactory);

  1. 执行 invokeBeanFactoryPostProcessors 的方法
    1. BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor
      先执行 BeanDefinitionRegistryPostProcessor 的方法
      再执行 BeanFactoryPostProcessors 的方法

注册 BeanPostProcessors 【 Bean 的后置处理器 】

registerBeanPostProcessors(beanFactory);

优先级接口PriorityOrdered 和 Ordered

初始化 MessageSource 组件

initMessageSource();

初始化事件派发器

initApplicationEventMulticaster();

留给子容器(子类)

onRefresh();

给容器中将所有项目里面的ApplicationListener注册进来

registerListeners();

  1. 获取所有的事件,并添加到事件派发器中
for (ApplicationListener<?> listener : getApplicationListeners()) {
    getApplicationEventMulticaster().addApplicationListener(listener);
}
  1. 派发事件
getApplicationEventMulticaster().multicastEvent(earlyEvent);

初始化所有剩下的单实例 Bean(没有配置赖加载的 lazy!=true)

finishBeanFactoryInitialization(beanFactory);

  1. 初始化所有剩下的单实例bean
beanFactory.preInstantiateSingletons();
  1. 将容器中所有的 bean 加入到 List中
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
  1. 遍历该 List
for (String beanName : beanNames) {
  ...
}
  1. 获取 bean 定义信息
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
  1. bean 不是抽象的、是单例的、非懒加载的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
  ...
}
  1. 是否为 FactoryBean ,是则调用 FactoryBean 的创建方法,否则执行 getBean() 方法
if (isFactoryBean(beanName)) {
        ...     
}
  1. 调用 getBean() 方法 -> 内部再调用 doGetBean() 方法

    1. 尝试从从缓存中获取 bean
     Object sharedInstance = getSingleton(beanName);
    
    1. 获取 bean 定义信息
     RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    
    1. 判断是否有其他依赖,如果有其他依赖,注册依赖的 bean 并调用 getBean() 方法创建
    String[] dependsOn = mbd.getDependsOn();
    if (dependsOn != null) {
             for (String dep : dependsOn) {
                 if (isDependent(beanName, dep)) {
                     throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                             "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                 }
                 registerDependentBean(dep, beanName);
                 getBean(dep);
             }
         }
    
    1. 进入单实例 bean 的创建流程
    return createBean(beanName, mbd, args);
    

    单实例 bean 的创建流程很复杂,单独进行说明

完成BeanFactory的初始化创建工作;IOC容器就创建完成

finishRefresh();

  1. 从 beanFactory 中获取 LifecycleProcessor 组件,如果没有获取到,则创建。
if(xxx){
  this.lifecycleProcessor = beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
  ...
} else{
  DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
  ...
}
  1. 调用 onRefresh() 方法,在上一步中,已经有 LifecycleProcessor 组件了
getLifecycleProcessor().onRefresh();

  1. 发布容器刷新完成事件
publishEvent(new ContextRefreshedEvent(this));
  1. LiveBeansView.registerApplicationContext(this);
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351

推荐阅读更多精彩内容