Spring源码分析

Spring源码分析

Spring整体架构

1.Core Container

 	 1. core
     主要包含了spring框架基本的的核心工具类,spring的其他组件都要用到这个包,core模块是其他组件的基本核心。
     
     2. beans
     包含了访问spring配置文件,创建并管理bean以及进行IOC和DI操作相关的所有类。
     
     3. context
     为spring核心提供了大量扩展,添加了对国际化,事件传播,资源加载和对context的透明创建和支持。context同时也支持J2EE的一些特性,如EJB,JMX和基础的远程处理。ApplicationContext接口是Context模块的关键。
     
     4. expression
    提供了强大的表达式语言,用于在运行时查询和操纵对象。

2.Data Acess/Integration

1. JDBC
包含了Spring对JDBC数据访问进行封装的所有类。

 2. ORM
为对象-关系映射的API,如Hibernate,iBatis等,提供了一个交互层。利用ORM的封装包,可以混合使用所有Spring提供的特性进行O/R映射。

 3. OXM
提供了一个对Object/XML映射实现的抽象层。

 4. JMS
主要包含了一些制造和消费信息的特性。

 5. Transactions
支持编程和声明性的事务管理,这些事务必须实现特定的接口,并且岁所有的POJO都适用。

3.Web

1. Web模块
提供了基础的面向Web的集成特性,例如,多文件上传,使用servlet listeners初始化IOC容器以及一个面向Web的应用上下文。

 2. Web-Servlet
包含了SpringMVC的实现。

 3. Web-Porlet
提供了用于Portlet环境和Web-Servlet模块的MVC实现。

4.AOP

提供了面向切面编程的实现,Spring AOP模块为基于Spring的应用程序中的对象提供了事务管理服务。

5.Test

支持适用JUnit和TestNG对Spring组件进行测试。

容器的基本实现

Spring AOP实现原理

//scope :方法作用域,如public,private,protect //returnt-type:方法返回值类型
//fully-qualified-class-name:方法所在类的完全限定名称 //parameters 方法参数
execution(< scope> < return-type> < fully-qualified-class-name>.*(parameters))
注意这一块,如果没有精确到class-name,而是到包名就停止了,要用两个"…"来表示包下的任意类:

execution(* com.zdy…(…)):com.zdy包下所有类的所有方法.
execution(
com.zdy.Dog.*(…)): Dog类下的所有方法.

Spring IOC 容器源码分析

Spring-IOC源码分析

  • BeanDefinition 就是我们所说的 Spring 的 Bean,我们自己定义的各个 Bean 其实会转换成一个个BeanDefinition 存在于 Spring 的 BeanFactory 中。
  • 所以,如果有人问你 Bean 是什么的时候,你要知道 Bean 在代码层面上可以认为是 BeanDefinition 的实例。
  • BeanDefinition 中保存了我们的 Bean 信息,比如这个 Bean 指向的是哪个类、是否是单例的、是否懒加载、这个 Bean 依赖了哪些 Bean 等等。

IOC步骤:

@Override
public void refresh() throws BeansException, IllegalStateException {

   // 来个锁,不然 refresh() 还没结束,你又来个启动或销毁容器的操作,那不就乱套了嘛
   synchronized (this.startupShutdownMonitor) {

      // 准备工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
      prepareRefresh();

      // 这步比较关键,这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中,
      // 当然,这里说的 Bean 还没有初始化,只是配置信息都提取出来了,
      // 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map)
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
      // 这块待会会展开说
      prepareBeanFactory(beanFactory);

      try {
         // 【这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口,
         // 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。】

         // 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
         // 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
         postProcessBeanFactory(beanFactory);
         
         // 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 回调方法
         invokeBeanFactoryPostProcessors(beanFactory);          

         // 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
         // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
         // 两个方法分别在 Bean 初始化之前和初始化之后得到执行。这里仅仅是注册,之后会看到回调这两方法的时机
         registerBeanPostProcessors(beanFactory);

         // 初始化当前 ApplicationContext 的 MessageSource,国际化这里就不展开说了,不然没完没了了
         initMessageSource();

         // 初始化当前 ApplicationContext 的事件广播器,这里也不展开了
         initApplicationEventMulticaster();

         // 从方法名就可以知道,典型的模板方法(钩子方法),不展开说
         // 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
         onRefresh();

         // 注册事件监听器,监听器需要实现 ApplicationListener 接口。这也不是我们的重点,过
         registerListeners();

         // 重点,重点,重点
         // 初始化所有的 singleton beans
         //(lazy-init 的除外)
         finishBeanFactoryInitialization(beanFactory);

         // 最后,广播事件,ApplicationContext 初始化完成,不展开
         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.
         // 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);

         // 把异常往外抛
         throw ex;
      }

      finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
      }
   }
}
  1. 从 ClassPathXmlApplicationContext 的构造方法说起,首先进入它的refresh方法。

(这里简单说下为什么是 refresh(),而不是 init() 这种名字的方法。因为ApplicationContext 建立起来以后,其实我们是可以通过调用 refresh() 这个方法重建的,refresh()会将原来的 ApplicationContext 销毁,然后再重新执行一次初始化操作。)

  1. 然后进入AbstractApplicationContext 的prepareRefresh()方法,该方法记录启动时间,并检验XML文件。
  2. 之后创建 Bean 容器,加载并注册 Bean。也就是refresh() 方法中的下一行 obtainFreshBeanFactory()方法(用来返回一个BeanFactory)。这个方法是全文最重要的部分之一,这里将会初始化 BeanFactory、加载 Bean、注册 Bean 等等。当然,这步结束后,Bean 并没有完成初始化。这里指的是 Bean 实例并未在这一步生成。
  3. obtainFreshBeanFactory()方法的refreshBeanFactory()方法中,这个方法生成一个BeanFactory实例( DefaultListableBeanFactory类型)
  4. 然后执行customizeBeanFactory(beanFactory)方法,就是配置是否允许 BeanDefinition 覆盖、是否允许循环引用。
  5. 接下来是最重要的 loadBeanDefinitions(beanFactory) 方法了,这个方法将根据配置,加载各个 Bean,然后放到 BeanFactory 中。读取配置的操作在 XmlBeanDefinitionReader 中,其负责加载配置、解析。
  6. 根据 之类的标签创建了一个 BeanDefinitionHolder 实例,这个实例里面也就是一个 BeanDefinition 的实例和它的 beanName、aliases 这三个信息。然后我们准备注册这个 BeanDefinition,最后,把这个注册事件发送出去。
  7. 然后进入BeanDefinitionReaderUtils的registerBeanDefinition方法注册Bean,所有的 Bean 注册后会放入这个 beanDefinitionMap 中。

到这里已经初始化了 Bean 容器(只进行到obtainFreshBeanFactory()方法), 配置也相应的转换为了一个个 BeanDefinition,然后注册了各个 BeanDefinition 到注册中心,并且发送了注册事件。

  1. 执行prepareBeanFactory方法,对一些特殊的 bean 进行了处理。
  2. finishBeanFactoryInitialization(beanFactory)会负责初始化所有的 singleton beans,执行方法里最后的beanFactory.preInstantiateSingletons()方法进行初始化所有非懒加载的bean。
  3. 接着就进入到 getBean(beanName) 方法了,这个方法我们经常用来从 BeanFactory 中获取一个 Bean,而初始化的过程也封装到了这个方法里。这里面要开始创建Bean了(如果是单例且已经创建,就直接返回),执行createBean(String beanName, RootBeanDefinition mbd, Object[] args)最后 return (T) bean。
  4. createBean中有个真正的执行方法doCreateBean,doCreateBean 中有三个细节很重要;一个是创建 Bean 实例的 createBeanInstance 方法,一个是依赖注入的 populateBean 方法,还有就是回调方法 initializeBean。

总结:
一个是 xml映射load成BeanDefinitions然后register到beanFactory,然后就是bean的初始化。有的bean是启动时候可以初始化,有的bean是懒初始化 getBean的时候初始化。

Spring核心类介绍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值