zoukankan      html  css  js  c++  java
  • Spring四、Spring IOC、DI、MVC、AOP时序图

     最近一直在研究Spring IOC、DI、AOP、MVC几个步骤的源码,画出几种的时序图,方便以后查看回忆源码

    1、IOC容器初始化

     IOC 容器的初始化包含了BeanDefinition资源文件Resource定位、解析加载和注册三个步骤。
     步骤依次为 : 读取资源文件为InputStream --> 转为Resource -> Document -> 解析元素节点封装为 BeanDefinition
    -> 放入IOC容器中,即DefaultListableBeanFactory的 Map<String, BeanDefinition> beanDefinitionMap

      主要的几个类
      BeanFactory : BeanFactory及其子类也就是我们说的IOC容器,Spring提供了多种IOC容器以供选择
          ListableBeanFactory接口表示Bean可列表化、HierarchicalBeanFactory接口表示Bean有继承关系、AutowireCapableBeanFactory定义自动装配;
          以上三个接口的默认实现均为 org.springframework.beans.factory.support.DefaultListableBeanFactory
      BeanDefinition : 描述Bean在资源文件中的配置信息及相互关系
      BeanDefinitionReader : 解析资源为BeanDefinition 
    

    1.1 基于xml的Ioc容器初始化

    入口:

    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class IoCTest {
    
        public static void main(String[] args) {
            //  
            ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
            applicationContext.getBean("myUser");
            
        }
        
    }
    

    IOC实现流程及原理
    Spring IOC时序图

    1.2 基于web的Ioc容器初始化

    入口: web Ioc容器初始化由DispatcherServlet.init()方法开始

      DispatcherServlet.init() 其实是调用的父类 org.springframework.web.servlet.HttpServletBean#init方法,之后 
        -> org.springframework.web.servlet.FrameworkServlet#initServletBean 
          -> org.springframework.web.servlet.FrameworkServlet#initWebApplicationContext
            -> org.springframework.web.servlet.FrameworkServlet#configureAndRefreshWebApplicationContext
              -> org.springframework.context.support.AbstractApplicationContext#refresh
                -> org.springframework.context.support.AbstractApplicationContext#obtainFreshBeanFactory
       到此,余下 web Ioc容器的初始化步骤和 XML IOC容器的初始化都经由 AbstractApplicationContext#obtainFreshBeanFactory 来完成,和上面时序图一样。
    

    1.3 基于注解的Ioc容器初始化

    2、DI依赖注入时序图

      入口: org.springframework.context.support.ClassPathXmlApplicationContext#getBean(java.lang.String)  
            ->  org.springframework.context.support.AbstractApplicationContext#getBean(java.lang.String)
      
      实现原理: 反射为属性赋值,如果存在循环依赖,使用三级缓存来处理:
          一级缓存: 类成功实例化,属性也成功赋值
          二级缓存: 类成功实例化,属性存在循环依赖、不能赋值 
          三级缓存: 类不能成功实例化 (指定使用构造器方法进行实例化,构造器中的参数存在循环引用) 
        在初始化完毕,会先遍历三级缓存进行依赖注入,放入一级缓存;然后遍历二级缓存,放入一级缓存; 
    

    3、AOP时序图

      入口: org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
      
      实现逻辑: 
        基于JDK或者Cglib的动态代理通过字节码重组实现;
        首先加载配置的切面PointCut及方法拦截通知Advice的配置,在进行依赖注入时,为每个类及类的每个方法正则匹配是否符合切面表达式,符合的话判断该类是否实现了接口,实现接口的话使用JDK的动态代理,否则使用Cglib的动态代理字节码重组重新织入通知代码,以次生产新的代理类。    
    
      AdvisedSupport -> AopConfig -> Advice -> JDKProxy or CglibProxy
    

    4、MVC流程时序图

      入口: DispatcherServlet.init()  &&   DispatcherServlet.doService()
    
      实现逻辑:
      首先程序启动初始化Spring九大组件:
        初始化url映射HandlerMapping; 扫描Controller下的所有RequestMapping,组成正则类型的url Pattern,并与Controller、method绑定关系组成HandlerMapping对象;
        初始化参数适配器HandlerAdapter;记录RequestMapping对应method的参数类型,参数名称,RequestParam绑定名称等
        初始化视图解析器ViewResolver;
        .... 
      之后再页面url发出请求后,根据请求url正则匹配到对应1到多个HandlerMapping,然后找出对应的参数适配器HandlerAdapter,反射进行方法调用返回ModelAndView,再由ViewResolver进行解析、占位符替换,最后对View渲染,将html或jsp通过Response返回   
    
      DispatcherServlet -> HandlerMapping -> HandlerAdapter -> ModelAndView -> ViewResolver -> View  
    

  • 相关阅读:
    JUnit4.13环境配置
    OO第5-7次作业总结
    电梯的一点浅优化
    C++变量作用域、生存期、存储类别
    最后一次OO博客
    OO第三次总结
    OO第二次总结
    OO第一次总结
    POJ3934
    POJ刷题计划
  • 原文地址:https://www.cnblogs.com/Qkxh320/p/spring_04.html
Copyright © 2011-2022 走看看