Spring核心原理

Spring核心原理

在Spring中拥有许多的组件,但核心部分主要为:Beans、Core、Context、Expression,其中最为主要的为Core、与Beans,它们提供了最为核心的IOC和依赖注入功能。下文主要从这两个着手进行说明。html

设计思想

Spring5架构图:java

在这里插入图片描述

Spring框架设计理念web

在Spring框架中,其最核心组件应属Beans,Spring-Beans模块是全部应用都必须使用的,它包含了访问配置文件、建立和管理Bean以及进行控制反转(IOC,Inversion of Control)、依赖注入(DI,Dependency Injection)操做相关的全部类。spring

在IBM developerWorks一文中(https://www.ibm.com/developerworks/cn/java/j-lo-spring-principle/index.html)这样说道:Spring就是面向Bean编程(BOP,Bean Oriented Programming),Bean 在 Spring 中才是真正的主角。编程

Bean生命周期

在Spring中Bean贯穿整个Spring应用,其生命周期应是从Spring容器建立后开始,直至Spring容器主动或被动销毁Bean。缓存

在Spring中,Bean默认为单例模式,即singleton属性默认为false,从BeanFactory中取得的Bean实例为在其初始化就产生一个新的对象,而不是每次获取的时候都产出一个新的对象。固然咱们也能够在初始化Bean的时候设置其singleton属性为true,使这个Bean变成多例模式,在getBean的时候,Spring都会产出一个新的对象,相似于Java的中的new Object操做。但设置其为多例,应避免多线程同时存取共享资源所引起的数据不一样步问题。数据结构

而后在Spring中,一个Bean从建立到销毁,大体须要经历一下几个步骤(其具体的实现方式,将在下放继续阐述):多线程

  1. 实例化Bean,根据Spring配置,执行包扫描操做,并对其进行实例化操做。
  2. 根据Spring上线文对实例化的Bean进行配置,其中包括依赖注入。
  3. 判断是否实现了BeanNameAware接口,若是有会执行setBeanName方法去设置这个Bean的id,即本身设置Bean在BeanFactory中的名字。
  4. 判断是否实现了BeanFactoryAware接口,若是有则执行setBeanFactory方法,使得Bean能够获取本身的工厂,从而可使用工厂的getBean方法。
  5. 判断是否实现了ApplicationContextAware接口,若是有则执行setApplicationContext方法,使得在Bean中能够获取Spring上下文,从而能够获取经过上下文去getBean,该步骤与上一步做用大体相同,但经过该中方式能实现的功能却更加丰富。
  6. 判断是否实现了BeanPostProcessor接口,若是有则调用postProcessBeforeInitialization方法,这一步属于实例化Bean的前置操做,在通过该步骤后,即Bean实例化后一样也会执行一个操做,详情见第八条。
  7. 判断Bean是否配置了init-method,若是有,在Bean初始化以后会默认执行一次init-method指定的方法。
  8. 判断Bean是否实现了BeanPostProcessor接口,若是有则调用postProcessAfterInitialization方法,该方法属于Bean实例化后的操做。在通过这个步骤后,Bean的初始化操做就完成了。
  9. 当Bean实例化完成后,当Bean再也不被须要的时候会执行销毁操做。通常是在ApplicationContext执行close方法时会进行销毁操做。
  10. 在销毁过程当中,判断是否实现了DisposableBean接口,若是有则执行destroy方法。
  11. 判断Bean是否配置了destroy-method,若是有,在销毁过程当中会默认执行一次destroy-method方法。

Bean初始化过程

在上一篇关于‘Spring初始化过程’的文章最后写到Spring初始化过程当中最后执行的核心方法是AbstractRefreshableApplicationContext类的refresh方法。这里再次将其源码贴出.架构

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
               // 1.为应用上下文的刷新作准备--设置时间、记录刷新日志、初始化属性源中的占位符(事实上什么都没作)和验证必要的属性等
			// Prepare this context for refreshing.
			prepareRefresh();
			// 2.让子类刷新内部的bean factory
			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
            //3.为上下文准备bean factory
			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);
			try {
                 // 4.bean factory 后置处理
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);
				// 5.调用应用上下文中做为bean注册的工厂处理器
				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);
				// 6.注册拦截建立bean的bean处理器
				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);
				 // 7.初始化消息源
				// Initialize message source for this context.
				initMessageSource();
				 // 8.初始化事件广播
				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();
				// 9.初始化特定上下文子类中的其它bean
				// Initialize other special beans in specific context subclasses.
				onRefresh();
				 // 10.注册监听器bean
				// Check for listener beans and register them.
				registerListeners();
				// 11.实例化全部的单例bean
				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);
 				// 12.发布相应的事件
				// Last step: publish corresponding event.
				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();
			}
		}
	}

经过源码能够看出该方法是构建整个IOC容器的完成过程。其中每一行代码都是建立容器的一个流程。其中主要包括如下几个步骤:框架

  1. 构建BeanFactory
  2. 添加事件处理
  3. 建立 Bean 实例对象并构建Bean关系
  4. 触发被监听的事件

构建BeanFactory

构建BeanFactory的操做主要包括步骤一、二、3。其中第一步在我看来并未作啥重要的事情,咱们只需将焦点定在二三步便可。

在第二步中,obtainFreshBeanFactory方法主要调用了AbstractRefreshableApplicationContext#refreshBeanFactory方法:

protected final void refreshBeanFactory() throws BeansException {
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			customizeBeanFactory(beanFactory);
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

在上述代码中清晰可见的说明了BeanFactory的建立过程,首先判断当前容器是否存在BeanFactory,若是有则销毁后在进行建立。经过try/catch中代码可见,BeanFactory的是DefaultListableBeanFactory的实例对象。

经过Idea查看DefaultListableBeanFactory的类图以下:

在这里插入图片描述

从这个图中发现除了 BeanFactory 相关的类外,还发现了与 Bean 的 register 相关。这在 refreshBeanFactory 方法中有一行 loadBeanDefinitions(beanFactory) 将找到答案,这个方法将开始加载、解析 Bean 的定义,也就是把用户定义的数据结构转化为 Ioc 容器中的特定数据结构。

对于WEB应用而言,其调用的是XmlWebApplicationContext#loadBeanDefinitions方法。

在BeanFactory建立成功后,Spring将建立的对象交于第三步,即prepareBeanFactory方法为其添加一些 Spring 自己须要的一些工具类。

添加事件处理

在第四、五、6步中,这三行代码对 Spring 的功能扩展性起了相当重要的做用 。其中第四、5步的代码主要是让你能够在Bean已经被建立,但未被初始化以前对已经构建的 BeanFactory 的配置作修改;第6步代码主要是让你能够对之后再建立 Bean 的实例对象时添加一些自定义的操做 。

第4步,即postProcessBeanFactory方法。主要功能为容许上下文能对BeanFactory作一些处理。好比:AbstractRefreshableWebApplicationContext抽象类实现了该方法,并在方法中对Servlet作了一些处理。

第5步,即invokeBeanFactoryPostProcessors方法主要是获取实现 BeanFactoryPostProcessor 接口的子类。其中主要包括执行BeanDefinitionRegistryPostProcessor类型的postProcessBeanDefinitionRegistry方法,以及执行非BeanDefinitionRegistryPostProcessor类型的postProcessBeanFactory方法。固然,该方法传入的参数是ConfigurableListableBeanFactory 类型,咱们仅能对BeanFactory的一些配置作修改。

第6步,即registerBeanPostProcessors 方法也是能够获取用户定义的实现了 BeanPostProcessor 接口的子类,并执行把它们注册到 BeanFactory 对象中的 beanPostProcessors 变量中。BeanPostProcessor 中声明了两个方法:postProcessBeforeInitialization、postProcessAfterInitialization 分别用于在 Bean 对象初始化时执行。能够执行用户自定义的操做。

第七、八、九、10步的方法主要是初始化监听事件和对系统的其余监听者的注册,监听者必须是 ApplicationListener 的子类。 在容器启动时,Spring会调用ApplicationStartListener的onApplicationEvent方法。

建立 Bean 实例对象并构建Bean关系

Bean的实例化过程是第11步开始的,即finishBeanFactoryInitialization方法,而在finishBeanFactoryInitialization方法中核心方法又为preInstantiateSingletons(DefaultListableBeanFactory类)。在该方法中,首先拿到全部beanName,而后在实例化的时候会判断bean是否为FactoryBean,顾名思义,这是一个特殊的工厂Bean,能够产生Bean的Bean。

这里的产生 Bean 是指 Bean 的实例,若是一个类继承 FactoryBean 用户只要实现他的 getObject 方法,就能够本身定义产生实例对象的方法。然而在 Spring 内部这个 Bean 的实例对象是 FactoryBean,经过调用这个对象的 getObject 方法就能获取用户自定义产生的对象,从而为 Spring 提供了很好的扩展性。Spring 获取 FactoryBean 自己的对象是在前面加上 & 来完成的。

在Bean的实例化主要分两个步骤:

  • Bean不为抽象、单例、非懒加载。
    • 判断Bean是否为FactoryBean,是则执行FactoryBean相关的操做,不然直接调用getBean方法产生实例。
  • 在singleton的bean初始化完了以后调用SmartInitializingSingleton的afterSingletonsInstantiated方法。

经过跟进Bean实例化代码能够发现getBean方法最后指向的是AbstractBeanFactory类的抽象方法createBean,其实现类为AbstractAutowireCapableBeanFactory。在该方法中有一个步骤会去查找Bean的依赖关系,并对其进行依赖注入操做。这里画一个时序图来做说明。

在这里插入图片描述

须要注意的是,在resolveValueIfNecessary方法中,不只有调用resolveReference,一样的还有resolveInnerBean,即解析内部的Bean引用。

触发被监听的事件

在经历第11步后,上下文的建立就已经基本完成了,这时Spring会执行finishRefresh方法,完成此上下文的刷新。其中包括LifecycleProcessor的onRefresh方法,并执行ContextRefreshedEvent事件。例如:执行SpringMVC的事件。

总结

在Bean声明周期中曾讲到,Spring在初始化Bean的时候前后对调用BeanPostProcessor接口的postProcessBeforeInitialization、postProcessAfterInitialization方法。利用这一特性咱们能够在Bean中实现BeanPostProcessor接口,而后再方法体中加入本身的逻辑。

对于Spring的IOC容器而言,除了BeanPostProcessor,还有BeanFactoryPostProcessor。顾明思议,BeanFactoryPostProcessor是在构建BeanFactory和构建Bean对象时调用。IOC容器容许BeanFactoryPostProcessor在容器初始化任何Bean以前对BeanFactory配置进行修改。

在Spring的IOC容器中还有一个特殊的Bean,即FactoryBean,FactoryBean主要用于初始化其余Bean,咱们能够本身实现一个FactoryBean,而后添加自定义实例化逻辑。在Spring中,AOP、ORM、事务管理等都是依靠FactoryBean的扩展来实现的。