Spring IOC容器初始化过程及其原理(源码层面)

论坛 期权论坛     
选择匿名的用户   2021-5-28 04:12   0   0
<blockquote>
<p><strong>Spring大家族在Java技术生态体系中占有重要地位,其中Spring更是其中的佼佼者。它极大的简化了我们的代码开发量,提高我们的工作效率。</strong></p>
<p><strong>其中Spring两大特性中的IOC特性是至关重要的。今天来从底层看一看Spring的容器的初始化过程。<span style="color:#e579b6;">算是我的学习笔记,也希望能对你有所帮助!</span></strong></p>
</blockquote>
<p>(如果有不懂IOC的小伙伴们可以去看一看我前面写的文章<strong><a href="https://blog.csdn.net/m0_46405589/article/details/107977319"><span style="color:#f33b45;">传送门在此</span></a></strong>)。</p>
<p><span style="color:#f33b45;">在开始之前,先思考几个问题。</span></p>
<ul><li><strong><span style="color:#3399ea;">&#64;Component,&#64;Service,&#64;Controller,&#64;Repository&#64;Bean等注解怎么实现的?</span></strong></li><li><span style="color:#3399ea;"><strong>&#64;Autowired,&#64;Resource 是怎么自动装配的?</strong></span></li><li><span style="color:#3399ea;"><strong>&#64;ComponentScan 为什么就可以扫描注册Bean</strong></span></li></ul>
<p> </p>
<p><strong>对此我在其他博客看到一张图,感觉很生动形象。</strong></p>
<h3><span style="color:#f33b45;">IOC 容器 示意图</span></h3>
<blockquote>
<p><strong><span style="color:#3399ea;">Spring IOC :</span></strong></p>
<ol><li><strong>Bean定义的定位,Bean 可以定义在<span style="color:#e579b6;">XML</span>中,或者一个<span style="color:#e579b6;">注解</span>,或者其他形式。这些都被用<span style="color:#e579b6;">Resource</span>来定位, 读取Resource获取<span style="color:#e579b6;">BeanDefinition </span>注册到 Bean定义注册表中。</strong></li><li><strong>第一次向容器getBean操作会触发Bean的创建过程,实列化一个Bean时 ,根据BeanDefinition中类信息等实列化Bean.</strong></li><li><strong>将实列化的Bean放到单列Bean缓存内。</strong></li><li><strong>此后再次获取向容器getBean就会从缓存中获取。</strong></li></ol>
</blockquote>
<p><br><img alt="" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-566c2931fc689ffc4e0b5e1358916d4d.png"></p>
<p> </p>
<p>OK,下面来看容器的初始化方法。</p>
<p><span style="color:#f33b45;"><strong>源码如下:</strong></span></p>
<pre class="blockcode"><code class="language-java">public void refresh() throws BeansException, IllegalStateException {
//同步代码块 。
        synchronized (this.startupShutdownMonitor) {
            // 准备刷新.
            prepareRefresh();
            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory &#61; 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(&#34;Exception encountered during context initialization - &#34; &#43;
                            &#34;cancelling refresh attempt: &#34; &#43; ex);
                }
                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();
                // Reset &#39;active&#39; flag.
                cancelRefresh(ex);
                // Propagate exception to caller.
                throw ex;
            }
            finally {
                // Reset common introspection caches in Spring&#39;s core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }</code></pre>
<h3><span style="color:#f33b45;"><strong>1. prepareRefresh 准备刷新</strong></span></h3>
<blockquote>
<ul><li>设置启动时间,设计容器激活标志(active&#61;true)</li><li>初始化 properties 资源</li><li>验证必须存在的properties(validateRequiredProperties)</li><li>初始earlyApplicationEnvents.用于收集已经产生的ApplicationEnvents.</li></ul>
</blockquote>
<h3><span style="color:#f33b45;"><strong>2.obtainFreshBeanFactory 获取容器</str
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP