spring bean加载过程_Spring如何加载「IOC容器」以及「装载Bean」源码解读

论坛 期权论坛     
选择匿名的用户   2021-5-23 20:50   152   0
<div style="font-size:16px;">
<p>SpringBoot应用开发已经非常普遍,的确,SpringBoot给我们的开发带来了很多便利,但其实,SpringBoot并没有增加什么新特性,只不过是在Spring注解的基础上做了升级版混合使用。SpringBoot的精髓就是<strong>自动装配(&#64;EnableAutoConfiguration)</strong>,我们不需要像以前使用Maven搭建项目时,引入过多的依赖包,同时还需要处理各种包冲突问题,简直是烦的要死,现在只需依赖SpringBoot核心包就能完成简单的应用开发了,所以了解Spring核心原理就非常重要了,下面我们开始从源码角度分析Spring底层原理。</p>
<div class="pgc-img">
  <img alt="25ec1499bf2b4415bbd2938dfe9c48e7" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-fb161081b4274e33a0ffc2f5155eeec9">
</div>
<p>下面我们首先定义一个实体类和配置类</p>
<pre class="blockcode"><code>/** * &#64;Description: Dog实体类 * &#64;Auther: Java思享汇 */&#64;Data&#64;ToStringpublic class Dog  {    private String name;    private Integer age;    public Dog(){        System.out.println(&#34;------&gt;构造函数调用&#34;);    }    public void init(){        System.out.println(&#34;------&gt;init函数调用&#34;);    }}</code></pre>
<pre class="blockcode"><code>/** * &#64;Description: Configuration配置类 * &#64;Auther: Java思享汇 */&#64;ComponentScan(&#34;com.study.spring&#34;)&#64;Configurationpublic class DogConfiguration {    public Dog dog(){        return new Dog();    }}</code></pre>
<p>接下来定一个测试类</p>
<pre class="blockcode"><code>/** * &#64;Description: 测试类 * &#64;Auther: Java思享汇 */public class Test {    &#64;org.junit.Test    public void test(){        AnnotationConfigApplicationContext ac &#61;new AnnotationConfigApplicationContext(DogConfiguration.class);        Dog dog &#61; (Dog) ac.getBean(&#34;dog&#34;);        System.out.println(dog);    }}</code></pre>
<p>我们就从AnnotationConfigApplicationContext这个类开始,探究下Spring的IOC容器是如何装载Bean的,源码如下:</p>
<pre class="blockcode"><code>public AnnotationConfigApplicationContext(Class&gt;... annotatedClasses) {this();register(annotatedClasses);//重点在下面这个方法,创建刷新容器refresh();}</code></pre>
<p>然后,我们继续向下跟踪这个refresh()方法,这个方法在抽象类AbstractApplicationContext下</p>
<pre class="blockcode"><code>&#64;Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 1、刷新前的预处理prepareRefresh();// 2、获取BeanFactoryConfigurableListableBeanFactory beanFactory &#61; obtainFreshBeanFactory();// 3、BeanFactory的预准备工作(BeanFactory进行一些设置)prepareBeanFactory(beanFactory);try {// 4、BeanFactory准备工作完成后进行的后置处理工作postProcessBeanFactory(beanFactory);// 5、执行BeanFactoryPostProcessor的方法invokeBeanFactoryPostProcessors(beanFactory);// 6、注册BeanPostProcessor(Bean的后置处理器),不同接口类型的BeanPostProcessor;在Bean创建前后的执行时机是不一样的registerBeanPostProcessors(beanFactory);// 7、初始化MessageSource组件(做国际化功能;消息绑定,消息解析)initMessageSource();// 8、初始化事件派发器;initApplicationEventMulticaster();// 9、留给子容器(子类),空方法onRefresh();// 10、给容器中将所有项目里面的ApplicationListener注册进来registerListeners();// 11、重点在这,初始化所有剩下的单实例bean(自定义的单例bean)finishBeanFactoryInitialization(beanFactory);// 12、完成BeanFactory的初始化创建工作;IOC容器就创建完成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>
<p>通过以上步骤,我们发现Spring的IOC容器主要完成了以下操作:</p>
<p>1、Spring容器在启动的时候,先会保存所有注册进来的Bean的定义信息;</p>
<ol start="1"><li>xml注册bean;</li><li>注解注册Bean;&#64;Service、&#64;Component、&#64;Bean</li></ol>
<p>2、Spring容器会合适的时机创建这些Bean</p>
<ol start="1"><li>用到这个bean的时候;利用getBean创建bean;创建好以后保存在容器中;</li><li>统一创建剩下所有的bean的时候;finishBeanFactoryInitialization();</li></ol>
<p>3、后置处理器;BeanPostProcessor</p>
<ol start="1"><li>每一个bean创建完成,都会使用各种后置处理器进行处理;来增强bean的功能;AutowiredAnnotationBeanPostProcessor:处理自动注入AnnotationAwareAspectJAutoProxyCreator:来做AOP功能;xxx…增强的功能注解:As
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

下载期权论坛手机APP