在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 中才是真正的主角。编程
在Spring中Bean贯穿整个Spring应用,其生命周期应是从Spring容器建立后开始,直至Spring容器主动或被动销毁Bean。缓存
在Spring中,Bean默认为单例模式,即singleton属性默认为false,从BeanFactory中取得的Bean实例为在其初始化就产生一个新的对象,而不是每次获取的时候都产出一个新的对象。固然咱们也能够在初始化Bean的时候设置其singleton属性为true,使这个Bean变成多例模式,在getBean的时候,Spring都会产出一个新的对象,相似于Java的中的new Object操做。但设置其为多例,应避免多线程同时存取共享资源所引起的数据不一样步问题。数据结构
而后在Spring中,一个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容器的完成过程。其中每一行代码都是建立容器的一个流程。其中主要包括如下几个步骤:框架
构建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的实例化过程是第11步开始的,即finishBeanFactoryInitialization方法,而在finishBeanFactoryInitialization方法中核心方法又为preInstantiateSingletons(DefaultListableBeanFactory类)。在该方法中,首先拿到全部beanName,而后在实例化的时候会判断bean是否为FactoryBean,顾名思义,这是一个特殊的工厂Bean,能够产生Bean的Bean。
这里的产生 Bean 是指 Bean 的实例,若是一个类继承 FactoryBean 用户只要实现他的 getObject 方法,就能够本身定义产生实例对象的方法。然而在 Spring 内部这个 Bean 的实例对象是 FactoryBean,经过调用这个对象的 getObject 方法就能获取用户自定义产生的对象,从而为 Spring 提供了很好的扩展性。Spring 获取 FactoryBean 自己的对象是在前面加上 & 来完成的。
在Bean的实例化主要分两个步骤:
经过跟进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的扩展来实现的。