<div style="font-size:16px;">
<p>SpringBoot应用开发已经非常普遍,的确,SpringBoot给我们的开发带来了很多便利,但其实,SpringBoot并没有增加什么新特性,只不过是在Spring注解的基础上做了升级版混合使用。SpringBoot的精髓就是<strong>自动装配(@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>/** * @Description: Dog实体类 * @Auther: Java思享汇 */@Data@ToStringpublic class Dog { private String name; private Integer age; public Dog(){ System.out.println("------>构造函数调用"); } public void init(){ System.out.println("------>init函数调用"); }}</code></pre>
<pre class="blockcode"><code>/** * @Description: Configuration配置类 * @Auther: Java思享汇 */@ComponentScan("com.study.spring")@Configurationpublic class DogConfiguration { public Dog dog(){ return new Dog(); }}</code></pre>
<p>接下来定一个测试类</p>
<pre class="blockcode"><code>/** * @Description: 测试类 * @Auther: Java思享汇 */public class Test { @org.junit.Test public void test(){ AnnotationConfigApplicationContext ac =new AnnotationConfigApplicationContext(DogConfiguration.class); Dog dog = (Dog) ac.getBean("dog"); System.out.println(dog); }}</code></pre>
<p>我们就从AnnotationConfigApplicationContext这个类开始,探究下Spring的IOC容器是如何装载Bean的,源码如下:</p>
<pre class="blockcode"><code>public AnnotationConfigApplicationContext(Class>... annotatedClasses) {this();register(annotatedClasses);//重点在下面这个方法,创建刷新容器refresh();}</code></pre>
<p>然后,我们继续向下跟踪这个refresh()方法,这个方法在抽象类AbstractApplicationContext下</p>
<pre class="blockcode"><code>@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 1、刷新前的预处理prepareRefresh();// 2、获取BeanFactoryConfigurableListableBeanFactory beanFactory = 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("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Spring'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;@Service、@Component、@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 |
|