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  
    

  • 相关阅读:
    POJ 1953 World Cup Noise
    POJ 1995 Raising Modulo Numbers (快速幂取余)
    poj 1256 Anagram
    POJ 1218 THE DRUNK JAILER
    POJ 1316 Self Numbers
    POJ 1663 Number Steps
    POJ 1664 放苹果
    如何查看DIV被设置什么CSS样式
    独行DIV自适应宽度布局CSS实例与扩大应用范围
    python 从入门到精通教程一:[1]Hello,world!
  • 原文地址:https://www.cnblogs.com/Qkxh320/p/spring_04.html
Copyright © 2011-2022 走看看